如何准确捕获最大化的window?

How to capture a maximized window accurately?

无论使用BitBlt还是PrintWindow,结果的边界都有几个像素点变黑

GetWindowRect:

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.

参考:PhysicalToLogicalPoint