hur.cn - 华软网

 热门搜索

有时一个进程有多个父窗口(句柄),怎样判断哪个是进程主窗口(句柄)

  作者:未知    来源:网络    更新时间:2010/1/16
我写了一个程序,可以取得该进程的所有父窗口的句柄,但连calc.exe的进程都有两个父窗口,怎样判断哪个一句柄才是真正的主窗口句柄!
C++">
// 取进程父窗口句柄.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 object

CWinApp 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;
}




---华软 网友回答---
我写了一个程序,可以取得该进程的所有父窗口的句柄,但连calc.exe的进程都有两个父窗口,怎样判断哪个一句柄才是真正的主窗口句柄! 
==============
进程那有什么父窗口啊?进程只有父进程,如果是窗口的父窗口也只有一个,不可能有两个的
---华软网友回复---
引用 1 楼 wltg2001 的回复:
我写了一个程序,可以取得该进程的所有父窗口的句柄,但连calc.exe的进程都有两个父窗口,怎样判断哪个一句柄才是真正的主窗口句柄!
==============
进程那有什么父窗口啊?进程只有父进程,如果是窗口的父窗口也只有一个,不可能有两个的

[img=http://user.qzone.qq.com/55713720/infocenter?ptlang=2052&ADUIN=55713720&ADSESSION=1263602361&ADTAG=CLIENT.QQ.2653_Mysrv.0][/img]
---华软网友回复---
看了一下你的代码,你用EnumWindows来枚举QQ的窗口,一个程序其实是有很多窗口的,我不明白你所说的“取得该进程的所有父窗口”是什么意思,一般来说,QQ的父窗口应该就是指桌面,“calc.exe有两个父窗口”,这个也不太明白,calc.exe的父窗口如果没有特殊处理也只能是桌面,或是没有父窗口才对
---华软网友回复---
你试试我的程序就知道了!

---华软网友回复---
你上面的图没问题啊,一个计算器中有很多窗口,000707F4是主窗口,所以它没有父窗口,余下的是子窗口,都是000707F4这个窗口的子窗口啊,哪里有多个父窗口啊?
---华软网友回复---
首先我在枚举里没有返回FALSE
如上图
如果先枚举000607FA就返回的话,取的不是真正的父窗口句柄,我的意思是在枚举出000607FA和000707F4这两个句柄后,怎样判断谁才是真正的父窗口,真正的父窗口句柄是可以接收WM_CLOSE消息的,其它父窗口是收不了WM_CLOSE消息的.
---华软网友回复---
明白了,不过“父窗口”这个词可不是你这么用的!你所说的窗口好像叫主窗口要好一点,你用EnumWindows来枚举窗口恐怕很难分辨出哪个窗口是主窗口,因为一个进程本身可以有很多窗口,而且这些窗口之间不一定有“父子关系”,可能都是顶层窗口,你所说的不接收WM_CLOSE,一般来说,顶层窗口只有是可视的都会接收这个消息,你上面的000607FA可能并不是可视的窗口吧!
---华软网友回复---
引用 7 楼 wltg2001 的回复:
明白了,不过“父窗口”这个词可不是你这么用的!你所说的窗口好像叫主窗口要好一点,你用EnumWindows来枚举窗口恐怕很难分辨出哪个窗口是主窗口,因为一个进程本身可以有很多窗口,而且这些窗口之间不一定有“父子关系”,可能都是顶层窗口,你所说的不接收WM_CLOSE,一般来说,顶层窗口只有是可视的都会接收这个消息,你上面的000607FA可能并不是可视的窗口吧!

就是这个意思,最终问题,分辨哪个顶层窗口是主窗口!
---华软网友回复---
用这些吗?
GetWindowInfo
GetWindow
---华软网友回复---
枚举窗口可能做不到这一点,其实一个进程也没有主窗口和非主窗口一说,大家都是顶层窗口,没有主从之分的,不过你所举例子中的那个窗口应该是隐藏的,所以可以用IsWindowVisible来看一下是不是隐藏窗口,如果是隐藏的,一定不是你想要的窗口了。
---华软网友回复---
没有进程的主窗口的说法,一般来说你软件功能上会有个主窗口,主要功能在这个窗口里。。
---华软网友回复---
是不是一个进程的顶层窗口只有一个非隐藏窗口!
---华软网友回复---
引用 12 楼 lili00000 的回复:
是不是一个进程的顶层窗口只有一个非隐藏窗口!

这也不一定,完全在于你的程序如何设计,有很软件就有多个不隐藏的顶层窗口。
---华软网友回复---
JJYY一大轮,到底还是没有解决啊。

2个星期前看过解决方案是可以通过句柄看到窗口类名的,我想通过类名判断句柄是哪个窗口的

我的问题是程序一开始有个标题窗口

过了5秒,才会出现主窗口,标题窗口就撤销了

我就是要判断句柄是主窗口,而不是一开始的标题窗口

PS.2个都是主窗口,我解决了再发上来吧

---华软网友回复---
参考这个
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)也有不止一个主窗口。如图一所示,资源管理器有两个主窗口。一般来讲,想要获取主窗口,凭窗口的式样或类名,你没有什么办法知道哪一个窗口是真正意义上的主窗口?
---华软网友回复---
简单来说就是这个方法

char classname[256];
GetClassName(hwnd,classname,sizeof(classname));

通过句柄找类名      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。