坐标错误使用GetWindowRect在不同的DPI

Coordinate Error using GetWindowRect in different DPI

本文关键字:DPI GetWindowRect 错误 坐标      更新时间:2023-10-16

我想在我的MFC程序中捕获组件的坐标。

现在我可以用GetWindowRect完美地完成这个。但是,当我将窗口dpi设置为150% (120 dpi)时,我从GetWindowRect获得不同的坐标。

因此,我研究了一些将新坐标转换为默认dpi (96 dpi)的方法。

最后,我发现有一些错误,当我尝试:

Rect.top = Rect.top * (DEFAULT_DPIY / CURRENT_DPIY);
Rect.left = Rect.left * (DEFAULT_DPIX / CURRENT_DPIX);

转换后的值非常接近,但不相等。

您的程序受制于DPI虚拟化。处理这个问题的正确方法是使你的程序具有高DPI意识,但这可能涉及到比你准备尝试的更多的更改。

如果高DPI感知不是你想解决的问题,那么你至少可以使你的算术更好。你的代码使用整数除法。但这是不准确的。为了尽量减少这种不准确性,你应该在乘法之后执行除法:

Rect.top = (Rect.top * DEFAULT_DPIY) / CURRENT_DPIY;
Rect.left = (Rect.left * DEFAULT_DPIX) / CURRENT_DPIX;

当然,省略括号也不会改变其含义,但我认为在这种情况下明确操作的顺序是很好的。

另一个选项是使用MulDiv:

Rect.top = MulDiv(Rect.top, DEFAULT_DPIY, CURRENT_DPIY);
Rect.left = MulDiv(Rect.left, DEFAULT_DPIX, CURRENT_DPIX);