问题描述
- 请参阅WebRTC desktop_capture,我已经能够成功且准确地捕获非最大化的窗口图像,但是在win10上捕获最大化的窗口时遇到了问题:无论使用BitBlt还是Printwindow,结果的边界黑色几个像素。
- 我对其进行了分析,根本原因是,当我最大化它时,我不知道如何获取与GetwindowDC上的可视窗口矩形相对应的区域。测试发现,GetwindowRect和DwmGetwindowAttribute(... DWMWA_EXTENDED_FRAME_BOUND),GetCroppedWindowRect获得的相对位置不正确。
解决方法
无论使用BitBlt还是PrintWindow,结果的边界都有几个黑色像素。
在Windows Vista和更高版本中,“窗口矩形”现在包括该区域 被阴影占据。
调用GetWindowRect将具有不同的行为,具体取决于 窗口是否曾经显示过。如果窗口还没有 如前所示,GetWindowRect将不包括放置区域 阴影。
要获取不包含阴影的窗口边界,请使用 DwmGetWindowAttribute,指定DWMWA_EXTENDED_FRAME_BOUNDS。注意 与Window Rect不同,DWM Extended Frame Bounds不 针对DPI进行了调整。获取扩展的框架范围只能完成 窗口至少显示一次之后。
测试发现,GetWindowRect和DwmGetWindowAttribute(... DWMWA_EXTENDED_FRAME_BOUND),GetCroppedWindowRect获得的相对位置不正确。
GetCroppedWindowRect
函数实际上是GetWindowRect
的包装。
bool GetCroppedWindowRect(HWND window,bool avoid_cropping_border,DesktopRect* cropped_rect,DesktopRect* original_rect) {
DesktopRect window_rect;
if (!GetWindowRect(window,&window_rect)) {
return false;
}
if (original_rect) {
*original_rect = window_rect;
}
*cropped_rect = window_rect;
bool is_maximized = false;
if (!IsWindowMaximized(window,&is_maximized)) {
return false;
}
DwmGetWindowAttribute()
返回物理坐标,GetWindowRect()
返回逻辑坐标。
Windows Vista引入了物理坐标的概念。桌面 窗口管理器(DWM)可以在以下情况下缩放每英寸(dpi)感知的非点数的窗口 显示器为高dpi。屏幕上看到的窗口对应于 物理坐标。该应用程序继续以逻辑方式工作 空间。因此,应用程序的窗口视图是不同的 从屏幕上显示的内容开始。 对于缩放窗口,逻辑和 物理坐标不同。