0

我在为 Windows 开发一些软件时遇到了一个问题,这个问题与在屏幕上移动窗口有关。

基本上,我发现特定的窗口将始终不遵循坐标系。我有一个函数,它接受一个窗口和一个比率,然后将窗口放大到它可以的最大尺寸(以该比率)并且仍然在显示器的工作区域内(不超过边缘或任务栏)。

示例 1:函数按预期工作,将窗口(VSCode)的大小设置为 4:3 的最大大小,并将其放在屏幕的角落(使用 SetWindowPos 并为坐标传递 0,0) .

示例 2:完全相同的函数在不同的窗口 (Firefox) 上运行,它再次调整为 4:3 并设置为 0,0。但是,这一次您可以看到窗口并没有完全在角落里,准确地说是相差 8 个像素。如果我使用 api 调用获取窗口位置,它会返回 0,0,即使它显然不是。如果我自己手动将其卡入角落,则返回 -8,0。

我不知道出了什么问题或如何解决它。它总是发生在同一个窗口上,不太确定,但我认为它与窗口的标题栏类型有关。

我见过的唯一一个遇到这个问题的人在这里:https ://answers.microsoft.com/en-us/insider/forum/insider_wintp-insider_desktop/desktop-coordinate-system-is-broken/9e6fd9ab-6d27 -45e0-bb55-4c868cd6ac45

不幸的是,他从来没有得到真正的答案,所以我回到了原点。

那么,有什么想法可以始终如一地将窗户设置在角落里吗?我已经提出了一些 janky 解决方案,例如尝试动态查找窗口从角落偏移多少,但这并不是我真正想要依赖的东西。这只是Windows的一个错误,我被卡住了吗?

谢谢,如果您有任何问题,请告诉我!

4

1 回答 1

2

这是windows系统的设计。

我很久以前就看到过类似的问题。

Windows 10 在左、右和底部有细的不可见边框,用于握住鼠标调整大小。边框可能如下所示:7,0,7,7(左、上、右、下)。

边框在 Windows 10 中是不可见的,因此看起来窗口位于错误的位置。Visual Studio IDE 有自己的工具窗口,当工具窗口停靠时,它不使用边框或自定义NC_PAINT;当它的工具窗口浮动时,它使用默认边框。

一种解决方法:

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`

有关更多信息,请参阅@Barmak Shemirani 的回答

类似情况:

检索没有 Windows 阴影的窗口大小

GetWindowRect 返回一个包含“不可见”边框的大小

注意:DwmGetWindowAttribute()返回物理坐标,但GetWindowRect()返回逻辑坐标。因此,对于缩放到 100% 以外的任何屏幕上的非 DPI 感知应用程序,边框宽度将是错误的。

于 2020-03-16T09:17:26.717 回答