为什么这个BitBlt示例不再起作用?

piq*_*sel 4 c windows winapi

我现在正在使用Petzold的书(第5版)回到一些Windows编程.我使用BitBlt 编译了以下示例,但它不能正常工作.

它应该复制Window的(CxSource,CySource)大小的图标并在整个窗口的表面上复制它.实际上,使用Windows 7会发生什么,窗口下方的位图会被获取并复制到绘图表面,即hdcClient.

我不明白为什么它表现得像这样知道很明显传递给BitBlt的DC是hdcWindow,它指的是通过当前应用程序的GetWindowDC(hwnd)获得的设备上下文.

我首先想到的是,默认情况下启用了透明度模式,但是停用它不会改变任何东西.BitBlt似乎总是占据应用程序窗口下方的表面!我不明白!:)任何人都知道它为什么这样工作以及如何解决它?

Han*_*ant 7

自添加DWM(桌面窗口管理器,又称Aero)以来,使用BitBlt()制作屏幕截图并没有那么容易.Petzold的示例代码存在一个微妙的计时问题,它很快就会截屏.它是这样做的,而Aero仍然忙于动画框架,将其淡入视图.因此,您可以看到窗口背后的内容,可能已经部分褪色,具体取决于生成第一个WM_PAINT消息的速度.

您可以通过禁用效果轻松修复它:

#include <windows.h>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
Run Code Online (Sandbox Code Playgroud)

在CreateWindow()调用之后:

BOOL disabled = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_TRANSITIONS_FORCEDISABLED, &disabled, sizeof(disabled));
Run Code Online (Sandbox Code Playgroud)

另一个棘手的细节是第一个 BitBlt很重要,DWM之后返回一个缓存的副本,这个副本没有被动画正确地无效.

当您需要属于另一个进程的窗口的屏幕截图时,这会变得更加粗糙.但这在Aero之前已经是一个问题,你必须等待足够长的时间以确保窗口完全涂漆.值得注意的可能是BitBlt()的性能,它必须通过从窗口后缓冲区编写最终图像来明显陷入困境.在SO没有很多问题,没有快乐的答案.