On the difficulty of getting pixel-perfect layout in Win32 dialog templates
A customer was having trouble getting their dialog box template to produce exactly what they wanted.
Our designer has specified the UI design in pixels. When we created a dialog box using DLU units in the .rc file, we are not able to get the same dimensions which the designer has specified. We have tried various combinations of dialog font face / size but have not been to figure out a combination which does not have rounding off errors. Also, if we use small font sizes, the aspect ratio of UI elements changes at higher DPIs.
How can we create this UI to the exact pixel sizes using Win32 dialog templates? Is there a font face / font size combination which will give a 1 DLU = 1 pixel mapping?
Dialog boxes are not intended for pixel-perfect layout. They are designed to scale with the font and the user’s display settings. For example, the user may be on a high-DPI system, or simply may prefer that the text be larger (so that, y’know, they can see it), and dialog boxes will scale to accommodate those changes.
It is also the case that fonts do not scale linearly with point size. Smaller fonts tend to be wider to compensate for the reduced height.
Specifying that a button be exactly 50 pixels tall ignores various aspects of reality, such as the fact that a 50-pixel-tall button will be unusable on a 300-DPI display.
DLUs are defined as one eighth of the height of the average font character and one quarter of the width. These values may not be exact multiples of eight and four, so you will experience rounding.¹ Furthermore, you cannot predict exactly how many pixels tall your font will be on the user’s display, because you cannot predict what kind of display the user will use. (Assuming you are coding for a general audience and not a dedicated system, of course.) And the font you request may not even be the font you get, due to font substitution or font linking.
You have a few options.
- Talk with your designer about the realities of modern display technology and work to get a design that can be implemented using dialog templates.
- Switch to another technology that allows greater control than dialog templates. For example, units in WPF can be expressed in “device independent pixels” which are defined to be 1/96 inch.
- Fall back to calculating positions yourself and using
CreateWindowto put the controls exactly where you need them. You will probably want to invent your own template language for this instead of hard-coding the layout for every one of your dialogs.
¹ I guess you could get a font where 1 DLU = 1 pixel by creating a font where the average character height is 8 pixels and the average character width is 4 pixels. On the other hand, your designer is unlikely to be happy with such a font!