韩国电脑上的扩展错误

d.w*_*ing 9 c# winforms

情况

我们正在向全世界的客户销售Windows Forms应用程序.我们在欧洲和美国的几个国家安装了它.没问题.上周我们在韩国安装了我们的软件并认识到了一种奇怪的行为......

问题仅发生在客户办公室PC上,而是发生在所有客户办公室PC上.有些有Windows 7 Professional K,有些有Windows XP.

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

功能

我们的应用程序中的所有元素都源自提供特殊功能的"父级用户控件".其中一个功能是"自动调整和定位".当父级更改大小时,将调用所有子级的此函数.

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

InitializeComponent();
this.m_actSize = this.ClientSize;
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

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));
    }
Run Code Online (Sandbox Code Playgroud)

问题

当我们的应用程序在韩国的客户PC上启动时,宽度约为20%.这意味着,右侧是一个只有灰色背景的区域.高度约为10%至高.这意味着,位于应用程序底部的项目位于屏幕之外. 在此输入图像描述

修复

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

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

所有都有不同的grafic适配器......

都有.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);
Run Code Online (Sandbox Code Playgroud)

在"Designer"文件中,手动将ClientSize从(1016,734)更改为大约(900,800).这使它在大多数客户PC上看起来都很好.但不是全部.

问题

什么可以成为这个问题的真正解决方案?哪里可以来的?

Mik*_*ike 3

如果您在每个包含的控件上使用AutoScaleMode.Dpi或 ,AutoScaleMode.None那么在同一台计算机上是否会遇到相同的问题AutoScaleMode.Font

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

根据 MSDN 的说法,从较高的层面来看,该控件的效果AutoScaleMode.Font是“相对于类正在使用的字体的尺寸进行缩放,该字体通常是系统字体”。(强调我的。)

我深入研究了System.Windows.Forms.ContainerControl一下源代码。该方法在控件事件期间自动PerformAutoScale调用。如果设置为,则由间接调用。GetFontAutoScaleDimensions 中的注释解释了如何实现:OnLayoutAutoScaleModeFontGetFontAutoScaleDimensionsOnLayoutAutoScaleMode.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.
Run Code Online (Sandbox Code Playgroud)

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

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

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

  1. 不要使用AutoScaleMode.Font.

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

无论您做什么,请确保所有容器都使用相同的AutoScaleMode设置。混合和搭配会让人头疼。

祝你好运!

  • 好的,我刚刚在韩国网上测试过,效果非常好!多谢!! (2认同)