VC2008获取指定的窗口句柄

 

VC2008获取指定的窗口句柄

 

每每编程时都要和窗口句柄hWnd打交道,如果只是MFC的程序还好说this->m_hWnd就解决了,这也只是当前窗口的句柄而已,都说家花哪有野花香,不费力的事情好像不太给力,给点难度对于我们这些初学者来说还是有点成就感的

下面有参考MSDN和网上的资料:

一、

HWND FindWindow(LPCTSTR lpClassName,  LPCTSTR lpWindowName);

这种方法最直接了,不过两参数中有一个不太好得到,WindowName就是窗口名,也就是窗口程序运行时任务栏上显示的;窗口的ClassName一般是看不到了,也就是这个最纠结了。如果当前只运行同一窗口程序的一个实例,就可以直接

::FindWindow(NULL,  LPCTSTR lpWindowName);//这样返回的直接就是指定窗口名的窗口句柄了

二、

HANDLE WINAPI CreateToolhelp32Snapshot( __in DWORD dwFlags, __in DWORD th32ProcessID);

BOOL WINAPI Process32First( __in HANDLE hSnapshot, __in_out LPPROCESSENTRY32 lppe);

BOOL WINAPI Process32Next( __in HANDLE hSnapshot, __out LPPROCESSENTRY32 lppe);

这三个API函数配合使用 结构体PROCESSENTRY32可以参考MSDN

 当然要#include "Tlhelp32.h"

先定义一个全局变量,类中的全局变量就可以

HWND SpecialhWnd;

//枚举窗口回调
//hwnd窗口句柄 lParam指定的进程ID
BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM lParam)
{
 DWORD dwID;
 GetWindowThreadProcessId(hwnd, &dwID);
 if (dwID == (DWORD)lParam && IsWindowVisible(hwnd) && GetParent(hwnd) == NULL)
 {//匹配条件为   进程ID相符&&窗口可见&&无父级窗口(自己是顶级窗口)
  SpecialhWnd = hwnd;//全局变量保存符合的窗口句柄
 }
 return TRUE;
}

EnumWindow  API参考MSDN,第一个参数为回调函数地址,第二个参数为提供给回调函数的参数

BOOL EnumWindows(WNDENUMPROC lpEnumFunc,     LPARAM lParam);

//进程快照枚举进程 lpszProcName指定进程名
void CXXXXXDlg::GethWndByProc32SnapShot(TCHAR* lpszProcName)
{
 PROCESSENTRY32W PE32Info;
 HANDLE hSnapShot;
 BOOL bReport;

 CString OutDebug;

  memset(&PE32Info, 0, sizeof(PROCESSENTRY32W));
  PE32Info.dwSize = sizeof(PROCESSENTRY32W);
 hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//创建进程快照,返回快照句柄
 bReport = Process32FirstW(hSnapShot, &PE32Info);//将第一个进程的信息填充到结构体中
 while (bReport)
 {
   if (!_wcsicmp(PE32Info.szExeFile, lpszProcName))//将当前进程名与指定的进程名不区分大小写比对
  {
   EnumWindows((WNDENUMPROC)EnumWinProc, PE32Info.th32ProcessID);//枚举窗口
   OutDebug.Format(L"进程: %ws > 进程ID: %d > 窗口句柄: 0xx", PE32Info.szExeFile, PE32Info.th32ProcessID, SpecialhWnd);
   OutputDebugStringW(OutDebug);
  }
  bReport = Process32NextW(hSnapShot, &PE32Info);//
 }
 CloseHandle(hSnapShot);
 return;
}

以上两种方法都有个不足就是,如果同时运行一个程序多个实例时,无论窗口名还是进程名都会有相同的好几个,这样第二种方法就只能获取到其中的一个,因为保存句柄的全局变量被重新赋值。

当然不是没有解决的方法,可以将保存句柄的变量定义成一个数组,也就是HWND hWnd[ nsize ];数组的大小自己控制,并定义一个局部的计数器,当有符合条件的句柄时就保存到句柄数组中去。

回调的实现也就是下面那样了:

//枚举窗口回调
//hwnd窗口句柄 lParam指定的进程ID
BOOL CALLBACK EnumWinProc(HWND hwnd, LPARAM lParam)
{
 DWORD dwID;

int count = 0;
 GetWindowThreadProcessId(hwnd, &dwID);
 if (dwID == (DWORD)lParam && IsWindowVisible(hwnd) && GetParent(hwnd) == NULL)
 {
  SpecialhWnd[count++] = hwnd;//全局变量保存符合的窗口句柄
 }
 return TRUE;
}

这样同一程序的不同实例的窗口句柄都可以得到,不过该怎么去区分它们?

解决的方法总是有的,加上一组只能唯一的识别号,进程ID或许可以

除了使用二组数组,还有一种方法就是使用容器,因为不是很理解,这里也不好写下去了,能捧场的多留点口水,实在是想多学点

在网上也还见到过其他方法的,有兴趣的可以去找找,可以自己动动手实践一下






引文来源   VC2008获取指定的窗口句柄_黑幕狼影_百度空间

你可能感兴趣的:(编程相关)