#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.获取窗口内容的两种方式:
GetWindowText(hWnd, szOut);
SendMessage(hWnd, WM_GETTEXT, nLen, szOut);
两种方式对于进程内的操作来说是一样的。
但是跨进程操作时,前者只返回窗口的标题(有的窗口可能没有标题),后者返回窗口文本。
2.wprintf如果要输出中文需要在程序入口添加setlocale(LC_CTYPE, "chs");
3.EnumWindows只能枚举顶级窗口,需要递归调用EnumChildWindows才能获得进程的所有窗口。