有些时候我们通过CreateProcess之后,想知道这个进程是不是有错误窗口弹出。有一种方法就是通过枚举窗口的方式进行。下面是相关的说明。还有一种就是我们不想知道具体的窗口信息,只是想知道有没有窗口弹出,那么我们可以使用GetGUIThreadInfo()函数进行。相应的代码在下面也会有说明。
关键系统函数:
(一)BOOL EnumWindows(
WNDENUMPROC lpEnumFunc, //回调函数指针
LPARAM lParam //传递给回调函数的参数
);
typedef BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam);
该函数枚举所有顶层窗口。如果lpEnumFunc返回值为FALSE,则中止枚举。
如果函数成功,返回值为非零;如果函数失败,返回值为零
(二)
DWORD GetWindowThreadProcessId(
HWND hWnd, // 窗口句柄
LPDWORD lpdwProcessId //【OUT】指向进程ID变量的地址。
);
获取创建窗口的进程ID,返回值为创建窗口的线程ID
代码实现:
typedef struct EnumFunArg
{
HWND hWnd;
DWORD dwProcessId;
}EnumFunArg;
BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
{
EnumFunArg *pArg = lParam;
DWORD processId;
GetWindowThreadProcessId(wnd, &ProcessId);
if( processId == pArg->dwProcessId )
{
arg->hWnd = hwnd;
return TRUE;
}
return FALSE;
}
HWND myGetWindowByProcessId( DWORD dwProcessId )
{
lEnumFunArg arg;
arg.dwProcessId = dwProcessId;
arg.hWnd = 0;
EnumWindows(lpEnumFunc, (LPARAM)&arg );
return arg.hWnd;
}
注意:
一个进程可能创建多个窗口,比如,在程序里使用MessageBox.
下面说说通过GetGUIThreadInfo()函数进行检测。这种方法要简单的很多。只是几句就够了。给一个完整的例子。
PROCESS_INFORMATION psinfo;
STARTUP_INFO si;
GUITHREADINFO gui;
if(CreateProcess(.....))
{
WaitForInputIdle(psinfo.hProcess,INFINTE);
GetGUIThreadInfo(psinfo.dwThreadId,&gui);
if(gui.hwndActive)
{
printf("发现有窗口存在!");
}
}