Я сделал, как и в ассемблерной программе. Трюк с прогрессом.
Развернуть: GetIP.cpp- Код: Выделить всё
// GetIP.cpp
#ifdef _MSC_VER
#pragma comment(lib,"comctl32.lib")
#endif
#include <windows.h>
#include <commctrl.h>
#include "resource.h"
BOOL CopyToClipboard(char* str);
void mb(char* str);
int DoExit();
#ifndef PBS_SMOOTH
#define PBS_SMOOTH 01
#endif
#ifndef PBS_VERTICAL
#define PBS_VERTICAL 04
#endif
#ifndef PBM_SETBARCOLOR
#define PBM_SETBARCOLOR (WM_USER+9)
#endif
typedef HRESULT (WINAPI* _URLDownloadToFileA)(LPUNKNOWN pCaller, LPCSTR szURL, LPCSTR szFileName, DWORD dwReserved, void* lpfnCB);
_URLDownloadToFileA pURLDownloadToFile;
char* szAppname = "GetIP";
char* szMsg = "\nПодключение к серверу checkip.dyndns.org\n"
"Пожалуйста, ждите...";
char* szUrl = "http://checkip.dyndns.org/Current IP Check.htm";
char* szName = "ip.txt";
char* szMatch = "Current IP Address:";
char* szDebugFileName = "ip_dbg.txt";
char* szFormat = "IP Address: %s";
char* szFormat2 = "IP Address: %s\n"
"Адрес скопирован в Буфер Обмена\n"
"для вставки в документ нажмите клавишу \"Ctrl+V\".";
char* szErr01 = "Не удалось создать прогресс.";
char* szErr02 = "Не удалось загрузить функцию URLDownloadToFile";
char* szErr03 = "Нет связи.";
char* szErr04 = "Не удалось создать временный файл для записи.";
char* szErr05 = "Не удалось. Блокирует Ростелеком!";
HINSTANCE g_hInstance;
BOOL g_bRunning;
DWORD dwColor = RGB(255, 0, 0); // Red
//DWORD dwColor = RGB(0, 0, 255); // Blue
//DWORD dwColor = RGB(0, 128, 0); // Green
#define BUFFSIZE 2048
char szBuff[BUFFSIZE];
static DWORD WINAPI WorkThread(LPVOID)
{
pURLDownloadToFile = (_URLDownloadToFileA)
GetProcAddress(LoadLibraryA("urlmon"),
"URLDownloadToFileA");
if (!pURLDownloadToFile)
{
lstrcpy(szBuff,szErr02);
return DoExit();
}
char szTempFileName[MAX_PATH];
GetTempPath(MAX_PATH,szTempFileName);
lstrcat(szTempFileName,szName);
if (pURLDownloadToFile(0,szUrl,szTempFileName,0,0))
{
lstrcpy(szBuff,szErr03);
return DoExit();
}
HANDLE hFile;
#ifdef _DEBUG
hFile = CreateFile(szDebugFileName,
GENERIC_READ,0,0,OPEN_EXISTING,0,0);
#else
hFile = CreateFile(szTempFileName,
GENERIC_READ,0,0,OPEN_EXISTING,0,0);
#endif
if (INVALID_HANDLE_VALUE==hFile)
{
lstrcpy(szBuff,szErr04);
return DoExit();
}
DWORD n, dwBytesRead;
char szResult[BUFFSIZE];
ReadFile(hFile,szResult,BUFFSIZE,&dwBytesRead,NULL);
CloseHandle(hFile);
if (!strstr(szResult,szMatch))
{
lstrcpy(szBuff,szErr05);
return DoExit();
}
char* szToken = strrchr(szResult, ':');
szToken = strtok(szToken, "<");
lstrcpyn(szResult, szToken+2, sizeof(szResult));
n = lstrlen(szResult);
if (n) // Скопировать IP-адрес в буфер обмена.
n = CopyToClipboard(szResult);
if (!n)
wsprintf(szBuff,szFormat,szResult);
else
wsprintf(szBuff,szFormat2,szResult);
g_bRunning = 0; // Работа завершена!
return 0;
}
static DWORD WINAPI ProgressThread(LPVOID)
{
HWND hwndProgress, hWnd = 0;
// Найти главное окно программы,
// в данном случае системный MessageBox.
while (!hWnd)
{
Sleep(50); // Таймаут (небольшой перерыв).
hWnd = FindWindow(NULL,szAppname);
}
// Обеспечивает загрузку библиотеки Comctl32.dll.
InitCommonControls();
// Скрыть кнопку OK у MessageBox.
ShowWindow(GetTopWindow(hWnd),SW_HIDE);
// Вычислить координаты главного окна (т.е. родительского),
// в данном случае, родительское окно, системный MessageBox.
RECT rect;
GetClientRect(hWnd,&rect);
int x = 1;
int y = rect.bottom - 20;
int nWidth = rect.right - 2;
int nHeight = 20;
// Создать прогресс индикатор (Progress Bar).
hwndProgress = CreateWindow("msctls_progress32",
"Progress",
WS_VISIBLE | WS_CHILD | PBS_SMOOTH,
x, y, nWidth, nHeight,
hWnd,(HMENU)IDC_PROGRESS1,
g_hInstance,NULL);
if (!hwndProgress)
{
lstrcpy(szBuff,szErr01);
return DoExit();
}
// Создать рабочий поток.
DWORD tid;
CreateThread(NULL,0,WorkThread,0,0,&tid);
// Цвет прогресс индикатора.
SendMessage(hwndProgress,
PBM_SETBARCOLOR,0,(LPARAM)dwColor);
int nMaxRange = 100;
int nNewPos = 0;
// Показать прогресс индикатор.
ShowWindow(hwndProgress,SW_SHOW);
// Вычислить диапазон прогресс индикатора (0-100).
SendMessage(hwndProgress,
PBM_SETRANGE,
0,(LPARAM)MAKELONG(0,nMaxRange));
// Установить диапазон прогресс индикатора.
SendMessage(hwndProgress,
PBM_SETSTEP,(WPARAM)1,0);
// Пока пользователь не закрыл окно или
// переменная bRunning не пуста - выполнять цикл.
while (IsWindowVisible(hWnd) && g_bRunning)
{
++nNewPos; // Прибавить шкалу индикатора прогресса.
if (nMaxRange == nNewPos)
nNewPos = 0;
// Движение прогресс индикатора.
SendMessage(hwndProgress,PBM_SETPOS,nNewPos,0);
Sleep(20); // Таймаут. Небольшой переыв.
}
// Закрыть прогресс бар.
DestroyWindow(hwndProgress);
// Закрыть диалоговое окно (MessageBox) нажав кнопку OK.
//ShowWindow(GetTopWindow(hWnd),SW_SHOW);
SendMessage(GetTopWindow(hWnd),BM_CLICK,0,0);
return 0;
}
int DoExit()
{
HWND hWnd = FindWindow(NULL,szAppname);
if (hWnd) // Если окно найдено, закрыть его.
{
// Закрыть диалоговое окно (MessageBox) нажав кнопку OK.
//ShowWindow(GetTopWindow(hWnd),SW_SHOW);
SendMessage(GetTopWindow(hWnd),BM_CLICK,0,0);
}
if (szBuff[0]) // Если буфер не пуст, показать сообщение.
{
mb(szBuff);
szBuff[0] = 0;
g_bRunning = 0;
}
return 0;
}
/*
* Начало программы (Entry point).
*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
g_hInstance = hInstance;
g_bRunning = 1;
DWORD tid;
CreateThread(NULL,0,ProgressThread,0,0,&tid);
mb(szMsg);
while (g_bRunning)
Sleep(20);
return DoExit();
}
BOOL CopyToClipboard(char* str) {
BOOL bRet=FALSE;
CloseClipboard();
if (OpenClipboard(GetActiveWindow())) {
EmptyClipboard();
HGLOBAL GlobalMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,lstrlen(str)+1);
if (GlobalMem) {
char* Data=(char*)GlobalLock(GlobalMem);
lstrcpy(Data,str);
GlobalUnlock(GlobalMem);
if (SetClipboardData(CF_TEXT,GlobalMem))
bRet=1;
}
CloseClipboard();
}
return bRet;
}
void mb(char* str) {
UINT uType=MB_OK | MB_ICONINFORMATION |
MB_SETFOREGROUND | MB_SYSTEMMODAL;
int n=0;
if (strstr(str,"Нет ") || strstr(str,"Не удалось"))
++n;
if (n) {
uType &=~MB_ICONINFORMATION;
uType |=MB_ICONWARNING;
} MessageBox(GetActiveWindow(),str,szAppname,uType);
if (n) ExitProcess(n);
}
Есть один ньюанс, при поиске дескриптора окна (hWnd, хэндла).
Это здесь :
char* szAppname = "GetIP"; // Это заголовок.
// Найти главное окно программы,
// в данном случае системный MessageBox.
while (!hWnd)
{
Sleep(50); // Таймаут (небольшой перерыв).
// Функции FindWindow нужно два параметра
// один из которых заголовок окна.
hWnd = FindWindow(NULL,szAppname);
}
Если этот заголовок будет совпадать с именем папки, то программа
поведёт себя непредсказуемо. Для этого, лучше всего, добавить ещё
какую-нибудь строку или символ. Сделайте так, как в ассемблерной версии программы
(здесь я забыл). Вообще, у меня ОС настроена показывать полный путь
в строке заголовка и из-за этого, у меня проблем нет. Вы же, не забудьте
исправить. Я так и не сказал, как программа может повести себя, если
примет Хэндл (hWnd), идентификатор папки, а не окна. Скорее всего,
просто быстро закроется или может создать прогресс на окне папки.
Итого. Вам нужно изменить заголовок окна на это:
char* szAppname = "GetIP - Узнать IP-адреса";
Также, есть дополнительный параметр поиска hWnd идентификатора,
это имя класса, но из-за трюка с поиском не собственного окна - это
является не проблемой, а плохим тоном или как говорят костылём.
В общем, у системного MessageBox класс называется #32770.
Для просмотра свойств окно, есть несколько утилит, одна
в инструментах Borland и Microsoft, имя её Spyxx. Есть независимая
утилита WinSpy
Развернуть: Имя оконного класса MessageBox