Re: How do I get my app to look correct at different dpi settings?

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



"Ivar" <Ivar.ekstromer000@xxxxxxxxxxxx> wrote in message news:f5oMl.34678$tb.25787@xxxxxxxxxxxxxxxx

Just my opinion here but :-)
If when ever I start a new project or add a new form the first
thing I do is set it's scalemode to vbPixels, this also applies to
any control that has a scalemode and HDC property. With
what you look at (the screen) you can't get smaller than a pixel
and all graphical APIs work in pixels. Just work with one
scalemode only . . .

Being consistent in ScaleModes does usually make things easier to deal with, but it will not in itself solve the problem of possible control displacement when running your compiled exe on a machine that is set to a different dpi than your development machine. That's because VB always records the design time size of the client area of the Form and the design time size and position of all Controls using twips, regardless of the ScaleModes you happen to be using. It does this both in the .frm files themselves and in the compiled exe file.

At runtime the compiled exe examines those twip values and converts them to pixels in accordance with the dpi setting of the machine on which the exe is currently running. Then it attempts to create a Form of such an overall size that its client area is the pixel size it has just calculated, taking into account the various Form border thicknesses on that specific machine when working out what the overall Width and Height of such a Form needs to be. Then it converts the Left, Top, Width and Height of all controls from the design time twip size to pixels, again in accordance with the dpi setting of the machine on which the exe is currently running. It then places those controls at the calculated pixel size and at the calculated pixel positions.

All this works really well if the Form is fairly small, and it achieves its main aim of "expanding the size of everything" in accordance with the user's dpi setting whilst at the same time maintaining the correct overall look of the Form, without any runtime code being involved. For example, for a fairly small Form, the Form and its contents get displayed on a "large dpi machine" as a correct but magnified version of the same Form as it would have looked on a standard dpi machine, which is in fact the original purpose of the adjustable dpi settings in Windows. If you're using any bitmaps of course and if you are dumping them to the Form or to a Control "as is" then those bitmaps will get displayed at the same pixel size both on the standard dpi machine and on the large dpi machine, so it is usually wise to draw such bitmaps at the desired size in code if that is what suits your application. Fonts are generally okay because they too will be expanded in size to suit the expanded size of the Form and the Controls, although there can be a couple of little problems with font sizes in a few cases because of the constraint of point sizes and individual character widths to be whole pixel values, but that can be easily fixed by simply "allowing a little bit more room" for the various text items.

Anyway, all of the above works fine for fairly small Forms. The problem arises when the Form is fairly large and where the compiled exe cannot create a Form of the required pixel size (the pixel size that was calculated from its design time twip size by reference to the dpi settings of the machine on which the code is currently running). If the Form needs to be a larger pixel size than will physically fit on the screen then VB is restricted to creating a smaller Form than it really want to, so that the smaller Form does fit on the screen. However, both the size and the position of all contained Contols will still be at their full calculated pixel size on that machine and so some of them, particularly those near the right and bottom edges, will either partially or wholly disappear off the Form. It is that specific problem that resizing code needs to address. It is difficult to write general purpose resizing code that will suit all applications because there simply is not an easy "one size fits all" solution and any code must take into account the design decisions of the author of the application, which of course can be different in different circumstances. It's fairly easy to come up with something that suits a specific case though, as long as you properly take into account the way VB behaves in respect of the various dpi settings on different machines, which is as roughly outlined above.

Mike




.



Relevant Pages

  • Re: DPI setting problem
    ... Then at runtime (when you compiled app is run) VB looks at all the twip settings and converts them to pixels in accordance with the current twips per pixel setting of the machine on which your code is running. ... I think that this was originally a deliberate design choice by Microsoft because it allowed you to write a "smaller than the screen" fixed Form size app and it would be a specific size on a machine running at the standard 96 dpi setting. ...
    (microsoft.public.vb.general.discussion)
  • Re: Stack over flow?
    ... the value sent you need to set the PictureBox ScaleMode to vbPixels (I ... receives from the OS (which of course contains standard default pixel ... ScaleMode of the PictureBox. ... you will get a value of 1500 on a machine running at the standard 15 ...
    (comp.lang.basic.visual.misc)
  • Re: Adjusting Combo Box Height Property
    ... > controls, but the crazy decision by ms to make the combo box 1 pixel ... could i hold place this code in an inherited combo class componet. ... I wish my eyes were still young enough to notice a 1 pixel height ... public static extern int SendMessage(IntPtr hwnd, uint Msg, int wParam, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Show Design Grid in a Picture Box?
    ... I've just noticed that you appear to be placing Controls (Line ... controls) into your Picture Box as well as other pictures (which I assume ... will be different to the pixel size on your development machine (although ... then you might be inclined to set its Stretch property to False while you ...
    (microsoft.public.vb.general.discussion)
  • Re: SetMapMode
    ... if Steve is not prepared to write his code in such a way that the user passes the Control to his dll then he is unlikely to want the user to pass the Form or the Forms collection either. ... The second reason is because Steve has said that the window handle which is being passed to his dll is not necessarily the handle to a VB window. ... Besides, Steve apparently wants to "read" the VB ScaleMode of the window in order that he can calculate the pixel values of the passed coordinates in accordance with the ScaleMode, but doing it that way assumes that the person who wrote the code that "called" his function is actually using the ScaleMode units for his coordinates. ...
    (microsoft.public.vb.general.discussion)