C# 缩放 UserControl 内容以匹配用户 Dpi/字体大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/572820/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Scaling UserControl content to match users Dpi/Font Size
提问by
How do I get my OwnerDrawn UserControl to respect the users dpi (96/120/xxx) and/or font-size (normal, large, extra large)?
如何让我的 OwnerDrawn UserControl 尊重用户 dpi (96/120/xxx) 和/或字体大小(正常、大、特大)?
Some people suggest to use the DpiX and DpiY properties on a Graphics object, but that doesn't seem to to anything in my control (i.e. they are always set to 96, regardless of which font-size or dpi I choose).
有些人建议在 Graphics 对象上使用 DpiX 和 DpiY 属性,但这似乎对我的控件没有任何影响(即,无论我选择哪种字体大小或 dpi,它们始终设置为 96)。
There is another similar question here on StackOverflow where it suggests to use the AutoScale properties, but the suggested solutions don't really do anything either.
StackOverflow 上还有另一个类似的问题,它建议使用 AutoScale 属性,但建议的解决方案也没有真正做任何事情。
Is there no way of doing this in .NET except for relying on WPF?
除了依赖 WPF 之外,在 .NET 中没有办法做到这一点吗?
回答by CS.
I have the same problem, I tried using GetDC + GetDeviceCaps + ReleaseDC, except using Graphics worked, atleast on Vista32. I am not experienced with DPI yet, but nobody had answered this and at least this might be helpful for others.
我有同样的问题,我尝试使用 GetDC + GetDeviceCaps + ReleaseDC,除了使用 Graphics 工作,至少在 Vista32 上。我对 DPI 还没有经验,但没有人回答过这个问题,至少这可能对其他人有帮助。
Check out Creating a DPI-Aware Application. This mention why it might always return 96 regardless of actual DPI setting.
查看创建 DPI 感知应用程序。这提到了为什么无论实际 DPI 设置如何,它都可能始终返回 96。
Quote from above link:
引用上面的链接:
DPI scaling in a Win32 application
In Win32 applications, do the following:
- Use the SetProcessDPIAware function to cancel dpi scaling.
- When sizing drawn interface elements, use physical measurements, such as centimeters. By using physical dimensions rather than pixels, you ensure consistent sizing on all types of displays.
- To get the system dpi setting, use the CDC::GetDeviceCaps function with the LOGPIXELSX flag. If you do not cancel dpi scaling, this call returns the default value of 96 dpi.
- Use the GetSystemMetrics function to get preferred sizes of user interface elements, such as window borders. When dpi scaling is disabled, the measurement values that are returned for interface elements are scaled to the selected dpi setting. If dpi scaling is active, the function returns measurements based on 96 dpi, regardless of the system dpi setting.
Win32 应用程序中的 DPI 缩放
在 Win32 应用程序中,执行以下操作:
- 使用 SetProcessDPIAware 函数取消 dpi 缩放。
- 在调整绘制的界面元素的大小时,请使用物理测量值,例如厘米。通过使用物理尺寸而不是像素,您可以确保在所有类型的显示器上尺寸一致。
- 要获取系统 dpi 设置,请使用带有 LOGPIXELSX 标志的 CDC::GetDeviceCaps 函数。如果不取消 dpi 缩放,此调用将返回默认值 96 dpi。
- 使用 GetSystemMetrics 函数获取用户界面元素的首选大小,例如窗口边框。禁用 dpi 缩放后,为界面元素返回的测量值将缩放到选定的 dpi 设置。如果 dpi 缩放处于活动状态,则无论系统 dpi 设置如何,该函数都会返回基于 96 dpi 的测量值。
Answered from: About DPI Issue
回答自:关于 DPI 问题
Sample code rewritten with using-statement (original source):
使用-statement重写的示例代码(原始来源):
float dpiX = 96, dpiY = 96;
using(Graphics graphics = this.CreateGraphics())
{
dpiX = graphics.DpiX;
dpiY = graphics.DpiY;
}
回答by Allon Guralnek
You would need to set the AutoScaleMode property of the UserControl to AutoScaleMode.Dpi, and notset the AutoScale property to true. If you do, it will reset the AutoScaleMode back to None. The AutoScale property is obsolete and is there only for backwards compatibility (see the Important Notein this MSDN article).
您需要将 UserControl的 AutoScaleMode 属性设置为 AutoScaleMode.Dpi,而不是将 AutoScale 属性设置为 true。如果这样做,它会将 AutoScaleMode 重置回无。AutoScale 属性已过时,仅用于向后兼容(请参阅此MSDN 文章中的重要说明)。
Also, in Windows Vista/7, unless you explicitly specify that your application is DPI-aware, Windows will emulate a default DPI environment so that your application renders with 96 DPI, then scale the resulting bitmap to the appropriate size. To avoid that, you can alter your application manifest to inform Windows that you are in fact DPI aware - see the Using manifest to declare DPI awarenesssection in this article.
此外,在 Windows Vista/7 中,除非您明确指定您的应用程序是 DPI 感知的,否则 Windows 将模拟默认的 DPI 环境,以便您的应用程序以 96 DPI 呈现,然后将生成的位图缩放到适当的大小。为了避免这种情况,你可以改变你的应用程序清单,以通知Windows您实际上DPI知道-看到使用清单申报DPI意识在部分这篇文章。