GetWindowRect返回包括“不可见"大小的大小.边界 [英] GetWindowRect returns a size including "invisible" borders

查看:227
本文介绍了GetWindowRect返回包括“不可见"大小的大小.边界的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,该应用程序以网格样式将屏幕上的窗口放置在屏幕上.在Windows 10上运行此命令时,两个窗口之间存在巨大差距.进一步的调查表明,GetWindowRect返回的是意外值,包括不可见的边框,但是我无法让它返回带有可见边框的真实值.

I'm working on an app that positions windows on the screen in a grid style. When Running this on Windows 10, there is a huge gap between the windows. Further investigation shows that GetWindowRect is returning unexpected values, including an invisible border, but I can't get it to return the real values with the visible border.

1)MajorOperatingSystemVersion和MajorSubsystemVersion更改为6而没有任何影响

1) This thread suggests this is by design and you can "fix" it by linking with winver=6. My environment does not allow this but I've tried changing the PE MajorOperatingSystemVersion and MajorSubsystemVersion to 6 with no affect

2)该线程还建议将DwmGetWindowAttributeDWMWA_EXTENDED_FRAME_BOUNDS结合使用,以从DWM获取实际坐标,这是可行的,但意味着更改获取窗口坐标的所有位置.它还不允许设置该值,这使我们可以逆转过程以能够设置窗口大小.

2) That same thread also suggests using DwmGetWindowAttribute with DWMWA_EXTENDED_FRAME_BOUNDS to get the real coordinates from DWM, which works, but means changing everywhere that gets the window coordinates. It also doesn't allow the value to be set, leaving us to reverse the process to be able to set the window size.

3)此问题表明在此过程中缺乏DPI意识.在清单中设置DPI感知标志或调用SetProcessDpiAwareness都没有任何结果.

3) This question suggests it's lack of the DPI awareness in the process. Neither setting the DPI awareness flag in the manifest, or calling SetProcessDpiAwareness had any result.

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

4) On a whim, I've also tried adding the Windows Vista, 7, 8, 8.1 and 10 compatibility flags, and the Windows themes manifest with no change.

该窗口将移动到0x0、1280x1024,以填补整个屏幕,并且在向后查询坐标时,我们获得相同的值. 但是,考虑到旧版Windows的边框,该窗口实际上要窄14个像素.

This window is moved to 0x0, 1280x1024, supposedly to fill the entire screen, and when querying the coordinates back, we get the same values. The window however is actually 14 pixels narrower, to take into account the border on older versions of Windows.

如何说服Windows让我使用真实的窗口坐标?

How can I convince Windows to let me work with the real window coordinates?

推荐答案

Windows 10在左侧,右侧和底部具有细小的不可见边框,用于握住鼠标以调整大小.边框可能看起来像这样:7,0,7,7(左,上,右,下)

Windows 10 has thin invisible borders on left, right, and bottom, it is used to grip the mouse for resizing. The borders might look like this: 7,0,7,7 (left, top, right, bottom)

当您调用SetWindowPos将窗口置于此坐标处时:
0, 0, 1280, 1024

When you call SetWindowPos to put the window at this coordinates:
0, 0, 1280, 1024

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

The window will pick those exact coordinates, and GetWindowRect will return the same coordinates. But visually, the window appears to be here:
7, 0, 1273, 1017

您可以欺骗窗口并告诉它去这里:
-7, 0, 1287, 1031

You can fool the window and tell it to go here instead:
-7, 0, 1287, 1031

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

To do that, we get Windows 10 border thickness:

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`

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

Unless there is a simpler solution!

这篇关于GetWindowRect返回包括“不可见"大小的大小.边界的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆