Windows 在 Windows 10 OS 上形成图形问题
Windows Forms Graphic Issue on Windows 10 OS
当我运行在Windows10中的任何WindowsForms应用程序时,window里面的图形出现变形:
在设计时不会发生这种情况:
有没有人遇到过这种情况?
(请打开图片看得更清楚。)
要解决此问题,您可以使用以下任一选项使您的应用程序具有 DPI 感知能力:
- Application Manifest
- API 呼叫
SetProcessDPIAware
, SetProcessDpiAwareness
or SetProcessDpiAwarenessContext
Important Note: It is recommended that you set the process-default DPI
awareness via application manifest, not an API call.
使用应用程序清单文件
要使应用程序具有 DPI 感知能力,您可以将 应用程序清单文件 添加到您的项目中。然后在app.manifest
文件中,取消注释与DPI-Awareness相关的部分:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
然后在您的 app.config 文件中,添加 EnableWindowsFormsHighDpiAutoResizing
并将其值设置为 true:
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>
有关详细信息,请查看 Microsoft 文档中的以下主题:
- Windows
上的高 DPI 桌面应用程序开发
SetProcessDPIAware
API 调用示例[=41=]
您可以在显示主窗体之前使用 SetProcessDPIAware()
方法来设置您的应用程序 dpi 感知并防止 windows 缩放应用程序。您还应该检查 windows 版本是否大于或等于 vista:
static class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetProcessDPIAware();
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (Environment.OSVersion.Version.Major >= 6)
SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new Form1());
}
}
备注
正如上面已经提到的,建议您通过应用程序清单设置进程默认 DPI 感知,而不是 API 调用。
在使用 API 调用之前,请阅读文档以了解支持的 OS 以及 DLL 在初始化期间缓存 dpi 设置时可能出现的竞争条件。还要记住,DLL 应该接受主机进程的 dpi 设置而不是 API 调用它们自己。
- 您可能会发现此
DpiHelper
class 在 .NET Core 3.0 的 WinForms 中实现很有用。
当我运行在Windows10中的任何WindowsForms应用程序时,window里面的图形出现变形:
在设计时不会发生这种情况:
有没有人遇到过这种情况?
(请打开图片看得更清楚。)
要解决此问题,您可以使用以下任一选项使您的应用程序具有 DPI 感知能力:
- Application Manifest
- API 呼叫
SetProcessDPIAware
,SetProcessDpiAwareness
orSetProcessDpiAwarenessContext
Important Note: It is recommended that you set the process-default DPI awareness via application manifest, not an API call.
使用应用程序清单文件
要使应用程序具有 DPI 感知能力,您可以将 应用程序清单文件 添加到您的项目中。然后在app.manifest
文件中,取消注释与DPI-Awareness相关的部分:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
然后在您的 app.config 文件中,添加 EnableWindowsFormsHighDpiAutoResizing
并将其值设置为 true:
<appSettings>
<add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
</appSettings>
有关详细信息,请查看 Microsoft 文档中的以下主题:
- Windows 上的高 DPI 桌面应用程序开发
SetProcessDPIAware
API 调用示例[=41=]
您可以在显示主窗体之前使用 SetProcessDPIAware()
方法来设置您的应用程序 dpi 感知并防止 windows 缩放应用程序。您还应该检查 windows 版本是否大于或等于 vista:
static class Program
{
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetProcessDPIAware();
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (Environment.OSVersion.Version.Major >= 6)
SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(true);
Application.Run(new Form1());
}
}
备注
正如上面已经提到的,建议您通过应用程序清单设置进程默认 DPI 感知,而不是 API 调用。
在使用 API 调用之前,请阅读文档以了解支持的 OS 以及 DLL 在初始化期间缓存 dpi 设置时可能出现的竞争条件。还要记住,DLL 应该接受主机进程的 dpi 设置而不是 API 调用它们自己。
- 您可能会发现此
DpiHelper
class 在 .NET Core 3.0 的 WinForms 中实现很有用。