我写了一个程序,可以取得该进程的所有父窗口的句柄,但连calc.exe的进程都有两个父窗口,怎样判断哪个一句柄才是真正的主窗口句柄!// 取进程父窗口句柄.cpp : Defines the entry point for the console application.
//#include "stdafx.h"
#include "取进程父窗口句柄.h"
#include <Tlhelp32.h>
#include <winuser.h>#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// The one and only application objectCWinApp theApp;using namespace std;DWORD GetPID(CString name) 
{//跟据文件名取得PID(进程ID)
name.MakeLower();
HANDLE         hProcessSnap = NULL; 
BOOL           bRet      = FALSE; 
PROCESSENTRY32 pe32      = {0}; 
CString temp;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
if (hProcessSnap == INVALID_HANDLE_VALUE) 
return (FALSE); 
pe32.dwSize = sizeof(PROCESSENTRY32); 
if (Process32First(hProcessSnap, &pe32)) 
{
do 
{
temp=pe32.szExeFile;
temp.MakeLower();
if (name==temp)
{
return pe32.th32ProcessID;
}
} while (Process32Next(hProcessSnap, &pe32));

}
CloseHandle (hProcessSnap); 
}HWND GetParentHwnd(HWND hwnd)
{//取句柄的父窗口句柄
HWND htemp;
htemp=GetParent(hwnd);
if (htemp)
{
return GetParentHwnd(htemp);
}
else
{
return hwnd;
}
}BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{//枚举回调
HWND htemp;
DWORD id,PID;
CString cs;
PID=GetWindowThreadProcessId(hwnd,&id);
if (id==lParam)
{
printf("句柄%X的PID为:%d,它的线程ID为:%X\n",hwnd,id,PID);
htemp=GetParentHwnd(hwnd);
if (htemp)
{
printf("%X的父窗口为:%X\n",hwnd,htemp);
cout<<"--------------------------"<<endl;
return TRUE;
}
else
{
return TRUE;
}
return TRUE;

}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0; // initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
CString name="qq.exe";
DWORD PID=GetPID(name);
cout<<(LPCTSTR)name<<"的PID为:"<<PID<<endl<<"---------------------------"<<endl;
EnumWindows(EnumWindowsProc,PID);
}
return nRetCode;
}

解决方案 »

  1.   

    我写了一个程序,可以取得该进程的所有父窗口的句柄,但连calc.exe的进程都有两个父窗口,怎样判断哪个一句柄才是真正的主窗口句柄! 
    ==============
    进程那有什么父窗口啊?进程只有父进程,如果是窗口的父窗口也只有一个,不可能有两个的
      

  2.   

    看了一下你的代码,你用EnumWindows来枚举QQ的窗口,一个程序其实是有很多窗口的,我不明白你所说的“取得该进程的所有父窗口”是什么意思,一般来说,QQ的父窗口应该就是指桌面,“calc.exe有两个父窗口”,这个也不太明白,calc.exe的父窗口如果没有特殊处理也只能是桌面,或是没有父窗口才对
      

  3.   

    首先我在枚举里没有返回FALSE
    如上图
    如果先枚举000607FA就返回的话,取的不是真正的父窗口句柄,我的意思是在枚举出000607FA和000707F4这两个句柄后,怎样判断谁才是真正的父窗口,真正的父窗口句柄是可以接收WM_CLOSE消息的,其它父窗口是收不了WM_CLOSE消息的.
      

  4.   

    明白了,不过“父窗口”这个词可不是你这么用的!你所说的窗口好像叫主窗口要好一点,你用EnumWindows来枚举窗口恐怕很难分辨出哪个窗口是主窗口,因为一个进程本身可以有很多窗口,而且这些窗口之间不一定有“父子关系”,可能都是顶层窗口,你所说的不接收WM_CLOSE,一般来说,顶层窗口只有是可视的都会接收这个消息,你上面的000607FA可能并不是可视的窗口吧!
      

  5.   

    用这些吗?
    GetWindowInfo
    GetWindow
      

  6.   

    枚举窗口可能做不到这一点,其实一个进程也没有主窗口和非主窗口一说,大家都是顶层窗口,没有主从之分的,不过你所举例子中的那个窗口应该是隐藏的,所以可以用IsWindowVisible来看一下是不是隐藏窗口,如果是隐藏的,一定不是你想要的窗口了。
      

  7.   

    JJYY一大轮,到底还是没有解决啊。2个星期前看过解决方案是可以通过句柄看到窗口类名的,我想通过类名判断句柄是哪个窗口的我的问题是程序一开始有个标题窗口过了5秒,才会出现主窗口,标题窗口就撤销了我就是要判断句柄是主窗口,而不是一开始的标题窗口PS.2个都是主窗口,我解决了再发上来吧
      

  8.   

    参考这个
    http://blogold.chinaunix.net/u2/62117/showart_2070614.html
    这个可以下载源码
    http://dev.21tx.com/2005/05/06/12043.html摘抄一小段,
    在编写工具程序以及系统管理程序的时候。常常需要获取某个进程的主窗口以及创建此进程的程序名。获取主窗口的目的是向窗口发送各种消息。获取启动进程的程序名可以控制对进程的操作。但是有些进程往往有多个主窗口。你要的是哪一个主窗口呢?如果你用过Outlook程序,你就会发现它有多个主窗口,一个窗口列出收件箱和其它文件夹。如果你打开e-mail,便会有另外一个窗口显示信息。它们都是没有父窗口(或者说宿主窗口)的主窗口。运行一下Spy程序,你甚至会发现它们的窗口类名都相同:rctrl_renwnd32。资源管理器(Explorer.exe)也有不止一个主窗口。如图一所示,资源管理器有两个主窗口。一般来讲,想要获取主窗口,凭窗口的式样或类名,你没有什么办法知道哪一个窗口是真正意义上的主窗口?
      

  9.   

    简单来说就是这个方法char classname[256];
    GetClassName(hwnd,classname,sizeof(classname));通过句柄找类名