特定窗口c ++的屏幕截图

Posted

技术标签:

【中文标题】特定窗口c ++的屏幕截图【英文标题】:Screen capture of specific window c++ 【发布时间】: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_PRINTBitBlt()等),用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 中所述)。如果没有其他人可以,我会看看我是否可以调查一下。 【参考方案1】:

最简单的方法是使用PrintWindow。

这里有一些例子:

如果您想绘制整个窗口(带有框架),只需这样做: PrintWindow(calculatorHwnd, destHwnd, 0); 如果您只想捕获窗口的客户区,可以采用以下方法: PrintWindow(calculatorHwnd, destHwnd, PW_CLIENTONLY);

【讨论】:

不是通用解决方案。这需要必须正确处理 WM_PRINT 的目标窗口的合作。如果没有,你可能会得到垃圾或什么都没有。 而且很多应用无法处理WM_PRINT【参考方案2】:

考虑的方法是CreateForWindow。

考虑到目标窗口是可移动的,另一个角度是将其重新定位到当前桌面的左上角。捕获entire screen,然后在您知道窗口尺寸的情况下将其裁剪为这些尺寸。 如果security programs 可以暂停或终止,目标窗口不是cloaked,或者以上述 cmets 中讨论的方式组合,或者可以暂时禁用 Aero,则此操作成功的机会更大。

【讨论】:

以上是关于特定窗口c ++的屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章

即使窗口重叠,如何在 Qt(Python、Linux)中截取特定窗口的屏幕截图?

如何使用c ++为最小尺寸的窗口制作屏幕截图

如何使用c ++为最小尺寸的窗口制作屏幕截图

在 QML 中截取特定项目的屏幕截图的方法是啥?

Mac Catalyst 调整屏幕截图的窗口大小

C语言 服务项进行全屏幕截图 但是截图后是黑屏怎么办?