11

The Situation

We are selling a Windows Forms Application to customers all over the world. We installed it in several countries in Europe and America. No problems. Last week we installed our software in South-Korea and recognized a strange behaviour...

The problem occurs only on the customers office PCs, but on all of them. Some have Windows 7 Professional K, some have Windows XP.

The customer bought a new PC with an installed Windows 7 Ultimate. On this PC, there is no problem.

The Function

All elements in our application are derived from a "parent-user-control" that offers special functions. One of these functions is "autosizing and positioning". When the parent changes size, this function of all childs is called.

When our application starts, we store the "ClientSize":

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

Whenever the size of the application changes, we calculate the scaling factor and raise an event with it:

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);
}

Now, each child that subscribed, performs automatic resizing and positioning:

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));
    }

The Problem

When our application starts on the customers PCs in South-Korea, the width is about 20% to small. That means, on the right side is an area where is just a grey background. The height is about 10% to high. That means, the items located on the bottom of our application are outside the screen. enter image description here

The Fix

First, we thought the problem comes from the Windows DPI setting. When I set my Laptop to 125%, it looked similar. But, the customers PCs are all set to 100%...

Then, we thought about the screen resolution. All have different ones, some the same as my Laptop...

All have different grafic adapters...

All have .NET 4.5.1...

The only way, that solved the problem, was a strange one:

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);

In the "Designer" file, manually changing the ClientSize from (1016, 734) to about (900, 800). This made it look good on most customer PCs. But not on all.

The Question

What can be the real solution for this problem? Where can it come from?

d.wing
  • 263
  • 1
  • 2
  • 9
  • 2
    +1 for a great question. Unfortunately I do not have an answer for you. – Søren Lorentzen Nov 14 '14 at 07:50
  • This might be worth a look (UI truncation issue with Korean localization): http://stackoverflow.com/a/4458145/96089 – Steven Richards Nov 14 '14 at 08:23
  • @Steven, thank you for the link. As I tried to modify the Windows DPI without result, I thought it's not a DPI problem. When I set the new PC, which has a Windows 7 Ultimate installed, to Korean(Windows, keyboard, localisation), the problem doesn't appear. Finally, I can't reproduce the problem here at my working place (in germany). It only appears on the customers PCs in Korea(where it's 7 p.m. now). – d.wing Nov 14 '14 at 09:54
  • Programmers get themselves into dpiAware problems in very hard to diagnose ways. You need to keep in mind that XP supported a crappy trick, you could increase the size of the system font *without* changing the DPI setting. Very popular in East Asia, reading the intricate glyphs on lowres screens isn't very easy. You cannot repro this on your dev machine, this trick was discontinued. The rough diagnostic is that you are helping too much, Winforms already compensates for the increased system font size, you are doing it again. – Hans Passant Nov 16 '14 at 11:16
  • @HansPassant Thank You hans, You are right! There is no need for the build-in scaling as we are doing it in our parent-user-control. – d.wing Nov 19 '14 at 18:41
  • Well, that's of course doing it the wrong way around. – Hans Passant Nov 19 '14 at 18:45

1 Answers1

3

Do you have the same issues on the same computers if you use AutoScaleMode.Dpi or AutoScaleMode.None instead of AutoScaleMode.Font on each containing control?

If that solves your problem, here is why I think your issue may be related to using AutoScaleMode.Font

At a high level, according to MSDN, the effect of AutoScaleMode.Font is that the control will "scale relative to the dimensions of the font the classes are using, which is typically the system font." (Emphasis mine.)

I dug into the System.Windows.Forms.ContainerControl source code a bit. The method PerformAutoScale is automatically called during a control's OnLayout event. If AutoScaleMode is set to Font, then GetFontAutoScaleDimensions is called indirectly by OnLayout. The comments in GetFontAutoScaleDimensions explain howAutoScaleMode.Font is implemented:

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

So, the method takes a "long" string, sends it out to GDI and asks, "what are the dimensions of this string?" Notably, this method takes into consideration the control's font "which is typically the system font."

Did you know that the Korean alphabet (Hangul) is not represented in Arial? (I didn't until I researched this answer!) It makes perfect sense that your system font (something like Tahoe or Arial) is different than that of your clients in South Korea. It also makes sense that two different fonts will display the same string of characters with a different height and width. So, I bet the issues in question occur on workstations with a system font different than your system font.

So, if you do some testing and find that AutoScaleMode.Font really is the culprit, then you have a few options:

  1. Don't use AutoScaleMode.Font.

  2. Explicitly set the font of all containing controls explicitly. This will ensure that the font of the ContainerControl does not default to the computer's system font.

No matter what you do, ensure all of your containers use the same AutoScaleMode setting. Mixing and matching will lead to headaches.

Good Luck!

Community
  • 1
  • 1
Mike
  • 3,641
  • 3
  • 29
  • 39
  • 1
    Thank You for Your detailed research and answer. I modified all 'AutoScaleMode.Font' in our software to 'AutoScaleMode.None' and could not recognize any negative visual effects. So the next step will be the testing in South-Korea. As I have to wait for a timeframe, where the customers production allows testing, it will probably take some days until I know if it works. I will tell You as soon as I know it. – d.wing Nov 17 '14 at 19:39
  • 2
    OK, I just tested it online in South-Korea, and it worked perfect!! Thanks a lot!! – d.wing Nov 18 '14 at 05:55