gpt4 book ai didi

c++ - 隐藏窗口的PrintWindow和BitBlt

转载 作者:太空狗 更新时间:2023-10-29 20:20:07 33 4
gpt4 key购买 nike

我的程序正在截取其他应用程序窗口的屏幕截图以自动执行它们的某些任务。这些窗口有时会隐藏在屏幕外或被其他窗口遮挡。

为了减少困惑,我从代码 list 中删除了所有错误检查。我正在准备两种类型的屏幕截图

// Get size of the target window.
RECT clientRect;
GetClientRect(hwnd, &clientRect);
int width = clientRect.right - clientRect.left;
int height = clientRect.bottom - clientRect.top;
// Create a memory device context.
HDC windowDC = GetDC(hwnd);
HDC memoryDC = CreateCompatibleDC(windowDC);
// Create a bitmap for rendering.
BITMAPINFO bitmapInfo;
ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biHeight = -height;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biSizeImage = width * height * 4;
RGBQUAD* buffer;
HBITMAP bitmap = CreateDIBSection(windowDC, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, 0, 0);
HGDIOBJ previousObject = SelectOBject(memoryDC, bitmap);

然后我用其中任何一个截取实际的屏幕截图

PrintWindow(hwnd, memoryDC, PW_CLIENTONLY); 
GdiFlush();

UpdateWindow(hwnd);
BitBlt(memoryDC, 0, 0, width, height, windowDC, 0, 0, SRCCOPY);
GdiFlush();

然后我将缓冲区内容复制到一个 vector

std::vector<RGBQUAD> pixels;
pixels.resize(width * height, { 0, 0, 0, 0 });
memcpy(&pixels[0], buffer, bitmapInfo.bmiHeader.biSizeImage);

最后我用

清理了一切
ReleaseDC(hwnd, windowDC);
SelectObject(memoryDC, previousObject);
DeleteDC(memoryDC);
DeleteObject(bitmap);

我对上面的代码有三个问题:

  1. 我需要调用 GdiFlush() 吗?我阅读了文档并进行了一些 Google 研究,但我仍然不确定调用它是否有意义。
  2. BitBlt() 之前调用 UpdateWindow() 有什么不同吗?这是否有助于设备上下文内容“更新”?
  3. 我是否正确地假设对于 PrintWindow() 所有工作都是在目标应用程序内部完成的(增加目标应用程序的 CPU 使用率),而 BitBlt()完全从调用线程内执行(因此增加了我自己的应用程序的 CPU 使用率)?
  4. 在什么情况下上述功能可能失效?我知道 BitBlt() 仅适用于启用桌面组合 (DWM) 的隐藏窗口,但在非常小的系统集 (Windows 8/10) BitBlt()PrintWindow() 对于它们在其他系统上工作正常的窗口似乎失败(即使启用了 DWM)。不过,我无法发现任何模式来说明原因。

感谢任何信息,谢谢。

最佳答案

最后,经过几个小时的调查,我找到了解决该问题的方法:在要成像的表单的 ACTIVATE 事件中调用以下命令就足够了(VB 编码中的示例):

Call SetWindowLong(me.hwnd, GWL_EXSTYLE, WS_EX_LAYERED)

而这个命令定义如下:

Private Declare Function SetWindowLong Lib "User32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Private Const GWL_EXSTYLE = (-20)

Private Const WS_EX_LAYERED = &H80000

请试试这个!

最好的问候,小鹿斑比66

关于c++ - 隐藏窗口的PrintWindow和BitBlt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53710135/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com