如何让我的 OwnerDrawn UserControl 尊重用户 dpi (96/120/xxx) 和/或字体大小(正常、大、特大)?
有些人建议在 Graphics 对象上使用 DpiX 和 DpiY 属性,但这似乎与我的控制无关(即,无论我选择哪种字体大小或 dpi,它们总是设置为 96)。
StackOverflow 上还有另一个类似的问题,它建议使用 AutoScale 属性,但建议的解决方案也没有真正做任何事情。
除了依赖 WPF 之外,在 .NET 中没有办法做到这一点吗?
如何让我的 OwnerDrawn UserControl 尊重用户 dpi (96/120/xxx) 和/或字体大小(正常、大、特大)?
有些人建议在 Graphics 对象上使用 DpiX 和 DpiY 属性,但这似乎与我的控制无关(即,无论我选择哪种字体大小或 dpi,它们总是设置为 96)。
StackOverflow 上还有另一个类似的问题,它建议使用 AutoScale 属性,但建议的解决方案也没有真正做任何事情。
除了依赖 WPF 之外,在 .NET 中没有办法做到这一点吗?
您需要将 UserControl 的 AutoScaleMode 属性设置为 AutoScaleMode.Dpi,而不是将 AutoScale 属性设置为 true。如果这样做,它会将 AutoScaleMode 重置为 None。AutoScale 属性已过时,仅用于向后兼容(请参阅此MSDN 文章中的重要说明)。
此外,在 Windows Vista/7 中,除非您明确指定您的应用程序支持 DPI,否则 Windows 将模拟默认 DPI 环境,以便您的应用程序以 96 DPI 呈现,然后将生成的位图缩放到适当的大小。为避免这种情况,您可以更改应用程序清单以通知 Windows 您实际上可以识别 DPI - 请参阅本文中的使用清单声明 DPI 感知部分。
我有同样的问题,我尝试使用 GetDC + GetDeviceCaps + ReleaseDC,除了使用图形工作,至少在 Vista32 上。我还没有使用 DPI 的经验,但是没有人回答这个问题,至少这可能对其他人有帮助。
查看创建 DPI 感知应用程序。这提到了为什么无论实际 DPI 设置如何,它都可能总是返回 96。
从上面的链接引用:
Win32 应用程序中的 DPI 缩放
在 Win32 应用程序中,执行以下操作:
- 使用 SetProcessDPIAware 函数取消 dpi 缩放。
- 在调整绘制的界面元素的大小时,请使用物理测量值,例如厘米。通过使用物理尺寸而不是像素,您可以确保所有类型显示器的尺寸一致。
- 要获取系统 dpi 设置,请使用带有 LOGPIXELSX 标志的 CDC::GetDeviceCaps 函数。如果不取消 dpi 缩放,此调用将返回默认值 96 dpi。
- 使用 GetSystemMetrics 函数获取用户界面元素的首选大小,例如窗口边框。禁用 dpi 缩放时,为界面元素返回的测量值将缩放到选定的 dpi 设置。如果 dpi 缩放处于活动状态,该函数将返回基于 96 dpi 的测量值,而不管系统 dpi 设置如何。
来自:关于 DPI 问题
使用-statement重写的示例代码(原始来源):
float dpiX = 96, dpiY = 96;
using(Graphics graphics = this.CreateGraphics())
{
dpiX = graphics.DpiX;
dpiY = graphics.DpiY;
}