Create mobile apps with HTML5, JavaScript and Visual Studio

(Elle) #1

msdnmagazine.com February 2014 13


pixel density of the screen, but in reality many factors infl uence


the DPI value—such as form factor and distance to the screen—


so the eff ective DPI value you end up using has little to do with an


actual inch. Th ese four options also represent the full spectrum of


possibilities, but what a particular PC might off er depends on the


vertical resolution of its displays.


Th is is illustrated in Figure 5. Th ese limits are intended to keep


UI elements from getting cropped off the bottom of the display. If


your display has fewer than 900 lines of vertical resolution, then


you won’t have any options and the 100 percent scaling factor will


be all there is. As the vertical resolution of your display increases,


you’re presented with more options until you reach 1,440 lines of


vertical resolution, at which point you experi-


ence all four possible options. These options


do not, however, affect the scaling on all


monitors equally. Th is is where the concept of


per-monitor DPI scaling comes from. It isn’t


entirely obvious at fi rst glance because the OS


takes into account both the vertical resolution


as well as the native DPI for the physical display.


As a developer of desktop applications, it’s


important to realize there are now two scaling


factors that may be at play. Th ere’s the system


DPI scaling factor and then there’s a per-monitor


DPI scaling factor. Th e system DPI scaling factor


corresponds to one of the values in Figure 4—


with the exception of devices such as Windows


Phone—and remains constant for the duration


of the logon session. Th e system DPI value is


based on the initial radio button shown in Fig-


ure 2 or the slider position shown in Figure 3.


To retrieve the system DPI value, you start by


getting hold of the desktop device context. Yes,


this boils down to the old GDI API, but it has noth-


ing to do with GDI rendering and is only a historical footnote. First,


to get a handle representing the desktop device context, you call the


GetDC function with a nullptr instead of a window handle. Th is


special value indicates you want the device context for the desk-


top as a whole rather than a particular window:


auto dc = GetDC(nullptr);

Naturally, you must remember to free this


handle when you’re done:


ReleaseDC(nullptr, dc);

Th e fi rst parameter is the handle to the win-


dow to which the device context refers. Again,


a nullptr value represents the desktop. Now,


given the device context, you can use the Get-


DeviceCaps function to retrieve the system DPI


scaling factor for the x and y axes as follows:


auto x = GetDeviceCaps(dc, LOGPIXELSX);
auto y = GetDeviceCaps(dc, LOGPIXELSY);

Having a diff erent value for the x and y axes


dates back to the dark ages when printers rou-


tinely off ered diff erent scaling factors horizontally


and vertically. I’ve never come across a display


that off ers up non-square pixels, but I hear they


do exist in some industries for which special


graphics cards have been developed. LOG-


PIXELSX and LOGPIXELSY represent the


number of pixels per logical inch along the


Figure 3 Windows 8.1 PC Setting Affecting Dynamic


and Per-Monitor Scaling for the Desktop


Figure 2 Pre-Windows 8.1 PC Setting Affecting Desktop Applications


It’s important to realize there


are now two scaling factors that


may be at play.

Free download pdf