韩国电脑上的扩展错误

时间:2014-11-14 07:32:32

标签: c# winforms

情况

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

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

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

功能

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

当我们的应用程序启动时,我们存储" 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);
}

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

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%......

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

所有人都有不同的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);

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

问题

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

1 个答案:

答案 0 :(得分:2)

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

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

相关

在较高级别according to MSDNAutoScaleMode.Font的效果是控件将相对于类正在使用的字体尺寸进行缩放,通常是系统字体。" (强调我的。)

我稍微挖掘了System.Windows.Forms.ContainerControl源代码。在控件的PerformAutoScale事件期间,方法OnLayoutautomatically called。如果AutoScaleMode设置为Font,则GetFontAutoScaleDimensions间接调用OnLayoutcomments 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并询问,"这个字符串的尺寸是多少?"值得注意的是,这种方法考虑了控件的字体"它通常是系统字体。"

你知道韩文字母(Hangul)is not represented in Arial吗? (直到我研究这个答案,我都没有!)你的系统字体(如Tahoe或Arial)与韩国客户的字体不同,这是完全合理的。同样有意义的是,两种不同的字体将显示具有不同高度和宽度的相同字符串。所以,我敢打赌,有问题的问题发生在系统字体与系统字体不同的工作站上。

所以,如果你做一些测试并发现AutoScaleMode.Font确实是罪魁祸首,那么你有几个选择:

  1. 请勿使用AutoScaleMode.Font

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

  3. 无论您做什么,请确保设置所有容器use the same AutoScaleMode。混合和匹配会导致头痛。

    祝你好运!