While customizing a Button class, I noticed that somehow my customized button doesn’t display the button image in the same size to that when the image is applied to Button class.
Here, I would like to figure out why it happens and how to solve it.
First, let’s see how it looks when it shows the problem.
As you can see, the customized button shows the same image ( 100×42) bigger than the others in Button and PictureBox. I used the same 96 DPI image. After thinking about what could be wrong, I started to suspect the “Make it easier to read what’s on your screen” setting, which is custom DPI setting, in other word. ( Is there MS terminology to refer it? )
In the OnDraw method in my custom Button, I used Image.DrawImage( Image, int, int ) just to apply the native DPI of interested image. So, it is quite clear that this custom DPI behavior is not supported transparently.
Now, let’s look how it looks like in “Smaller” setting.
I set the dimension of “Clear 8” button to 99×42 to display the button image nicely. However, I noticed that other buttons ( with “Ease x” and “Clear x” are on them ) have wrong dimension. This means that the dimension of buttons are changed. So, to confirm that, I changed back to Medium setting to see how if the dimension of “Clear 8” was to be changed. And as seen on the first picture, it is changed to 132×50.
Let’s not forget that this “Clear 8” button is .NET Button class. It’s not my customized button.
Then, MS don’t keep dimension of each widgets and their images matched correctly.
Then as a developer, how can we be sure if our program runs as designed on other people’s computers with different DPI setting?
To make my customized button works like .NET Button, I need to use “current DPI” instead of the native DPI of images. However, it doesn’t solve all the layout problems as with the Button case.
What can be even better is to use MS DPI-aware feature.
Windows 7 supports DPI-aware UI. In Apple’s term, it’s resolution independence. It means DPI is virtualized. What is odd is that the term DPI is more H/W-friendly term. So, it sounds like that H/W DPI is to be changed in that mode. But it’s not. it is like to have a coordinate system scaled. Anyway, here are some documents on DPI-awareness.
- MFC applications now default to being DPI-aware
- DPI-aware applications in Windows Vista and Windows 7
Currently, it turned out that Visual C++ .NET supports DPI-awareness more well than C# .NET project. The property of C++ project has a check box to turn on the mode, while C# project doesn’t. It is weird that MS somehow introduced this feature to C++ earlier than C#. Many features available to C# were not introduced to C++ yet, or even though they did, they have been usually later than C#.
Anyway, there are still some problems. DPI-awareness is not fully transparent to application programmers. For example, laying out is not really proportionally done perfectly yet. It is far from being perfect. The scale ratio of widgets and images are different. So, depending on situation you are on, you could need to draw and position images and widgets themselves manually.
Overall, it looks like that MS is still trying hard to bring this feature more completely to MS Windows.
However, who pay attention to MS Windows nowadays? I strongly feel and know that less and less people are interested in Windows.