/*
说明:枚举指定窗口 且可见子窗体 句柄
文件:FindWindows.h
作者:@jd
枚举指定进程子窗口类
此类以Acrobat Reader DC (AcroRd32.exe)为例
*/
#pragma once
class CFindWindows
{
public:
CFindWindows(void);
~CFindWindows(void);
/*
返回可见子窗口句柄 成功返回--非空 失败返回-NULL
*/
HWND FindPdfWindow(CString strRootClass = _T("AcrobatSDIWindow"), CString strTitle = _T("AVPageView"),
CString strClass = _T("AVL_AVView"), BOOL bIsVisible = TRUE);
HWND FindWndByProcessId(DWORD dwId = ::GetCurrentProcessId());
///< 枚举窗口回调函数
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);
static BOOL CALLBACK EnumProcessWindowsProc( HWND hwnd, LPARAM lParam );
void OnInitData();
CString m_strRootClass; //主进程根类名
CString m_strTitle; //子窗体名
CString m_strClass; //子窗口类,名
BOOL m_bIsVisible; //是否可见
};
//FindWindows.cpp
#include "StdAfx.h"
#include "FindWindows.h"
typedef struct
{
HWND hwndWindow; // 窗口句柄
DWORD dwProcessID; // 进程ID
CFindWindows *pFindWnd;
}EnumWindowsArgEx;
CFindWindows::CFindWindows(void)
{
OnInitData();
}
CFindWindows::~CFindWindows(void)
{
}
HWND CFindWindows::FindPdfWindow(CString strRootClass ,CString strTitle, CString strClass, BOOL bIsVisible /*= TRUE*/ )
{
m_strRootClass = strRootClass;
m_strTitle = strTitle;
m_strClass = strClass;
m_bIsVisible = bIsVisible;
EnumWindowsArgEx ewa;
ewa.dwProcessID =0;// GetCurrentProcessId();
ewa.hwndWindow = NULL;
ewa.pFindWnd = this;
#if G_TEST
HWND hFind = FindWndByProcessId();
#else
HWND hFind = ::FindWindow(m_strRootClass, NULL);
#endif
if (hFind == NULL)
{
ewa.hwndWindow = NULL;
}
else
{
EnumChildWindows(hFind,EnumWindowsProc, (LPARAM)&ewa);
}
OnInitData();
//返回可见子窗口句柄
return ewa.hwndWindow;
}
HWND CFindWindows::FindWndByProcessId( DWORD dwId )
{
EnumWindowsArgEx ewa;
ewa.dwProcessID =dwId;// GetCurrentProcessId();
ewa.hwndWindow = NULL;
ewa.pFindWnd = this;
HWND hwndRet = NULL;
//AcrobatSDIWindow;
EnumWindows(EnumProcessWindowsProc, (LPARAM)&ewa);
if (ewa.hwndWindow)
{
hwndRet = ewa.hwndWindow;
}
return hwndRet;
}
//枚举窗口回调
BOOL CALLBACK CFindWindows::EnumWindowsProc( HWND hwnd, LPARAM lParam )
{
EnumWindowsArgEx *pArg = (EnumWindowsArgEx *)lParam;
if(::GetWindowLong(hwnd, GWL_STYLE)&WS_VISIBLE)
{
TCHAR szTitle[MAX_PATH] = {0};
TCHAR szTitle[MAX_PATH] = { 0 };
//::GetWindowText(hwnd, szTitle, MAX_PATH); 获取其他进程edit会失败,应发送 用wm_gettext
::SendMessage(hwnd, WM_GETTEXT, sizeof(szTitle) / sizeof(TCHAR), (LPARAM)(void*)szTitle);
TCHAR szclass[MAX_PATH] = {0};
::GetClassName(hwnd,szclass,MAX_PATH);
BOOL bIsRet = ::IsWindowVisible(hwnd);
if (bIsRet && (pArg->pFindWnd->m_strTitle.CompareNoCase(szTitle) == 0) && pArg->pFindWnd->m_strClass.CompareNoCase(szclass) == 0)
{
pArg->hwndWindow = hwnd;
//找到可见的窗口弹出了!!!
return FALSE;
}
}
// 没找到,继续找,返回TRUE
return TRUE;
}
BOOL CALLBACK CFindWindows::EnumProcessWindowsProc( HWND hWnd, LPARAM lParam )
{
EnumWindowsArgEx *pInfo = (EnumWindowsArgEx *)lParam;
DWORD dwProcId;
::GetWindowThreadProcessId(hWnd, &dwProcId);
if(dwProcId == pInfo->dwProcessID)
{
// 在此添加更多限制条件
TCHAR szclass[MAX_PATH] = {0};
::GetClassName(hWnd,szclass,MAX_PATH);
if (::IsWindowVisible(hWnd) && (pInfo->pFindWnd->m_strRootClass.CompareNoCase(szclass) == 0) ) // 当前窗口是否可见
{
pInfo->hwndWindow = hWnd; // 获取到第一个窗口句柄
return FALSE;
}
}
return TRUE;
}
void CFindWindows::OnInitData()
{
m_strRootClass = _T("");
m_strTitle = _T("");
m_strClass = _T("");
m_bIsVisible = TRUE;
}
spy++抓取窗口对比如下: