On the difficulty of getting pixel-perfect layout in Win32 dialog templates

Date:May 10, 2018 / year-entry #109
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20180510-00/?p=98725
Comments:    19
Summary:That's not what it's for.

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 Create­Window to 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.

Good luck.

¹ 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!


Comments (22)
  1. kantos says:

    I see this in web-dev too… people have the unrealistic notion that all their users are using the exact same monitor as their designer, using the exact same rendering tech, on the exact same OS. This is usually one of the first things I have to work hard to remove from their assumptions.

    1. Peter says:

      I think this goes way beyond visual layouts. It seems that when using pretty much any framework, people will go to ludicrous lengths to pound the framework into submission and make it conform to their existing paradigm. If you find your framework fighting with you, it’s a hint that you might want to adjust your expectations and change your point of view. Alternatively, your framework may be garbage. That happens too. ;)

      1. Simon Farnsworth says:

        In a previous job, we kept the awful LCD long past its use by date to victimise designers who thought that way. If you complain about pixel-perfect colour matching (as in expecting the difference between #FF8899 and #FF8898 to be clear to users), we reserved the right to swap your nice Dell monitor for a 1024×768 LCD with a VGA connector only, 6 bits per channel (18 per pixel) on the panel, and no built in dithering.

        A few days of that monitor were generally all it took to get the designer to realise that depending on customers having perfect screens was a hiding to nothing…

        1. kantos says:

          I find requiring accessibility training helps too. When designers realize they need to design interfaces that have to be dealt with by the colorblind, blind, and sight impaired it tends to help them focus on simpler more easily understood designs that scale.

  2. smf says:

    Another option is getting a designer who can create designs that the technology they are designing for actually supports.

    “Under Construction. We are currently waiting for HTML to catch up with our web designers superior designs. Please check back again soon.”

    1. Alex Cohn says:

      Speaking of HTML. I once developed the whole Windows application UI based on what was known as DHTML dialogs. Some presentation logoc was even in JavaScript. I remember thar it was tricky to work around the discrepancies between Windows XP and Windows 2000 versions of IE.

  3. Lars says:

    You’d think by now designers had heard of “responsive design”…

    1. cheong00 says:

      WinForm design with controls like FlowLayoutPanel is relatively new.

      And some people complains it makes writing manuals difficult (website, especially public ones, seldom need manual. However it’s still common required delivery item for WinForm applications)

      1. kantos says:

        The UI/UX absolutist would say that if you need to write a manual… you’re already doing it wrong. The goal being that your product should be intuitive and discoverable. That said you can always just say “The images in this manual are taken at X resolution, layout may vary”.

      2. Zenith says:

        Well the other issue here is that WinForms is all over the place with sizes and points. Sure, if you’re only using stuff that comes out of the box or slapping some 3rd party control library into your dependency chain, you might not see it as much. But if you’re really trying to customize layouts and make it look like it’s supposed to on all devices, it’s a nightmare. To be fair though, none of the alternatives are nice enough to be called a nightmare.

    2. xtal256 says:

      I hate the term “responsive design”, because it just perpetuates the pixel-perfect mindset but with the addition of screen width breakpoints. UI elements should scale appropriately at any screen resolution and font size.

  4. skSdnW says:

    Recent versions of Windows 10 will scale dialog controls when monitors have different DPI if you are “aware” but it seems to only work for template based dialogs so if you create some of the controls on the fly you are on your own with those. Undocumented behavior AFAIK.

    1. Joshua says:

      It’s documented. It only does the templated controls because it doesn’t know how to do your controls. Handle the message.

    2. florian says:

      By the way, what’s the font that should be used in dialog templates, nowadays?

      The Windows Run dialog for example has:

      FONT 9, “Segoe UI”

      and many other Windows dialogs have:

      FONT 8, “MS Shell Dlg”

      which maps to … something (I don’t recall, by heart).

      I have come across a recommendation to use the former, but the latter is still very common.

      1. Azarien says:

        Since Vista the recommended UI font is Segoe UI size 9. It used to be Tahoma (aka MS Shell Dlg 2) size 8 in XP, and in Windows 9x times it was MS Shell Dlg, which mapped to Microsoft Sans Serif in English and most European versions of Windows.

  5. Adrian says:

    Unfortunately, DLUs can make it hard to line up controls relative to each other.

    For example, if you have a static text label adjacent to an edit control there’s not enough precision in the DLU coordinate system to make the text inside the edit control align vertically with the label, depending on your resolution, font, etc. The label might be a pixel too high or a pixel too low–just enough to make it look like you intended to line them up but missed. (This explains the popularity of putting the labels above the controls.)

    I even saw an example where a tall stack of controls that were evenly spaced (in DLUs) resulted in an uneven appearance, as the rounding error (due to an unusual DPI) would accumulate from row to row until finally it was enough to either push a row down by an extra pixel or to make one of the controls one pixel taller than the rest. We ended up writing code to fix-up the layout at runtime.

    1. florian says:

      I’ve seen that, too. The Visual Studio dialog editor applies a default “inside distance” (just to avoid talking in CSS) of 7 DLUs. The a group of controls has a vertical spacing of 11, you can end up with a lot of odd numbers not divisable by 4 and 8, and irregular spacing in the final layout.

      But the concept of being able to visually design user interfaces is just too great to complain … :)

  6. DLU is a pretty common concept. Since I’m more retro game oriented, how would you properly set up a custom draw control (picturebox or similar) which does have to have a exact pixel representation (scaled only in full factors) ?

    Usually I end up forcing a certain sizing factor for that particular control and try to make it fit in with others on a dialog, but it feels clunky.

    1. Anon says:

      For an owner draw control, just make sure the mapping mode is MM_TEXT. That way you can draw in pixels. Of course you’d need to do all the scaling yourself. But if you’re drawing a graph or a gauge it’s actually pretty easy to do that. Same if you’re just going to Blit a bitmap.

  7. Neil says:

    At least you have a scaled width unit. I can remember trying to define reasonable widths in CSS before `ch` became common.

    1. Joshua says:

      Wait what? em and ex always existed in CSS.

  8. The_Assimilator says:

    I can’t believe someone was stupid enough to file a support case with Microsoft for this, as opposed to punching their designer and/or manager in the face.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index