2015-08-14 2 views
0

Вот сценарий:Невозможно найти ручку главного окна только что прочитанного Диалог APP

У меня 2 приложения. Одним из них является мое основное приложение, а второе - диалоговое приложение, которое запускается с первого. Я пытаюсь захватить главный дескриптор приложения, основанного на диалоге, из моего основного приложения. Проблема в том, что я не могу найти его с EnumWindows. Проблема исчезнет, ​​если я поставлю сон на секунду, перед тем, как начать перечислять окна.

Это код:

... 

BOOL res = ::CreateProcess(NULL, _T("MyApp.exe"), NULL, NULL, FALSE, NULL, NULL, NULL, &siStartInfo, &piProcInfo); 
ASSERT(res); 
dwErr = WaitForInputIdle(piProcInfo.hProcess, iTimeout); 
ASSERT(dwErr == 0); 

//Sleep(1000); //<-- uncomment this will fix the problem 

DWORD dwProcessId = piProcInfo.dwProcessId; 
EnumWindows(EnumWindowsProc, (LPARAM)&dwProcessId); 
.... 

BOOL IsMainWindow(HWND handle) 
{ 
    return GetWindow(handle, GW_OWNER) == (HWND)0 && IsWindowVisible(handle); 
} 

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) 
{ 
    DWORD* pParam = (DWORD*)lParam; 
    DWORD dwTargetProcessId = *pParam; 
    DWORD dwProcessId = 0; 
    ::GetWindowThreadProcessId(hwnd, &dwProcessId); 

    if (dwProcessId == dwTargetProcessId) 
    { 
     TCHAR buffer[MAXTEXT]; 
     ::SendMessage(hwnd, WM_GETTEXT, (WPARAM)MAXTEXT,(LPARAM)buffer); 

     if(IsMainWindow(hwnd))  
     { 
      g_hDlg = hwnd; 
      return FALSE; 
     } 
    } 

    return TRUE; 
} 

Есть ровно два окна, которые принадлежат к моему процессу и отслеживание их текста показывает:

GDI+ Window 
Default IME 

Я не совсем уверен, что это значит. Это могут быть заголовки по умолчанию, назначенные для окон, до их инициализации .... но я вызываю EnumWindows после WaitForInputIdle ...

Любая помощь будет оценена.

+0

Вы должны объяснить, что "главное окно"? Как он отличается от другого окна верхнего уровня? –

+0

Привет, В главном окне я имею в виду главное окно :). Те, кто справляется со всеми остальными. В этом случае основным окном является диалоговое окно. – Kiko

+0

Это как сказать «этим окном я имею в виду это окно» :) Что особенного в окне, которое вы назвали «основным»? Как вы можете отличить его от других окон, таких как «GDI + Window»? –

ответ

3

CreateProcess возвращает, когда ОС создала объект процесса, включая объект, представляющий основной поток. Это не означает, что процесс начал выполнение.

Если вам нужно запросить другой процесс для информации, доступной только после того, как этот процесс запустился до определенной точки, вам потребуется установить какую-то синхронизацию. Очевидным вариантом является именованный объект события (см. CreateEvent), который сигнализируется, когда второй процесс завершил свою инициализацию, и диалог запущен и работает. Первый процесс затем просто WaitForSingleProcess и только продолжит, как только событие будет сигнализировано. (Более надежное решение вызывало бы WaitForMultipleObjects как для события, так и для дескриптора процесса, чтобы ответить на неожиданное завершение процесса.)

Другой вариант заключается в том, чтобы второй процесс отправил пользовательское сообщение (WM_APP+x) на первое процесс, передавая его HWND.


WaitForInputIdle звучит как жизнеспособное решение. Кроме того, это не так. WaitForInputIdle был представлен для соответствия требованиям DDE и просто проверяет, может ли поток в целевом процессе получать сообщения. И это действительно означает любой поток в этом процессе. Он не привязан к GUI, который работает и работает.

Дополнительная информация по данной теме можно найти здесь:

+1

И по этой причине я использую WaitForInputIdle. Согласно MSDN: WaitForInputIdle: Ожидает, что указанный процесс завершит обработку начального ввода и ждет ввода пользователя без ожидания ввода, – Kiko

+0

Ha, спасибо за эту помощь :). Действительно WaitForInputIdle работает не так, как ожидалось, по крайней мере, не для приложений с одним потоком. И я согласен с тем, что лучшим решением будет введение Events. – Kiko

Смежные вопросы