c++ windows 截取指定进程主窗口
时间: 2025-01-06 10:48:28 浏览: 0
在C++中,截取指定进程的主窗口可以通过Windows API实现。以下是一个简单的示例代码,展示了如何获取指定进程的主窗口句柄并进行截屏:
```cpp
#include <windows.h>
#include <iostream>
#include <string>
// 获取指定进程ID的主窗口句柄
HWND GetProcessMainWindow(DWORD processID) {
HWND hwnd = NULL;
DWORD windowProcessID = 0;
// 枚举所有顶级窗口
EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL {
DWORD processID = 0;
GetWindowThreadProcessId(hwnd, &processID);
// 检查窗口是否可见且具有标题
if (IsWindowVisible(hwnd) && GetWindowTextLength(hwnd) > 0) {
DWORD* processIDPtr = reinterpret_cast<DWORD*>(lParam);
if (processID == *processIDPtr) {
// 找到目标进程的主窗口
SetLastError(ERROR_SUCCESS);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)processIDPtr);
return FALSE; // 停止枚举
}
}
return TRUE; // 继续枚举
}, (LPARAM)&processID);
if (GetLastError() == ERROR_SUCCESS) {
hwnd = FindWindowEx(NULL, NULL, NULL, NULL);
while (hwnd != NULL) {
if (GetWindowLongPtr(hwnd, GWLP_USERDATA) == (LONG_PTR)&processID) {
break;
}
hwnd = GetWindow(hwnd, GW_HWNDNEXT);
}
}
return hwnd;
}
// 截取指定窗口的图像
bool CaptureWindow(HWND hwnd, const std::string& filename) {
if (!hwnd) return false;
RECT rect;
if (!GetWindowRect(hwnd, &rect)) return false;
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
// 创建设备上下文
HDC hdcScreen = GetDC(hwnd);
HDC hdcWindow = CreateCompatibleDC(hdcScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height);
SelectObject(hdcWindow, hBitmap);
// 截取窗口图像
if (!BitBlt(hdcWindow, 0, 0, width, height, hdcScreen, 0, 0, SRCCOPY)) {
DeleteObject(hBitmap);
DeleteDC(hdcWindow);
ReleaseDC(hwnd, hdcScreen);
return false;
}
// 保存图像到文件
BITMAP bmp;
GetObject(hBitmap, sizeof(BITMAP), &bmp);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmp.bmWidth;
bi.biHeight = bmp.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmp.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmp.bmHeight;
// 创建文件
HANDLE hFile = CreateFileA(filename.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
DeleteObject(hBitmap);
DeleteDC(hdcWindow);
ReleaseDC(hwnd, hdcScreen);
return false;
}
// 写入文件头
DWORD dwSizeOfDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize = dwSizeOfDIB;
bmfHeader.bfType = 0x4D42; // BM
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPVOID)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPVOID)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
// 写入位图数据
BYTE* lpBits = new BYTE[dwBmpSize];
GetDIBits(hdcWindow, hBitmap, 0, (UINT)bmp.bmHeight, lpBits, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
WriteFile(hFile, (LPVOID)lpBits, dwBmpSize, &dwBytesWritten, NULL);
// 清理
delete[] lpBits;
CloseHandle(hFile);
DeleteObject(hBitmap);
DeleteDC(hdcWindow);
ReleaseDC(hwnd, hdcScreen);
return true;
}
int main() {
DWORD processID = 1234; // 替换为目标进程的ID
HWND hwnd = GetProcessMainWindow(processID);
if (hwnd) {
std::cout << "找到主窗口句柄: " << hwnd << std::endl;
CaptureWindow(hwnd, "screenshot.bmp");
std::cout << "截屏保存为 screenshot.bmp" << std::endl;
} else {
std::cout << "未找到主窗口句柄" << std::endl;
}
return 0;
}
```
阅读全文