Я использую CreateProcess для запуска приложений (ПРОИЗВОЛЬНЫХ!).
Мне нужно, сразу после запуска, поймать HWND главного окна этого приложения. FindWindow не подходит, т.к. я заранее не знаю, какое WindowName...
На всякий случай скажу, что это мне необходимо для общения с запущенным приложением через WinMess.
Здравствуйте, jim1406, Вы писали:
J>Я использую CreateProcess для запуска приложений (ПРОИЗВОЛЬНЫХ!). J>Мне нужно, сразу после запуска, поймать HWND главного окна этого приложения. FindWindow не подходит, т.к. я заранее не знаю, какое WindowName...
J>На всякий случай скажу, что это мне необходимо для общения с запущенным приложением через WinMess.
J>Помогите!?...
Нужно перечислить окна через EnumWindows, а затем в EnumWindowsProc вызывать GetWindowThreadProcessId и сравнивать полученный ProcessID cо значением, полученным от CreateProcess. Можно было бы сравнивать и ThreadID, но не факт, что первичный поток процесса создаст окно, хотя в большинстве случаев так оно и есть.
Вообще-то еще неизвестно, какое окно является главным Может оно мессэдж бокс покажет или сплеш скрин до показа своего основного окна. Или в промежутке между двумя енумерациями создаст сразу 10 окон, как дельфи делает, например.
M>Нужно перечислить окна через EnumWindows, а затем в EnumWindowsProc вызывать GetWindowThreadProcessId и сравнивать полученный ProcessID cо значением, полученным от CreateProcess. Можно было бы сравнивать и ThreadID, но не факт, что первичный поток процесса создаст окно, хотя в большинстве случаев так оно и есть.
Здравствуйте, maximilian, Вы писали:
M>Нужно перечислить окна через EnumWindows, а затем в EnumWindowsProc вызывать GetWindowThreadProcessId и сравнивать полученный ProcessID cо значением, полученным от CreateProcess. Можно было бы сравнивать и ThreadID, но не факт, что первичный поток процесса создаст окно, хотя в большинстве случаев так оно и есть.
Залез в MSDN...
Не могу понять, что за параметры у этих ф-й и как их испльзовать...
Буду благодарен, если кто-нибудь пояснит мне...
Здравствуйте, jim1406, Вы писали:
J>Здравствуйте, maximilian, Вы писали:
M>>Нужно перечислить окна через EnumWindows, а затем в EnumWindowsProc вызывать GetWindowThreadProcessId и сравнивать полученный ProcessID cо значением, полученным от CreateProcess. Можно было бы сравнивать и ThreadID, но не факт, что первичный поток процесса создаст окно, хотя в большинстве случаев так оно и есть.
J>Залез в MSDN... J>Не могу понять, что за параметры у этих ф-й и как их испльзовать... J>Буду благодарен, если кто-нибудь пояснит мне...
начини с того что объяcни народу для чегор именно тебе это нужно — может можно по другому проблему решить
Здравствуйте, jim1406, Вы писали:
J>Залез в MSDN... J>Не могу понять, что за параметры у этих ф-й и как их испльзовать... J>Буду благодарен, если кто-нибудь пояснит мне...
// Запускаем процесс
PROCESS_INFORMATION pi = {0};
BOOL bCreated = CreateProcess(..., &pi);
if (bCreated)
{
// процесс создан, дождемся завершения инициализации процесса
WaitForInputIdle(pi.hProcess, INFINITE);
// MSDN пишет: For example, the creating process would use WaitForInputIdle
// before trying to find a window associated with the new process.
// описатель первичного потока нам не понадобится, закроем его
CloseHandle(pi.hThread);
// описатель процесса нам более не нужет, закроем его
CloseHandle(pi.hProcess);
// пробуем перечислить все окна верхнего уровня и найти то, которое принадлежит
// одному из потоков нового процесса.
// первый параметр - указатель на ф-цию, которая будет вызвана системой
// для каждого окна верхнего уровня, определение ф-ции приведено ниже;
// второй параметр исключительно для наших нужд, его значение будет передаваться
// ф-ции обратного вызова EnumWindowsProc.
// поскольку в ф-ции обратного вызова необходимо определять принадлежность окон новому
// процессу, имеет смысл передать в качестве такого параметра идентификатор процесса.
EnumWindows(EnumWindowsProc, LPARAM(pi.dwProcessID));
}
ф-ция обратного вызова
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
BOOL bContinue = TRUE;
DWORD dwProcessID;
// определяем процесс, один из потоков которого владеет окном.
GetWindowThreadProcessId(hWnd, &dwProcessID);
if (dwProcessID == DWORD(lParam))
{
// нашли окно, прекращаем перечисление окон
// делаем что-то с окном...
bContinue = FALSE;
}
return bContinue;
}
Здравствуйте, jim1406, Вы писали:
A>>начини с того что объяcни народу для чегор именно тебе это нужно — может можно по другому проблему решить
J>Есть прога, она запускет другие, но заранее не знает какие, запускает, значит, и посылает им WinMess-аги... Вот, а HWND?..
Во-первых, можно поставить CBT-хук и ловить HCBT_CREATEWND. Имеет смысл, если быть уверенным в том, что первое созданное процессом окно и есть главное окно.
Во-вторых, можно попытаться воспользоваться GetGUIThreadInfo. hwndActive скорее всего и будет главным окном.
В-третьих, полученный результат, вне зависимости от способа получения, всегда можно и должно проконтролировать на достоверность(GetClassName), и при провале проверки воспользоваться альтернативным способом — например, первая попытка GetGUIThreadInfo, в случае неудачи — EnumDesktopWindows.