如何准确捕获最大化的window?
How to capture a maximized window accurately?
- 参考WebRTC desktop_capture,我已经能够成功准确的抓取非最大化window图像,但是我在win10上抓取最大化windows时遇到问题:是否使用BitBlt or PrintWindow, 结果的边界有几个像素黑色。
- 我分析了一下,根本原因是我在最大化的时候不知道怎么在GetWindowDC上得到可视window矩形对应的区域。测试发现GetWindowRect和DwmGetWindowAttribute(...DWMWA_EXTENDED_FRAME_BOUND),GetCroppedWindowRect获取的相对位置不正确
无论使用BitBlt还是PrintWindow,结果的边界都有几个像素点变黑
In Windows Vista and later, the Window Rect now includes the area
occupied by the drop shadow.
Calling GetWindowRect will have different behavior depending on
whether the window has ever been shown or not. If the window has not
been shown before, GetWindowRect will not include the area of the drop
shadow.
To get the window bounds excluding the drop shadow, use
DwmGetWindowAttribute, specifying DWMWA_EXTENDED_FRAME_BOUNDS. Note
that unlike the Window Rect, the DWM Extended Frame Bounds are not
adjusted for DPI. Getting the extended frame bounds can only be done
after the window has been shown at least once.
测试发现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()
returns物理坐标,GetWindowRect()
returns逻辑坐标。
Windows Vista introduces the concept of physical coordinates. Desktop
Window Manager (DWM) scales non-dots per inch (dpi) aware windows when
the display is high dpi. The window seen on the screen corresponds to
the physical coordinates. The application continues to work in logical
space. Therefore, the application's view of the window is different
from that which appears on the screen. For scaled windows, logical and
physical coordinates are different.
- 参考WebRTC desktop_capture,我已经能够成功准确的抓取非最大化window图像,但是我在win10上抓取最大化windows时遇到问题:是否使用BitBlt or PrintWindow, 结果的边界有几个像素黑色。
- 我分析了一下,根本原因是我在最大化的时候不知道怎么在GetWindowDC上得到可视window矩形对应的区域。测试发现GetWindowRect和DwmGetWindowAttribute(...DWMWA_EXTENDED_FRAME_BOUND),GetCroppedWindowRect获取的相对位置不正确
无论使用BitBlt还是PrintWindow,结果的边界都有几个像素点变黑
In Windows Vista and later, the Window Rect now includes the area occupied by the drop shadow.
Calling GetWindowRect will have different behavior depending on whether the window has ever been shown or not. If the window has not been shown before, GetWindowRect will not include the area of the drop shadow.
To get the window bounds excluding the drop shadow, use DwmGetWindowAttribute, specifying DWMWA_EXTENDED_FRAME_BOUNDS. Note that unlike the Window Rect, the DWM Extended Frame Bounds are not adjusted for DPI. Getting the extended frame bounds can only be done after the window has been shown at least once.
测试发现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()
returns物理坐标,GetWindowRect()
returns逻辑坐标。
Windows Vista introduces the concept of physical coordinates. Desktop Window Manager (DWM) scales non-dots per inch (dpi) aware windows when the display is high dpi. The window seen on the screen corresponds to the physical coordinates. The application continues to work in logical space. Therefore, the application's view of the window is different from that which appears on the screen. For scaled windows, logical and physical coordinates are different.