gdiScaling:使用 GDI 绘制线条的问题

问题描述 投票:0回答:1

我在清单中启用了“gdiScaling”选项,以在我的 MFC C++ 应用程序上启用增强的 GDI 缩放功能。

然而,我在使用 MoveTo/LineTo 绘制线条时遇到了一些问题:绘制一个简单的矩形在边缘上有一些“小故障”,这些“故障”不再匹配,就像由于缩放而导致的像素相差一个像素。

有人有过这样的经历吗?如何修复它? (除了更改 API,例如 Rectangle())

PS:按照https://blogs.windows.com/windowsdeveloper/2017/05/19/improving-high-dpi-experience-gdi-based-desktop-apps/

中所述启用gdiScalign
SelectObject(hdc, CreatePen(PS_SOLID, 1, 0));

int x1 = 100;
int y1 = 100;
int x2 = 199;
int y2 = 199;
int ofs = 1;  // LineTo does not include last pixel!

MoveToEx(hdc, x1, y1, nullptr);
LineTo(hdc, x2 + ofs, y1);

MoveToEx(hdc, x1, y1, nullptr);
LineTo(hdc, x1, y2 + ofs);

MoveToEx(hdc, x2, y1, nullptr);
LineTo(hdc, x2, y2 + ofs);

MoveToEx(hdc, x1, y2, nullptr);
LineTo(hdc, x2 + ofs, y2);

wrong rectangle

c++ winapi gdi dpi
1个回答
0
投票

忘记我在之前的回答中建议的明显内容。

思考 Windows 如何处理其绘图 API 中的“1 过去”事物以及其意图,以便开发人员不必明确考虑它。我的假设是,如果您编写代码来显式地让每个“MoveTo”坐标显式地拾取在后续行中绘制的位置,那么它就会变得容易得多:

所以代替这个:

MoveToEx(hdc, x1, y1, nullptr);
LineTo(hdc, x2 + ofs, y1);

MoveToEx(hdc, x1, y1, nullptr);
LineTo(hdc, x1, y2 + ofs);

MoveToEx(hdc, x2, y1, nullptr);
LineTo(hdc, x2, y2 + ofs);

MoveToEx(hdc, x1, y2, nullptr);
LineTo(hdc, x2 + ofs, y2);

这个:

int x1 = 100;
int y1 = 100;
int x2 = 200;
int y2 = 200;


MoveToEx(hdc, x1, y1, nullptr);
LineTo(hdc, x2, y1);

MoveToEx(hdc, x2, y1, nullptr);
LineTo(hdc, x2, y2);

MoveToEx(hdc, x2, y2, nullptr);
LineTo(hdc, x1, y2);

MoveToEx(hdc, x1, y2, nullptr);
LineTo(hdc, x1, y1);

这可能是一个正确的假设。这是最终结果:

enter image description here

现在,从技术上讲,这可能会使盒子比您预期的“宽和高 1 像素”。如果是这种情况,请将 x2 和 y2 改回 199。

© www.soinside.com 2019 - 2024. All rights reserved.