I'm having a go at multi monitor high DPI support for my styled 64 bit VCL app, which is still not supported in 10.2. Using Scaled and ScaleBy I can come a long way, but what about main and popup menus, anyone an idea how to scale these? Looks like the main screen DPI setting is used, not the monitor where the menu is drawn. This makes for very miniature menus!

I'm having a go at multi monitor high DPI support for my styled 64 bit VCL app, which is still not supported in 10.2. Using Scaled and ScaleBy I can come a long way, but what about main and popup menus, anyone an idea how to scale these? Looks like the main screen DPI setting is used, not the monitor where the menu is drawn. This makes for very miniature menus!
See also RSP-12580 (not mine but related).
See also https://stackoverflow.com/questions/33020096/how-to-handle-menu-scaling-after-runtime-dpi-change-in-delphi-seattle (old, and not my preferred solution).

Comments

  1. I have found similar problems with plain RadioButtons and CheckBoxes. Although I would love to see MS work that out properly (the current status is Won't do), it won't help much as long as all potential users are not yet on the latest Windows version then. Given the current state of HDPI support in different Windows versions I doubt that one can get that working with all available VCL controls and there is only so much that Embarcadero can do about that. Seems that FMX might be an alternative here.

    ReplyDelete
  2. It's a must do for me as the percentage of my clients that have a 4K laptop or small screen is growing steadily, and I'm loosing them because of this.
    I'm OK with just static multi DPI support in W10 for now, and so far that seems to look promising (including radio buttons). So far the issues I am worried about are limited to dialogs and menus, both have fonts that don't scale automatically nor do I know how to do that manually.
    FMX is not suited for multi-threaded real-time video processing, VCL barely is.

    ReplyDelete
  3. The issue with RadioButtons and CheckBoxes is visible only when you have multi monitors with different DPI. Effectively it boils down to use custom drawing for these controls.

    ReplyDelete
  4. As I implicated in my original post I have multiple monitors with different DPI settings. It works fine for me. My issues are with dialogs and menus. Lacking automated support, how can I manually change the font size in menus? For dialogs the problems is even more odd: the title text does not respect DPI but the message does.

    ReplyDelete
  5. Don't think it helps that Emba insist on owner drawing menus.

    ReplyDelete
  6. Well, that was easy! You can change both main and popup menu font size with Screen's MenuFont. Unfortunately there is no DialogFont property, so the dialog titles are still way too small..

    ReplyDelete
  7. Actually, above works but the popup menu does not adjust its width to fit the larger fonts so the widest entries get cut off. I assume this is a bug in VCL. Anyone have an idea how to work around this?

    ReplyDelete
  8. First of all check that you are on the latest Creators update (1703). Only in this update Microsoft has added automatic scaling of system elements such as main menu. Then, as the first action of your app, you will need to call SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2). After this call scalling of system-drawn elements should work according to Microsoft: blogs.windows.com - High-DPI Scaling Improvements for Desktop Applications in the Windows 10 Creators Update - Building Apps for Windows

    ReplyDelete
  9. Thank you, I will look into this and report back.

    ReplyDelete
  10. Микола Петрівський Didn't get anywhere with this: I cannot use SetProcessDpiAwarenessContext as the compiler cannot find its definition (despite including Windef). I also tried (the recommended way of) creating a manifest and adding PMv2 awareness but this makes the debugger crash consistently.

    ReplyDelete
  11. As no one seems to be able to help I opened a support case (00585679).

    ReplyDelete
  12. Not good news I'm afraid.. VCL does not support the new multi hdpi features in creators update and neither does upcoming 10.2.1.

    ReplyDelete
  13. I sort of expected that. MS is changing HDPI handling in Windows faster than anyone can follow. When a feature is so strictly tied to a particular Windows build number, relying on that feature can be a real challenge.

    ReplyDelete
  14. I've not had any problems using per monitor v2 DPI. I do it through a manifest though. I'm also using XE7 and handling the entire DPI scaling myself because XE7 predates Emba high DPI support.

    ReplyDelete
  15. As I mentioned earlier Tokyo does not support a manifest with the PMv2 flag (curious XE7 does) and reverting back to XE7 is not an option for many reasons. Although I fail to come up with even one right now :D

    ReplyDelete
  16. What do you mean "does not support"? You just add a custom manifest. Surely that is possible in Tokyo.

    ReplyDelete
  17. Yes, just not that flag. See my earlier post: with debugging the debugger crashes, without it I get the "side-by-side configuration is incorrect" error which AFAIK means it's not supported. Which EMBD support confirmed.

    ReplyDelete
  18. That's because your manifest is no good. Defect is at your end.

    ReplyDelete
  19. I have tried following code in my project: "const
    DPI_AWARENESS_CONTEXT_UNAWARE = 16;
    DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = 17;
    DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = 18;
    DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = 34;
    function SetProcessDpiAwarenessContext(value: Integer): BOOL; stdcall; external user32 name 'SetProcessDpiAwarenessContext' delayed;
    //... SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
    But it does not change anything. Main menu is scaled anyway (I am on Tokyo), and popup menu - doesn't. So VCL definitely needs a fix. On FMX everything is the oposite - the only thing that scales is popup menu.

    ReplyDelete
  20. Meanwhile I managed to get the manifest to be accepted (don't use the code posted by M$) but it makes things worse: the popup menu is offset from the mouse and the text is all fuzzy (like it is not dpi aware). For those jumping in without reading previous posts: this is using styles, behaviour differs when not using styles.
    No updates from EMBD support today, let's hope they're busy coding.

    ReplyDelete
  21. Микола Петрівський works fine for me using a manifest. I'm not sure you've diagnosed things properly.

    ReplyDelete
  22. David Heffernan Can you upload a small demo somewhere?

    ReplyDelete
  23. Ok, so with following manifest it really works:


    name="MyApp"
    processorArchitecture="*"
    version="1.0.0.0"
    type="win32"
    />
    My Application description


    type="win32"
    name="Microsoft.Windows.Common-Controls"
    version="6.0.0.0"
    processorArchitecture="*"
    publicKeyToken="6595b64144ccf1df"
    language="*"
    />





    level="asInvoker"
    uiAccess="false"
    />





    http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM
    http://schemas.microsoft.com/SMI/2016/WindowsSettings">
    PerMonitorV2, PerMonitor











    ReplyDelete
  24. Mike Versteeg Make sure to update your support case. We all will benefit from good default manifest.

    ReplyDelete
  25. Interesting. And you tested this with styles?

    ReplyDelete
  26. Микола Петрівський Well.. I first need to get positive results. This is not working for me. In fact it makes things worse. I also don't understand why adding the supportedOS makes any difference (the rest of the manifest looks exactly the same as what I had already). You are using styles, right? Windows 1703?

    ReplyDelete
  27. Styles? Not gong to fly with styles. Going to need VCL support. That's the cross you bear for choosing to use styles.

    ReplyDelete
  28. Another reason for our differences could be you are using single HDPI, not multi? My primary monitor is 96 dpi, I test VCL on a second monitor that is 144 dpi. I do not move my app from 96->144 as that is a different scaling with what you see when you create the app on the 144 dpi monitor. In fact moving the app from low to high DPI has always worked rather well, but not instantiating on high DPI. I feel to show the bugs it is also very important to have the primary monitor low DPI (I think it takes most of its settings from there and use these).

    ReplyDelete
  29. I've had no probs at all with per monitor DPI in my own implementation. Obviously I've tested with monitors at different DPI.

    ReplyDelete
  30. Mike Versteeg I have tried with styles (Ruby Graphite). At first glimpse looks fine. But I probably will not notice if it will be a few pixels off. And it probably depends on style too.

    ReplyDelete
  31. David Heffernan I've always known it works fine without styles, my issue is with styles. I should have made that clear from the start and I apologise for any confusion this has caused.

    ReplyDelete
  32. Микола Петрівський Interesting. I use Carbon and all fonts are small. If I manually change MenuFont most are OK but dialog captions and buttons remain small.
    https://plus.google.com/photos/...

    ReplyDelete
  33. Agree, I looked closer and now see, that styles cripple scaling a lot. All fonts and bitmap elements from style are not scaled.

    ReplyDelete
  34. Right, looks like we've got this figured out then. I'll repeat all tests with 10.2.1 and report everything to Embarcadero. Let's hope 10.2.2 will be a smooth ride!

    ReplyDelete
  35. Styles are a bit hackish technology. Fixing DPI scaling there may be quite a big effort. So I wouldn't expect this to be fixed at least until 10.3.

    ReplyDelete

Post a Comment