【发布时间】:2013-11-13 22:27:53
【问题描述】:
我正在尝试截取 Chrome 窗口的屏幕截图。它看起来像这样:
当我使用PrintWindow 获取屏幕截图时,我可以看到窗口标题栏/Chrome 选项卡区域闪烁。捕获的屏幕截图包含一个奇怪的 Windows Basic 风格的标题栏渲染(即使我的机器运行 Aero 主题):
我注意到其他一些应用程序也表现出类似的行为,它们在屏幕上闪烁,但标题栏伪影在捕获的屏幕截图中不可见。执行此操作的应用程序包括 Office 2010、IE 10 和 Trillian 选项卡式聊天窗口 — 换句话说,扩展非客户区的窗口似乎存在此问题。
重现这一点的代码很简单:
void Screenshot(HWND hWnd) {
RECT rc;
GetClientRect(hWnd, &rc);
HDC hdcScreen = GetDC(NULL);
HDC hdc = CreateCompatibleDC(hdcScreen);
HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen,
rc.right - rc.left, rc.bottom - rc.top);
SelectObject(hdc, hbmp);
//Print to memory hdc
PrintWindow(hWnd, hdc, PW_CLIENTONLY);
}
为什么我看到闪烁和奇怪的视觉伪影?我能做些什么来阻止它?
【问题讨论】:
-
使用您的代码,我无法重现。 Windows 7 64。使用 32b 或 64b 版本。使用 PW_CLIENTONLY 或 0。目标:Chrome 主窗口或 Excel 2010 主窗口。没有闪烁,“几乎”好的 PNG(使用 GDIPLUS)
-
@manuell:有趣的是,在我的实际应用中,每次我调用
PrintWindow时都会发生闪烁(这是在窗口获得焦点后不久)。在我做while (1) { Screenshot(hWnd); Sleep(100); }的准系统测试应用程序中,闪烁是间歇性的。 -
应用程序处理“焦点”和“活动”窗口消息的方式很长/之前/实际绘画发生,恕我直言。我敢打赌,你的要求来得太早了。试着拖延更多。没有上下文很难提供帮助。使用旧的 BitBblt 截取的屏幕截图不会闪烁,并且消耗的资源更少,但是当窗口只是“最小化”或“恢复”时会给出一些有趣的结果
-
@manuell:我尝试过延迟通话无济于事。无论如何,在循环中从测试工具调用屏幕截图函数会导致闪烁,即使在不切换窗口时也是如此。
-
你为什么不只是 BitBlt?
标签: c++ windows winapi screenshot