【问题标题】:Capturing invisible window with win32 API使用 win32 API 捕获不可见窗口
【发布时间】:2016-01-25 10:52:51
【问题描述】:

尝试使用 BitBlt 捕获窗口的内容。在这种可能很重要的特殊情况下,我说的是不可见的窗口/窗口上的不可见区域 - 由于 z 顺序不可见,它们是可见的但被其他窗口覆盖。我得到的只是一个黑匣子。

HDC winDC = GetWindowDC(hwnd);
HDC hdc_offscreen = CreateCompatibleDC(winDC);

HBITMAP bmp = CreateCompatibleBitmap(winDC, areaWidth, areaHeight);
HGDIOBJ origHandle = SelectObject(hdc_offscreen, bmp);

BitBlt(hdc_offscreen, rect.left, rect.top, 
rect.right - rect.left, 
rect.bottom - rect.top, 
winDC, copy_from.left, copy_from.top, SRCCOPY);

// at this point i expect pixels to be there, but nah!

ReleaseDC(hwnd, winDC);

SelectObject(hdc_offscreen, origHandle);

DeleteDC(hdc_offscreen);
ReleaseDC(hWnd_main, winDC);

hwnd 是我要捕获的窗口。同样的事情就像启用 Aero 主题的魅力一样。我正在使用 Windows 7 专业版。

知道我错过了什么吗?

【问题讨论】:

  • 你今天早些时候不是已经问过这个了吗? stackoverflow.com/questions/34988788/…那个问题怎么了?
  • 我删除了这个问题,因为我不知道如何快速修复不正确的源代码引用。
  • 您在周末还针对您较早的问题发布了一个完全错误的内容。我担心如果您没有立即得到答案,您可能会养成反复问同一个问题的习惯。
  • 你的BitBlt 申请真的很……奇怪。无论如何:此功能根本不用于图像捕获。顾名思义,它的主要目的是对位图进行图形操作。请注意文档中的说明 “并非所有设备都支持 BitBlt 功能” - 您可能拥有一个甚至无法进行 BitBlt 操作的设备,您可以通过 GetDeviceCaps 进行检查
  • 我可以看出这是不可取的。不过,让我再问你一次。如果一扇窗户在另一个窗户下面,为什么它会画任何东西?

标签: c++ winapi gdi


【解决方案1】:

您最好的选择(尽管不能保证有效)是通过发送WM_PRINT 让另一个窗口将自己绘制到您的 DC。

【讨论】:

  • 嗯。你的回答 WM_PAINT(这是错误的),但你链接WM_PRINT(更接近正确,虽然我建议WM_PRINTCLIENT) .
  • @Cody Gray:感谢您发现错字——这使得它非常具有误导性。至于 WM_PRINT v. WM_PRINTCLIENT,我认为意图是抓住整个窗口。如果只是客户区,那么我会首先尝试 WM_PRINTCLIENT。
【解决方案2】:

GetWindowDC 返回的 HDC 不包含窗口的图像。我可以想象这个HDC 指的是与其他窗口相同的“位图”。启用 Aero 后,它们显然不共享相同的“位图”,这就是您获得良好结果的原因。

我宁愿尝试强制窗口绘制到您的 HDC,而不是读取 GetWindowDC 返回的 HDC。要获得客户区,您可以尝试使用您的 HDC 调用 BeginPaint,但谁知道如果一个窗口会检查它(或它的一部分)是否可见呢?

要获得非客户区,您可以使用 HDC 传递 WM_NCPAINT

标准控件支持通过WM_PAINT 传递的 HDC。其他窗口可能支持它,但这不是必需的。如果我没记错的话PrintWindow 依赖于这种行为。

总的来说,我会说没有 100% 的方式来获取窗口的图像,但 BeginPaintWM_NCPAINT 应该是一个很好的起点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    • 2016-11-04
    • 1970-01-01
    • 2012-02-01
    相关资源
    最近更新 更多