Windows跨进程获取列表中的数据
首先需要用到Spy++来查看目标窗体信息
主窗体Caption是"MFCApp"
ListView class是"SysListView32"
ListHeader class是"SysHeader32"
下面是代码实现
#include <iostream> #include <string> #include <Windows.h> #include <CommCtrl.h> using namespace std; //回调函数用于枚举子控件 BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam) { char buffer[256] = { 0 }; GetClassNameA(hwndChild, buffer, sizeof(buffer)); std::string childClassName(buffer); std::cout << "Child Control Class Name: " << childClassName << std::endl; return TRUE; } LPSTR ShunW2A(LPCWSTR lpcwszStrIn) { LPSTR pszOut = nullptr; if (lpcwszStrIn != nullptr) { int nInputStrLen = (int)wcslen(lpcwszStrIn); //获得缓冲所需的字节数大小 int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, lpcwszStrIn, nInputStrLen, nullptr, 0, 0, 0) + 2; pszOut = new char[nOutputStrLen]; if (pszOut) { memset(pszOut, 0, nOutputStrLen); WideCharToMultiByte(CP_ACP, 0, lpcwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0); } } return pszOut; } int main() { //获取目标应用程序的句柄 HWND hWndParent = nullptr; hWndParent = FindWindowA(nullptr, "MFCApp"); if (hWndParent == nullptr) { cout << L"未找到目标应用程序" << endl; return -1; } // 将目标窗口置顶 SetWindowPos(hWndParent, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); EnumChildWindows(hWndParent, EnumChildProc, 0); HWND hWndListCtrl = FindWindowExA(hWndParent, nullptr, "SysListView32", nullptr); if (hWndListCtrl == nullptr) { cout << "Child control not found with class name:" << "SysListView32" << endl; return -1; } DWORD PID; GetWindowThreadProcessId(hWndListCtrl, &PID); HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID); //获取目标进程句柄失败 if (!hProcess) { cout << "获取目标句柄失败!" << endl; return -1; } int nBufferLength = 1024; //窗口句柄 //HWND hWnd = NULL; //获取ListView列头句柄 HWND hLVHeader = (HWND)::SendMessage(hWndListCtrl, LVM_GETHEADER, 0, 0); //获取ListView列数 int nColumnCount = (int)::SendMessage(hLVHeader, HDM_GETITEMCOUNT, 0, 0); //获取ListView行数 int nRowCount = (int)::SendMessage(hWndListCtrl, LVM_GETITEMCOUNT, 0, 0); if (nRowCount <= 0) { cout << "内容为空" << endl; return -1; } //在目标进程地址空间分配内存 LVITEM *pVirtualItem = (LVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE); wchar_t *pVirtualBuffer = (wchar_t*)VirtualAllocEx(hProcess, NULL, nBufferLength * 2, MEM_COMMIT, PAGE_READWRITE); if ((!pVirtualItem) || (!pVirtualBuffer)) { cout << "内存分配失败!" << endl; return -1; } int nColumnIndex = 0, nRowIndex = 0; //缓冲区大小 LVITEM lvitem; wchar_t* buffer = new wchar_t[nBufferLength]; //UNICODE wmemset(buffer, 0, nBufferLength); for (int i = 0; i < nRowCount; i++) { for (int j = 0; j < nColumnCount; j++) { nColumnIndex = i; nRowIndex = j; lvitem.cchTextMax = nBufferLength * 2; lvitem.iSubItem = nRowIndex; lvitem.pszText = pVirtualBuffer; //核心技术:将LVITEM结构体插入目标进程里,然后通过LVM_GETITEMTEXT消息获取指定项的文本 WriteProcessMemory(hProcess, pVirtualItem, &lvitem, sizeof(LVITEM), NULL); ::SendMessage(hWndListCtrl, LVM_GETITEMTEXT, (WPARAM)nColumnIndex, (LPARAM)pVirtualItem); ReadProcessMemory(hProcess, pVirtualBuffer, buffer, nBufferLength * 2, NULL); //转换成ANSI编码 char* ansiBuffer = ShunW2A(buffer); cout << ansiBuffer << endl; delete[]ansiBuffer; } } //释放目标进程里分配的内存 VirtualFreeEx(hProcess, pVirtualItem, sizeof(LVITEM), MEM_FREE); VirtualFreeEx(hProcess, pVirtualBuffer, nBufferLength * 2, MEM_FREE); CloseHandle(hProcess); delete[]buffer; // 将目标窗口的Z序位置设置为普通窗口 SetWindowPos(hWndParent, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); //获取按钮的文本内容 HWND hWndButton = FindWindowExA(hWndParent, nullptr, "Button", nullptr); if (hWndButton == nullptr) { cout << "Child control not found with class name:" << "Button" << endl; return -1; } int textLength = GetWindowTextLengthA(hWndButton); if (textLength <= 0) { cout << "Control has no text" << endl; return -1; } char* buffer_text = new char[textLength + 1]; GetWindowTextA(hWndButton, buffer_text, textLength + 1); std::string controlText(buffer_text); delete[] buffer_text; cout << "Control Text:" << controlText << endl; return 1; }
分类:
Windows核心编程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?