guides:oi10:presentation_server_model:800_appendix_k_high_dpi_programning

With the increasing popularity of high-resolution monitors, one of the biggest usability problems today is the display size of text and UI controls, because they appear smaller as the screen resolution increases. The recommended advice to overcome this is to increase the DPI (dots-per-inch) setting of the system, thereby enlarging these elements and making them easier to see and read. If you’ve been using Windows Vista and above you’ve probably already seen this Control Panel applet that allows you to easily change your DPI settings:

Windows 7 DPi Control Panel Applet

Windows 7 DPI Control Panel Applet

However, unless an application is designed to be DPI-aware this can result in some unsatisfactory results, such as over-large fonts, clipped controls and blurry windows. This is because many older Windows applications assume a constant DPI (96) when setting font and size coordinates and they do not apply any scaling to these values, thereby resulting in the aforementioned problems.

(NB. The “magic number” of 96 that you’ll see throughout this document is due to the fact that at 96 DPI one logical pixel is equal to one screen pixel – this is the “100%” setting in the Control Panel applet shown above).

In an effort to accommodate these applications Microsoft have introduced a couple of OS features over the years:

  • On Windows XP the system fonts and some system UI elements are scaled up at runtime, but this leads to the common problem of text appearing larger and being clipped as the actual size of the bounding control is usually not scaled.
  • On Windows Vista and above a feature called “DPI-virtualization” automatically scales windows belonging to an application not marked as “DPI-aware” – in effect they are rendered at 96 DPI to an off-screen bitmap, resized, and then drawn to the screen, but this can result in some blurry windows due to pixel stretching. OpenInsight 10 is marked as a DPI-aware application so will not be subjected to DPI-virtualization, unless you use the "dpiAware" configuration option to turn it off (See the section headed " Starting the Presentation Server" earlier in this document).
Here's an example of DPI virtualization comparing different versions of OpenInsight:

https:revdevx.files.wordpress.com/2014/05/high-dpi-v9-and-v101.png

High-DPI comparison between v9 and v10 1

In the example above both forms are running on a desktop set to 144 DPI (150%). The top form is running under OpenInsight v9 and, as you can see, has been stretched by the system resulting in blurry outlines, icons and text. In contrast, the bottom form is running under OpenInsight v10 and has been scaled correctly – the checkbox image and icon are sharp and crisp, and the font has been scaled to the correct point size.

OpenInsight supports High-DPI by automatically scaling-up all GUI objects at runtime when created through the SYSTEM object’s CREATE method (formerly known as the “Utility CREATE service”). This affects the following two properties:

  • Size coordinates
  • Fonts

The actual scaling for coordinates is calculated by the following simple formula:

screenPixels = logicalPixels * ( currentDPI / 96 )

(logicalPixels are also known as "DIPs" – see "Handling High-DPI layout for scaled forms and controls" below for more details)

For example, if you create a control with a size of 200×100 logical pixels (DIPs) and you are running at 144 DPI on your monitor (i.e. 150% as per the Control Panel applet above) then the control will be created with an actual size of 300×150 pixels.

The font point size is similarly multiplied by the scaling factor (i.e. currentDPI / 96).

This leads us to one of the main issues with handling scaling: how do you get and set layout properties like SIZE for a scaled form? What units are used?

There are basically two choices available:

  • Use Device Independent Pixels (DIPs), also know a "Logical Pixels": With this method all coordinates are treated as though the form is scaled at 96 DPI with a scale factor of 1. The system is then responsible for mapping them to actual pixels at runtime.
  • Use Pixels (PX): With this method the coordinates passed are treated as actual screen pixels regardless of the DPI or scale factor.

By default, OpenInsight will always use DIPs when referring to coordinates and fonts. This provides maximum backwards compatibility with existing code and is certainly easier to work with from a developer's perspective. Having said that, there are a couple of possible drawbacks to be aware of:

  • Positioning can be imprecise due to integer rounding during a scaling operation from DIPs to PX (you may sometimes find a case where you need complete accuracy).
  • Some properties and events might be more useful to you in PX (mainly those that relate to screen coordinates), depending on the situation you are working with.

So, to mitigate this, all forms support a SCALEUNITS property that can be set at runtime to specify what units you want to work with, and there are also several other scaling helper methods (such as SCALEFONT, SCALESIZE etc.) that are available as well.

Another noticeable issue when running at high DPI settings are images, which are assumed to have been designed for 96 DPI and therefore have to be scaled up at runtime leading to a potential loss of quality due to the resize. To help with this the toolset has been extended to allow repository IMAGE and IMAGELIST entities to specify multiple image files when being defined:

  • The first will be used for 96 DPI (100%),
  • The second for up to 120 DPI (125%)
  • The third for up to 144 DPI (150%),
  • The fourth for up to 192 DPI (200%) and so on,
  • And further images can be defined at 48 DPI (50%) increments (for future-proofing).

When an image is displayed at runtime the system picks the appropriate size and scales it as needed (preferably down where possible) before applying any other transformations (See the Image Object API section and the corresponding FILENAMES property earlier in this manual for more details).

If you design your forms when running under a High-DPI setting the Form Designer will save and compile all coordinate and font information as though you were developing at 96DPI, so the values will be scaled down appropriately and stored as DIPs.

Until Windows 8.1 the DPI setting for the system was constant across all monitors and fixed during the login process – selecting another DPI setting required logging out and back in again, or even a full reboot in the case of Windows XP. Now, with the steady increase in monitor resolutions across different form factors, Microsoft have added the ability to set the DPI per monitor, which means that forms created on one monitor may look too small or too big when moved to another monitor with a different DPI.

In order to deal with this at runtime, top-level forms are now notified by a new windows message called WM_DPICHANGED, which is sent when either of the following happens:

  • The DPI of the monitor a form is displayed on changes, or
  • The form is moved between monitors that have different DPI settings.

This message is used by OpenInsight to adjust the scale of a form dynamically as required, so you will see this happen as you drag it across monitors with different DPIs. All the rules described above still apply of course:

  • Fonts are scaled
  • Coordinates are scaled
  • DPI-aware images are selected and/or scaled

As a developer you can react to this if you wish by using the form's SCALED event, which is triggered when a WM_DPICHANGED message is received.

Of course, we always try our best not to break existing applications so you can set an option in the RXI file to turn off the automatic DPI scaling if you wish (this option is exposed at runtime via the read-only SYSTEM DPISCALING property).

  • guides/oi10/presentation_server_model/800_appendix_k_high_dpi_programning.txt
  • Last modified: 2024/03/29 18:59
  • by 127.0.0.1