遍历查找某个进程拥有的所有窗口
#include <windows.h> #include <TlHelp32.h> #include <atlstr.h> #include <locale.h> #define WINDOW_TEXT_LENGTH 256 BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam) { DWORD dwPid = 0; GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程 if(dwPid == lParam) // 判断是否是目标进程的窗口 { printf("0x%08X ", hWnd); // 输出窗口信息 TCHAR buf[WINDOW_TEXT_LENGTH]; SendMessage(hWnd, WM_GETTEXT, WINDOW_TEXT_LENGTH, (LPARAM)buf); wprintf(L"%s/n", buf); EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam); // 递归查找子窗口 } return TRUE; } BOOL CALLBACK EnumWindowCallBack(HWND hWnd, LPARAM lParam) { DWORD dwPid = 0; GetWindowThreadProcessId(hWnd, &dwPid); // 获得找到窗口所属的进程 if(dwPid == lParam) // 判断是否是目标进程的窗口 { printf("0x%08X ", hWnd); // 输出窗口信息 TCHAR buf[WINDOW_TEXT_LENGTH]; SendMessage(hWnd, WM_GETTEXT, WINDOW_TEXT_LENGTH, (LPARAM)buf); wprintf(L"%s/n", buf); EnumChildWindows(hWnd, EnumChildWindowCallBack, lParam); // 继续查找子窗口 } return TRUE; } int main() { setlocale(LC_CTYPE, "chs"); DWORD qqPid = 0; // 进程id PROCESSENTRY32 pe; // 进程信息 pe.dwSize = sizeof(PROCESSENTRY32); HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 进程快照 if(!Process32First(hSnapshot, &pe)) // 得到第一个进程的快照 return 0; do { if(!Process32Next(hSnapshot, &pe)) return 0; } while (StrCmp(pe.szExeFile, L"QQ.exe")); // 遍历进程直到找打目标进程 qqPid = pe.th32ProcessID; wprintf(L"Find QQ.exe process: 0x%08X/n", qqPid); EnumWindows(EnumWindowCallBack, qqPid); return 0; } |
1.获取窗口内容的两种方式:
GetWindowTest(hWnd, szOut);
SendMessage(hWnd, WM_GETTEXT, nLen, szOut);
两种方式对于进程内的操作来说是一样的。
但是跨进程操作时,前者只返回窗口的标题(有的窗口可能没有标题),后者返回窗口文本。
2.wprintf如果要输出中文需要在程序入口添加setlocale(LC_CTYPE, "chs");
3.EnumWindows只能枚举顶级窗口,需要递归调用EnumChildWindows才能获得进程的所有窗口。