c++ 枚舉指定進程子窗口以Acrobat Reader DC (AcroRd32.exe)爲例

/*

說明:枚舉指定窗口 且可見子窗體 句柄
文件: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++抓取窗口對比如下:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章