【发布时间】:2017-10-11 01:41:30
【问题描述】:
我想截取某些特定窗口(例如计算器)的屏幕截图。
这是我根据this讨论写的代码:
// Get the window handle of calculator application.
HWND hWnd = ::FindWindow(0, _T("Calculator"));
RECT r;
GetWindowRect(hWnd, &r);
int x[2]; int y[2];
x[0] = r.top; x[1] = r.bottom;
y[0] = r.left; y[1] = r.right;
HDC hScreen = GetWindowDC(hWnd);
HDC hDC = CreateCompatibleDC(hScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, y[1] - y[0], x[1] - x[0]);
HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
BitBlt(hDC, 0, 0, y[1] - y[0], x[1] - x[0], hScreen, y[0], x[0], SRCCOPY);
之后,我将位图保存为 .bmp 图像。
结果具有正确的计算器窗口大小和位置,但生成的 bmp 全黑。
我尝试截取整个桌面,然后剪掉计算器部分,这很奏效。但我希望能够对窗口进行截图,即使它被最小化或被另一个窗口覆盖。
任何想法为什么此代码不起作用或有其他方法吗?
谢谢。
【问题讨论】:
-
"即使已最小化" - 无法以这种方式捕获最小化的窗口。但是您可以暂时恢复窗口(在屏幕外,或者 alpha 半透明度为 1,因此用户看不到它),捕获它,然后重新最小化它。
-
此外,在 Win7+ 中,应用程序可以通过
SetWindowDisplayAfffinity()选择不让其 Windows 被捕获。 -
@zett42:对于最小化的窗口,您可以使用DWM Thumbnail API。
-
@mbaros: 要捕获一个最小化的窗口,我调用
SystemParametersInfo(SPI_SETANIMATION)来关闭窗口动画,如果需要在窗口上启用WS_EX_LAYERED,使用SetWindowLayeredAttributes()对窗口应用1 的alpha ,用ShowWindow(SW_RESTORE)恢复窗口,用InvalidateRect()和UpdateWindow()重新绘制窗口,抓取窗口位图(WM_PRINT,BitBlt()等),用ShowWindow(SW_MINIMIZE)最小化窗口,将窗口alpha重置为255,如果需要删除WS_EX_LAYERED,如果需要启用窗口动画。 -
@zett42:没错,我忽略了那个“细节”。还有一个我没有评估过的想法:使用
WS_EX_NOREDIRECTIONBITMAPextended window style 创建一个窗口,并设置您自己的翻转链(如Windows with C++ : High-Performance Window Layering Using the Windows Composition Engine 中所述)。如果没有其他人可以,我会看看我是否可以调查一下。
标签: c++ windows winapi screenshot gdi