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

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

问题描述

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

1) 这个窗口被移动到0x0, 1280x1024,应该是填满整个屏幕,当回查询坐标时,我们得到相同的值.然而,考虑到旧版 Windows 的边框,该窗口实际上窄了 14 个像素.

如何说服 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 应该是`0, 0, 1280, 1024`//帧应该是`7, 0, 1273, 1017`矩形边框;border.left = frame.left - rect.left;border.top = frame.top - rect.top;border.right = rect.right - frame.right;border.bottom = rect.bottom - frame.bottom;//边框应该是`7, 0, 7, 7`

然后像这样偏移矩形:

rect.left -= border.left;rect.top -= border.top;rect.right += border.left + border.right;rect.bottom += border.top + border.bottom;//新的矩形应该是`-7, 0, 1287, 1031`

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

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) 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) 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) 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) 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.

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.

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

解决方案

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)

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

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

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

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`

Then offset the rectangle like so:

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天全站免登陆