Не удается найти дескриптор главного окна только что запущенного диалогового приложения

Вот сценарий:

У меня есть 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;
}

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

GDI+ Window
Default IME

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

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


person Kiko    schedule 14.08.2015    source источник
comment
Вам нужно объяснить, что такое главное окно? Чем оно отличается от другого окна верхнего уровня?   -  person Vlad Feinstein    schedule 14.08.2015
comment
Привет. Под главным окном я подразумеваю главное окно :). Те, кто занимается всеми остальными. В этом случае основным окном является Диалог.   -  person Kiko    schedule 17.08.2015
comment
Это все равно, что сказать под этим окном я имею в виду ЭТО окно :) Что такого особенного в окне, которое вы назвали главным? Как отличить его от других окон, таких как GDI+ Window?   -  person Vlad Feinstein    schedule 17.08.2015
comment
Хорошо, я могу быть не очень корректным, используя термин главное окно для диалогового окна, которое создается CreateWindow. Например. это родительское базовое окно, а это означает, что все остальные окна являются его дочерними элементами.   -  person Kiko    schedule 17.08.2015
comment
Все окна создаются функцией CreateWindow(). Ни одно из дочерних окон не перечисляется EnumWindows(). Вам нужно найти что-то еще, что отличает ваше главное окно от других.   -  person Vlad Feinstein    schedule 17.08.2015


Ответы (1)


person    schedule
comment
И по этой причине я использую WaitForInputIdle. Согласно MSDN: WaitForInputIdle: ждет, пока указанный процесс не завершит обработку своего начального ввода, и ожидает ввода пользователя без ожидания ввода, - person Kiko; 14.08.2015
comment
Ха, спасибо за эту помощь :). Действительно, WaitForInputIdle не работает должным образом, по крайней мере, для однопоточных приложений. И я согласен, что лучшим решением будет введение событий. - person Kiko; 17.08.2015