使用win32 API捕获不可见窗口

时间:2016-01-25 10:52:52

标签: c++ winapi gdi

尝试使用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 Professional。

知道我错过了什么吗?

2 个答案:

答案 0 :(得分:3)

你最好的选择(尽管它不能保证工作)是通过发送WM_PRINT来要求另一个窗口将自己画给你的DC。

答案 1 :(得分:0)

GetWindowDC返回的HDC只是不包含窗口的图像。我可以想象这个HDC指的是同一个"位图"像其他窗户一样。启用Aero后,他们显然不会共享相同的"位图"这就是你获得好成绩的原因。

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

要获得非客户区域,您可以通过HDC传递WM_NCPAINT

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

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