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