我写了一个程序,可以取得该进程的所有父窗口的句柄,但连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;
}
//#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;
}
解决方案 »
- 如何截获删除进程的消息
- 从入门到精通'图形学矩阵相乘、矩阵运算'看哪个人写的书好,哪个出版社的书好,才能少走弯路?
- 求几何图形旋转算法!
- 一个基于视图类的应用程序如何调用对话框
- 通过socket传送类,请问vc和vb.net的类,如果定义一样,可以传送吗?
- 如何调用此函数?
- dblist ,dbcombo,datalist,之类的控件是否可以用在vc中
- 屏幕刷新问题,求救!!!
- 如何在VC里编译C语言的程序?
- 请教omnihttpd.obj : error LNK2001: unresolved external symbol _closesocket@4我调试了好长时间也不行
- 在线程里动态创建CEdit,为什么线程退出后CEdit就消失了?如果线程继续进行业务操作,此时CEdit也不能接收消息了
- 怎样继承CFormView类
==============
进程那有什么父窗口啊?进程只有父进程,如果是窗口的父窗口也只有一个,不可能有两个的
如上图
如果先枚举000607FA就返回的话,取的不是真正的父窗口句柄,我的意思是在枚举出000607FA和000707F4这两个句柄后,怎样判断谁才是真正的父窗口,真正的父窗口句柄是可以接收WM_CLOSE消息的,其它父窗口是收不了WM_CLOSE消息的.
GetWindowInfo
GetWindow
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)也有不止一个主窗口。如图一所示,资源管理器有两个主窗口。一般来讲,想要获取主窗口,凭窗口的式样或类名,你没有什么办法知道哪一个窗口是真正意义上的主窗口?
GetClassName(hwnd,classname,sizeof(classname));通过句柄找类名