c# - 韩国 PC 上的错误缩放

标签 c# winforms

情况

我们正在向世界各地的客户销售 Windows 窗体应用程序。 我们在欧洲和美国的几个国家安装了它。没问题。 上周我们在韩国安装了我们的软件并发现了一个奇怪的行为......

问题只出现在客户的办公室 PC 上,但在所有这些 PC 上都出现。 有些安装的是 Windows 7 Professional K,有些安装的是 Windows XP。

客户购买了一台安装了 Windows 7 旗舰版的新 PC。 在这台电脑上,没有问题。

函数

我们应用程序中的所有元素都派生自提供特殊功能的“父用户控件”。 其中一项功能是“自动调整大小和定位”。 当父级改变尺寸时,调用所有子级的这个函数。

当我们的应用程序启动时,我们存储“ClientSize”:

InitializeComponent();
this.m_actSize = this.ClientSize;

每当应用程序的大小发生变化时,我们都会计算比例因子并引发一个事件:

void myFormSizeChanged(object sender, EventArgs e)
{
    this.m_xFactor = (float)this.ClientSize.Width / (float)this.m_actSize.Width;
    this.m_yFactor = (float)this.ClientSize.Height / (float)this.m_actSize.Height;
    if (this.m_MyOnResize != null)
        this.m_MyOnResize(this.m_xFactor, this.m_yFactor);
}

现在,每个订阅的 child 执行自动调整大小和定位:

void MyParentUserControl_MyOnResize(float v_xFactor, float v_yFactor)

    {
        this.Location = new Point((int)(this.m_actLocation.X * v_xFactor), (int)(this.m_actLocation.Y * v_yFactor));
        this.Size = new Size((int)(this.m_actSize.Width * v_xFactor), (int)(this.m_actSize.Height * v_yFactor));
    }

问题

当我们的应用程序在韩国客户的 PC 上启动时,宽度大约缩小了 20%。 这意味着,右侧是一个只有灰色背景的区域。 高度大约是10%到高。 这意味着,位于我们应用程序底部的项目在屏幕之外。 enter image description here

修复

首先,我们认为问题出在 Windows DPI 设置上。 当我将笔记本电脑设置为 125% 时,它看起来很相似。 但是,客户的 PC 都设置为 100%...

然后,我们考虑了屏幕分辨率。 都有不同的,有些和我的笔记本电脑一样...

都有不同的图形适配器...

都有 .NET 4.5.1...

解决问题的唯一方法是一个奇怪的方法:

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.ScrollBar;
this.ClientSize = new System.Drawing.Size(1016, 734);

在“Designer”文件中,手动将 ClientSize 从 (1016, 734) 更改为大约 (900, 800)。 这使得它在大多数客户 PC 上看起来不错。但并非全部。

问题

这个问题的真正解决方案是什么? 它从哪里来?

最佳答案

如果您使用 AutoScaleMode.DpiAutoScaleMode.None 而不是 AutoScaleMode.Font,您是否在同一台计算机上遇到相同的问题每个包含控件?

如果这解决了您的问题,这就是我认为您的问题可能与使用 AutoScaleMode.Font

有关的原因

在高层次上,according to MSDNAutoScaleMode.Font 的效果是控件将“根据类使用的字体尺寸进行缩放,通常是系统字体”。 (强调我的。)

我深入研究了 System.Windows.Forms.ContainerControl源代码一点。方法 PerformAutoScaleautomatically called在控件的 OnLayout 事件期间。如果 AutoScaleMode 设置为 Font,则 GetFontAutoScaleDimensions 将由 OnLayout 间接调用。 comments in GetFontAutoScaleDimensions解释AutoScaleMode.Font是如何实现的:

// We clone the Windows scaling function here as closely as
// possible.  They use textmetric for height, and textmetric
// for width of fixed width fonts.  For variable width fonts
// they use GetTextExtentPoint32 and pass in a long a-Z string.
// We must do the same here if our dialogs are to scale in a
// similar fashion.

因此,该方法接受一个“长”字符串,将其发送到 GDI 并询问“这个字符串的维度是多少?”值得注意的是,此方法考虑了控件的字体“通常是系统字体。”

你知道韩文字母表(韩文)is not represented in Arial ? (直到我研究了这个答案,我才知道!)您的系统字体(如 Tahoe 或 Arial)与您在韩国的客户的不同是完全有道理的。两种不同的字体将以不同的高度和宽度显示相同的字符串也是有道理的。因此,我敢打赌,所讨论的问题会出现在系统字体与您的系统字体不同的工作站上。

因此,如果您进行一些测试并发现 AutoScaleMode.Font 确实是罪魁祸首,那么您有几个选择:

  1. 不要使用 AutoScaleMode.Font

  2. 显式设置所有包含控件的字体 明确地。这将确保 ContainerControl 的字体 不默认为计算机的系统字体。

不管你做什么,确保你所有的容器use the same AutoScaleMode环境。混合搭配会让人头疼。

祝你好运!

关于c# - 韩国 PC 上的错误缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26925051/

相关文章:

c# - 在wpf中设置画笔的颜色级别

c# - 如何定义接口(interface)的索引器行为?

sql-server - SQL存储过程和错误处理

c# - 从 C# 控制相机设备

c# - 无法通过c#.net下载exe文件

具有返回多个接口(interface)实现的方法的 C# 接口(interface)

c# - Webrequest 不适用于带 SSL 的 IIS8

.net - WinForms:更改 TableLayoutPanel 中行数的正确方法

c# - 取消订阅事件

c# - 如何更改 WinForms 上下文菜单上复选标记或 'more' 箭头的颜色?