刚接触MFC没多久,碰到一个需求,去获取其他进程的窗口句柄,但是我用 FindWindow()和EnumWindows()等方法获取到的句柄不一致,希望各位帮忙解解惑。
以下是我获取句柄的三种方法
方法一
//通过进程名获取进程ID
DWORD GetPidByProcessName(TCHAR *pProcess)
{
HANDLE hSnapshot;
PROCESSENTRY32 lppe;
//创建系统快照
hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); //#include<Tlhelp32.h>
if (hSnapshot == NULL)
return 0;
//初始化 lppe 的大小
lppe.dwSize = sizeof(lppe);
//查找第一个进程
if (!::Process32First(hSnapshot, &lppe))
return false;
do
{
if(StrCmp(lppe.szExeFile, pProcess) == 0)
{
return lppe.th32ProcessID;
}
}
while (::Process32Next(hSnapshot, &lppe)); //查找下一个进程
return 1;
}
HWND GetHwndByPid(DWORD dwProcessID)
{
//返回Z序顶部的窗口句柄
HWND hWnd = ::GetTopWindow(0);
while ( hWnd )
{
DWORD pid = 0;
//根据窗口句柄获取进程ID
DWORD dwTheardId = ::GetWindowThreadProcessId( hWnd,&pid);
if (dwTheardId != 0)
{
if ( pid == dwProcessID )
{
flag=false;
return hWnd;
}
}
//返回z序中的前一个或后一个窗口的句柄
hWnd = ::GetNextWindow(hWnd , GW_HWNDNEXT);
}
return NULL;
}
方法二:
typedef struct EnumFunArg
{
HWND hWnd;
DWORD dwProcessId;
}EnumFunArg,*LPEnumFunArg;
BOOL CALLBACK lpEnumFunc(HWND hwnd, LPARAM lParam)
{
EnumFunArg *pArg = (LPEnumFunArg)lParam;
DWORD processId;
GetWindowThreadProcessId(hwnd, &processId);
if( processId == pArg->dwProcessId)
{
pArg->hWnd = hwnd;
return FALSE;
}
return TRUE;
}HWND ReturnWnd(DWORD processID)
{
HWND retWnd=NULL;
EnumFunArg wi;
wi.dwProcessId =processID;
wi.hWnd = NULL;
EnumWindows(lpEnumFunc,(LPARAM)&wi);
if(wi.hWnd){ retWnd=wi.hWnd;
} return retWnd;
}
方法三:
hwnd3= ::FindWindow(NULL,_T("QuickWatch_V00.01"));
运行结果及报错内容 :
方法一和方法二获取到的句柄相同,但与方法三获取的不同。我用Spy++查看,方法三获取到的才是正确的句柄。
以下是方法三获取到的句柄的信息
以下是方法一和方法二获取到的句柄的信息
好像方法一和方法二获取到的是方法三获取到的窗口的子窗口,这是什么原因?希望各位来指点一下,十分感谢!!