winapi – GetWindowRect返回包含“不可见”边框的大小

我正在开发一个以网格样式在屏幕上定位窗口的应用程序.在Windows 10上运行时,窗口之间存在巨大差距.进一步调查显示,GetWindowRect返回了意外的值,包括一个不可见的边框,但我不能让它返回带有可见边框的实际值.

1)This thread表明这是设计的,您可以通过链接winver = 6来“修复”它.我的环境不允许这样但我已经尝试将PE MajorOperatingSystemVersion和MajorSubsystemVersion更改为6而没有任何影响

2)同一个线程还建议使用带有DWMWA_EXTENDED_FRAME_BOUNDS的DwmGetWindowAttribute从DWM获取真实坐标,这有效,但意味着改变获取窗口坐标的所有位置.它也不允许设置值,让我们反转过程以便能够设置窗口大小.

3)This question表明在此过程中缺乏DPI意识.既不在清单中设置DPI感知标志,也不调用SetProcessDpiAwareness有任何结果.

4)一时兴起,我还尝试添加Windows Vista,7,8,8.1和10兼容性标志,并且Windows主题清单没有任何变化.

Screenshot of a "fullscreen" window with gaps all round
这个窗口移动到0x0,1280×1024,据说可以填满整个屏幕,当查询坐标时,我们得到相同的值.
然而,窗口实际上是14像素更窄,考虑到旧版Windows的边框.

我怎样才能说服Windows让我使用真实的窗口坐标?

最佳答案
Windows 10在左侧,右侧和底部具有薄的不可见边框,用于抓住鼠标以进行大小调整.边框可能如下所示:7,0,7,7(左,上,右,下)

当您调用SetWindowPos将窗口放在此坐标时:
0,0,1280,1024

窗口将选择那些精确的坐标,GetWindowRect将返回相同的坐标.但在视觉上,窗口似乎在这里:
7,0,1273,1017

你可以骗过窗户告诉它去这里:
-7,0,1287,1031

为此,我们获得Windows 10边框厚度:

RECT rect, frame;
GetWindowRect(hwnd, &rect);
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame, sizeof(RECT));

//rect should be `0, 0, 1280, 1024`
//frame should be `7, 0, 1273, 1017`

RECT border;
border.left = frame.left - rect.left;
border.top = frame.top - rect.top;
border.right = rect.right - frame.right;
border.bottom = rect.bottom - frame.bottom;

//border should be `7, 0, 7, 7`

然后像这样偏移矩形:

rect.left -= border.left;
rect.top -= border.top;
rect.right += border.left + border.right;
rect.bottom += border.top + border.bottom;

//new rect should be `-7, 0, 1287, 1031`

除非有更简单的解决方案!

转载注明原文:winapi – GetWindowRect返回包含“不可见”边框的大小 - 代码日志