找不到刚启动的 Dialog APP 的主 window 句柄

Cannot find the main window handle of the just stareted Dialog APP

场景如下:

我有 2 个应用程序。其中一个是我的主要应用程序,第二个是基于对话框的应用程序,它是从第一个开始的。我正在尝试从我的主应用程序中捕获基于对话框的应用程序的主句柄。问题是我无法使用 EnumWindows 找到它。如果我在开始枚举 windows.

之前睡一秒钟,问题就会消失

这是代码:

...

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 个 windows 属于我的进程,跟踪它们的文本显示:

GDI+ Window
Default IME

我不太清楚这是什么意思。这些可能是默认标题,在初始化之前分配给 windows....但我在 WaitForInputIdle 之后调用了 EnumWindows ...

任何帮助将不胜感激。

CreateProcessreturns,当OS创建了进程对象,包括代表主线程的对象。这并不意味着该进程已开始执行。

如果您需要查询另一个进程以获取仅在该进程具有 运行 特定点后才可用的信息,您将需要安装某种同步。一个明显的选择是命名事件对象(请参阅事件和进程句柄上的 CreateEvent), that is signaled, when the second process has finished its initialization, and the dialog is up and running. The first process would then simply WaitForSingleProcess, and only continue, once the event is signaled. (A more robust solution would call WaitForMultipleObjects,以响应意外的进程终止。)

另一种选择是让第二个进程向第一个进程发送用户定义的消息 (WM_APP+x),同时传递其 HWND


WaitForInputIdle 听起来像是一个可行的解决方案。除了,它不是。 WaitForInputIdle 是为了满足 DDE 的要求而引入的,只是检查目标进程中的线程是否可以接收消息。这实际上意味着该进程中的 any 线程。它并不严格依赖于正在启动的 GUI 和 运行.

可在此处找到有关该主题的其他信息: