Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Get application’s DPI Awareness 2

Status
Not open for further replies.

Gerrit Broekhuis

Programmer
Aug 16, 2004
316
NL
Hi,

I know it’s best to set an application’s DPI Awareness with a myapp.exe.manifest file (and that is what I do indeed).

Another - less effective - way is to use WIN32API and call SetProcessDPIAware().

I would like to know if there is something like “GetProcessDPiAware()”, to get the DPI awareness from within an application.
This would verify the DPI Awareness is set correctly.

Or is there another logical check for DPI Awareness? I don’t want to rely on visual verification, as most customers don’t notice any difference.

Regards, Gerrit
 
A small update from my side.

I set the dpi awareness now back to FALSE in my manifest. I have used TRUE for some days. On a full HD screen this looked OK, but on my 4K laptop screen it is dpi aware indeed and all forms are way too small. For normal readability a 200% scaling is requited on a 4K screen. And you cannot use any compatibility setting in the application’s shortcut for this. A full HD form with 1920 x 1080 pixels will still only use 25% of the screen...

I will do some testing soon with Antonio’s code “as is”.

A 4K screen resolution is still presenting a lot of challenges for a lot of commercial programs too, even though they look fine on a full HD screen. I’m still learning how to deal with this and checking all options.

Regards, Gerrit
 
Gerrit,

Thank you for testing. There is still a lot of things to test and address, and your input will be precious.

A few things to note:
[ol 1]
[li]Some graphic elements are outside the range of action of the DPI manager class: browse windows, the status bar, the Wait window (they will come small), and message boxes (Windows will scale these, making them blurry - I will try with Cesar's Foxydialog and see how a DPI-aware application renders it).[/li]
[li]The system menu requires special handling. It can be resized to higher scales, but the menu must be completely rebuilt when the DPI scale changes. I left an example (for just one of the system menu pads) in the test application.[/li]
[li]Adding controls at runtime can be done, but to put them under DPI-aware management, the manager must know about them. There is also an example of a DPIAwareOptionGroup subclass in the DPIAwareManager code. It may be used as a template.[/li]
[li]Grids scaling needs to be revisited. Some of the grid elements will not scale or not in the same manner (the record mark, the delete mark, panel separators, and the scroll bars). If the overall grid width scales (for instance, 1.5 times), these elements not scaling means extra space for the columns that will not be used. The grid resizing (whether growing or shrinking) must take this into account.[/li]
[/ol]

That said, the class is gaining some muscle, and I believe it will become usable eventually.
 
Gerrit,

what I suggested was using dpi awareness, and when your forms are okay with HD (1980x1080) or any resolution you know, then start them in that size (instead of fullscreen), afterwards (late, in the first form activate) maximize them and have a traditional resizer, which just enlarges every control width and height and font sizes. The end result then is good. The moment to change to fullscreen can be the first forms activate. That's the easiest way to deal with high resolutions.

Edit: If 200% scaling from Windows are activated, you have to counteract that, because the form design for HD will be best with 100% scaling and that means your fontsize scaling factor should be
actual width/(initial width * windows scaling factor). In case the resolution is double size and the scaling is set to 200%, the effective factor is even just 1, the 200% scaling is then often also recommended by the laptop or (embedded) graphics vendor to not use the high resolution for more text, but simply crisper higher resolution fonts, icons, etc. and when your app is dpi aware Windows will make the fonts double sized (quadruple area) but not change form and control dimensions, that's your only job, then.

Chriss
 
Gerrit,

For some reason, I couldn't upload images in the above message as I wanted to illustrate some of the current DPIAwareManager class capabilities.

Meanwhile, I tried running FoxyDialog() in a DPI-aware application to replace MessageBox, and the result is also shown below.

dpi1_lz103w.png


This is a screenshot of an application running @ 150% DPI scale. The points to note:
[ul]
[li]Fonts of menu pads are scaled (this is controlled by a _Screen object that receives information from the DPI manager when a change of scale occurs).[/li]
[li]The label "hWnd" reacts to the change of scales in a particular fashion. The control displays its caption in orange bold when the DPI scale is not 100%. This demonstrates that controls can incorporate their own processing to complement or replace what is done by the DPI Manager.[/li]
[li]Images can have an alternate picture to replace the ones targeted at the standard DPI. VFP scales the Image control on the left from a 96x96 image. The one on the right starts with the same image, but the Manager replaces it with a 528x528 image when the scale goes up to 150% and beyond.[/li]
[/ul]

Finally, a standard MESSAGEBOX() in a High DPI monitor, scaling to 150% (note the blurriness of the dialog contents, contrasting with the sharpness of the title),

dp2_ilaoct.png


and a FoxyDialog() at the same DPI scale

dpi3_bcjyzs.png
 
Thanks Antonio. Looks like the FoxyDialog is the way to go. This is an important subject and probably the greatest challenge for VFP application development. I hope this thread continues to be updated.

For the sake of this discussion, I will not use the term "DPI Aware" because VFP is not DPI Aware and any effort to make VFP DPI Aware by means of a manifest or SetProcessDPIAware() is useless. It is better to refer to the ability of VFP to properly resize objects, fonts, menus, etc. by means of specialized classes.

We are doing some "best practice" research on this subject: For the last few years, most business OEMs (e.g. Dell, HP, Lenov) have been offering two monitor resolutions for laptops and desktops: 1920x1080 and 3840x2160 (4k). There are also gamer machines with 2560x1440 and 3440x1440 resolutions. These are the important resolutions to be concerned about. To perform effective "resizing", the developer has to start with the lowest common denominator with respect to the development environment: A 1920x1080 (96 dpi) monitor. Any developed application (before resizing) can never exceed a total of 1280x720 pixels - including forms, toolbars and menus. Here is why:

Resolution / Max DPI Scaling = Lowest Dev Resolution
1920x1080 ./ Divide by 150% ... = 1280x720
2560x1440 ./ Divide by 200% ... = 1280x720
3440x1440 ./ Divide by 200% ... = 1720x720
3840x2160 ./ Divide by 200% ... = 1920x1080

The maximum resizing factor (DPI scaling) has to be accounted for to determine the lowest common denominator for the development environment. As shown above, that is 1280x720. This also means that application development for 1920x1080 (96 dpi) monitors is restricted to 1280x720 - yikes, we don't like that!

Of course, this is a broad stroke and does not take into account screen resolutions lower than 1920x1080. However, it may be a good map for the future.
 
Vernpace,

An application is DPI-aware as long as it can recognize the state and changes of DPI settings in display devices it is using as output and react accordingly by adjusting to the DPI scale setting of the device. Of course, this meaning allowing and be prepared for its screen and top-level forms to move from one device to another and move from a DPI setting to another.

What Windows expects from a DPI-aware application is laid down here: The goal of the DPIAwareManager class is to support "Per-Monitor and Per-Monitor (V2) DPI Awareness". As I pointed out, VFP imposes a few limitations, but those seem marginal and even replaceable.

The class is already honoring the DPI-awareness declaration of the application and, in general, performing as specified. For instance, a form displaying on a device with a DPI scale of 100% can be moved to a monitor with a different scale and automatically resize its objects to support the new settings. The same reaction if the monitor on which it is displaying changes its DPI settings. By using the DPIAwareManager class, or something like it in its place, a VFP9 application can not only be fully DPI-aware but also dynamically DPI-aware.

The manifest is the opposite of being useless. Not only it allows the VFP9 application to take control of the rendering of most of its graphical elements and improve the quality of the process, but it also guarantees that reports using the 90 behavior are properly rendered, without misalignments and printing off-margins.
 
Vernpace,

Good reading, thank you. I will check on how GDI scaling affects VFP9 applications, and the output of the report engine in particular (since it's a GDI issue, in the first place).
 
Antonio,

One thing to keep in mind is that VFP developers (like us) use GDIPlusX and FoxCharts extensively and not necessarily in reports. Also, the Image control's PictureVal uses GDI+. Not sure what else, but proper GDI+ rendering can be just as important. What is not clear in the docs is whether GDI Scaling can coexist with DPI Scaling
 
Antonio,

What you are doing is extremely interesting. Question: Since your DPIAwareManager class will support "Per-Monitor and Per-Monitor (V2) DPI Awareness", will you implement the use of WM_DPICHANGED message structures for HWND notifications?
 
Vernpace,

I haven't tried yet with FoxCharts, nor with ActiveX controls. I have access to two different versions of TextControl, for instance, the older one is not DPI-aware, the more recent is. It will be interesting to see how they behave.

The manager reacts to WM_DPICHANGED messages. That's how it senses a change for top-level forms. With the _Screen is a bit different, but this may change in the future.

Anyway, remember that you can accompany (or contribute!) the development of the manager at or use its ideas to incorporate into something completely different and that best matches your own framework.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top