I've got a WinForms application that works great on older systems, but I'm having trouble making it look good on 4k monitors. There are multiple issues, and a lot written on the subject, but this question is focused on one specific problem. I can set different controls to use the same font, but on high DPI systems, the controls will look a lot different. How can I fix this?
Obviously I can change the font size, move controls around, etc. But Windows is adding a mysterious factor into my font sizes. Without knowing what Windows is doing, it's hard for me to undo it!
On an older system my test window looks perfect:
On a high DPI system, some controls have a different font size than others:
I've tried several things, including manually setting the font on some controls rather than inheriting from the form. As you can see, changing the font did not fix the problem:
After searching the Internet I've tried several things to fix this including:
- Changing the application between PROCESS_DPI_UNAWARE, PROCESS_SYSTEM_DPI_AWARE, and PROCESS_PER_MONITOR_DPI_AWARE
- Explicitly changing the font rather than using the form's font.
- Building on an old system vs building on a high DPI system.
- Building on a monitor set to 96 DPI / 100% vs building on a monitor set to 192 DPI / 200% on the same computer.
- Building the form in visual studio's designer vs building it in pure C# code.
- .Net 4.0 vs. .Net 4.6.1
- Visual Studio 2010 vs Visual Studio 2015
I only found one thing that fixed my problem. Unfortunately I had to do it on the target machine, not on the machine where I'm building this. So it's not a practical solution. See the second item under "steps to repeat" for more details.
Steps to repeat:
- This happens with a lot of controls on a lot of forms. See the code sample below for a small, simple demo. That's how I got the screenshots, above.
I can make this problem appear or disappear with one system setting. If you change the main monitor to 96 DPI / 100% scaling, then reboot, you'll get the good result where all fonts are as requested. If you change the main monitor to a different DPI setting, then reboot, you'll see the bad results.
private void newFormButton_Click(object sender, EventArgs e) { Font copyOfFont = new Font(Font, FontStyle.Strikeout); Form form = new Form(); form.Font = Font; string sample = "Abc 123 :)"; int padding = 6; Label label = new Label(); label.Text = sample; label.Top = padding; label.Left = padding; label.Font = copyOfFont; label.Parent = form; Button button = new Button(); button.Text = sample; button.Top = label.Bottom + padding; button.Left = padding; button.Width = label.Width + padding * 2; button.Height = label.Height + padding * 2; button.Parent = form; TextBox textBox = new TextBox(); textBox.Text = sample; textBox.Size = button.Size; textBox.Top = button.Bottom + padding; textBox.Left = padding; textBox.Parent = form; ListBox listBox = new ListBox(); listBox.Items.Add(sample); listBox.Items.Add(sample); listBox.Width = button.Width; listBox.Height = button.Height * 2; listBox.Top = textBox.Bottom + padding; listBox.Left = padding; listBox.Font = copyOfFont; listBox.Parent = form; form.Show(); }