Just started to make our projects HighDPI aware - especially on Windows 8 tablets.

Just started to make our projects HighDPI aware - especially on Windows 8 tablets.

From now on I'm going to refer to this as "Project Pandora". Delphi is not really made for making HighDPI aware programs.

Using DevExpress components already solved a lot of the potential trouble. But it is surprising how many components - even 1st party Delphi components - totally lack HighDPI awareness.

Comments

  1. What I found really surprising was that even Windows Explorer was not high DPI aware.

    ReplyDelete
  2. Asbjørn Heid , yes it's surprising how many Microsoft modules - even parts of the OS in Windows 8 - do not properly support high DPI displays. It looks like all this high DPI stuff is quite new to MS :).

    After reviewing our own projects it looks like 20% still need to be adjusted. In result we are going to replace most of the components with DevExpress components that already support high DPI.

    BTW: I'm not working for DevExpress.

    ReplyDelete
  3. Can you provide a list of component vendors who do not support high DPIs please?

    ReplyDelete
  4. I have a project using XE2 and DX (13.1). But i think the issue is XE2. The IDE puts two form properties in inherited forms dfms when i edit them. These are PixelPerInch and TextHeight. These properties must reside in the base form, but for each inherited level that gets streamed in these properties will offset some stuff incorrectly on high DPI screens. I wrote a small loop to check and remove these properties before building in all dfm:s containing "inherited".

    DX LayoutControl will not render a layout designed on a traditional DPI screen properly. This problem was easier to solve. I simply litter the layouts with vertical splitters so users with high DPI can change the width of all exit boxes.

    Should not a FireMonkey app handle these things much better since it's free of much of the Win32 API that the VCL uses? Correct me if i'm wrong here, i have not had so much experience with FM.

    ReplyDelete
  5. Dany Marmur Firemonkey has NO HighDPI-Support at all (anymore)! You can scale via a TLayout but theming is totally broken then. See: http://stackoverflow.com/questions/20993907/delphi-firemonkey-scale-for-high-dpi-windows

    ReplyDelete
  6. There is BaseForms project for the rest of us without DX https://github.com/delphinotes/BaseForms

    ReplyDelete
  7. Ilya S That sounds very interesting. Where can I read more about this BaseForms project?

    ReplyDelete
  8. Steffen Binas Forgive my confusion, as I am still toiling in D2007, but I thought FireMonkey was created to facilitate mobile support. If that is the case, then it would seem essential that it provide support for high DPI... or have I misunderstood?

    ReplyDelete
  9. Bill Meyer That was original idea, but it looks that it got screwed on the way, probably because of "pixel perfect" controls. I haven't thoroughly investigate what is wrong with FM and high DPI, but it is broken for sure.

    ReplyDelete
  10. Dalija Prasnikar Then I would think that fixing High DPI in FMX, given the obvious focus on mobile in XE6, would have to be a top priority. It's interesting, as we are moving soon to XE5, and I have been looking for a mobile device of my own to tinker with. The only ones I have been considering would apparently be badly supported now, if I understand the issue correctly.

    ReplyDelete
  11. Ilya S Back in the days of D5, if memory serves, there were a couple of components which attempted to address form scaling. Actually, only one of them really tried to handle scaling, in the sense most of us would understand it. I bought that one, and spend some considerable time experimenting with it. The author made heroic efforts, but there were substantial problems. 

    Scaling a form to the screen without altering the layout is difficult. With integer font sizes, it is almost impossible. Using integer font sizes gives us very little room to maneuver with small fonts sizes, which is where we most need the ability to adjust. 

    Before the mobile market, I think these issues were overlooked by anyone not doing some sort of process control app. In office apps, they are not so much an issue because when the form is larger, you simply see more rows or columns. In process control, you typically have controls all over the rom, so the desire for a scalable form is much greater.

    ReplyDelete
  12. Bill Meyer FMX has some styles which are explicitly designed for HighDPI. These are used automatically on OSX Retina and mobile platforms. But on Windows there is no such style. My last experiments where with XE5...maybe XE6 has some improvements, but I doubt (see TPlatformWin.GetScreenScale returns a constant 1.0).

    ReplyDelete
  13. Steffen Binas The sudden appearance of 4K monitors at relatively low prices will change many things...

    ReplyDelete
  14. Bill Meyer not to forget: many new Windows tablets use Full HD displays and have high DPI scaling enabled as default - otherwise the content on the desktop wouldn't be readable.

    ReplyDelete
  15. Fred Ahrens Understood.  But I think that the same will be true on a 28" display at 3840x2160.

    ReplyDelete
  16. It becomes already a problem on my new Dell Laptop: 15 inches with 1920 x 1080 Pixel. Only when scaling up to 150% text becomes readable (for me). Windows Explorer looks clear and crips; but almost all 3rd party applications look blurry; including the Delphi IDE.

    I did some small test applications. Without any special manifest or API calls, the application will run with virtual 96 dpi (=100%); and Windows scales all up to 150%. That's why almost everything looks blurry.

    Using a manifest resource makes my test applications look clear and crisp, but it ist not scaled to 150%. Unfortunately there is no property in TForm which tells on which dpi setting the form was designed, so I am stuck at the moment.

    Any ideas or links to good readings about Delphi and High-DPI?

    ReplyDelete
  17. Achim Kalwa You can set high DPI awareness in Delphi with SetProcessDPIAware - it must be executed before the VCL gets initialized. The scaling of the forms will be done with Form.ScaleBy(PixelsPerInch, Screen.PixelsPerInch);

    But that's only a starting point.

    ReplyDelete
  18. In Alisters interview with Marco Interview #2 - Marco Cantu that HD Problem is mentioned and that they're working on it.

    ReplyDelete
  19. Achim Kalwa I ran my ThinkPads on 1920x1200 (120 pixels still make a difference) at 15.4 inch without any scaling. Still wish those were IPS (the last with IPS were 1600x1200 at 15 inch). Now I'm really happy with Retina MacBook IPS with 2880x1800 at 15.4 inch with 150% pixel scaling. It has some artifacts (even on the Mac side: put two filled rectangles one red, one green next to each other and you will see) as effectively I get 1920x1200, just as you effectively get 1280x720. I'm tempted to run full resolution (as VMware Fusion and Microsoft remote desktop support high DPI) with just font scaling to 150%, but Google Chrome on the OS X host keeps crashing the operating system unless I open 35% less Windows.

    ReplyDelete
  20. Fred Ahrens has http://qc.embarcadero.com/wc/qcmain.aspx?d=86494 been resolved by adding SetProcessDPIAware call or true into the manifest?

    ReplyDelete
  21. Ilya S In my opinion  that's not really an error - more an intended behavior ... and initially hard to understand. Windows handles all applications without the extended manifest (or calling SetProcessDPIAware) as non high DPI compliant programs. Forms will be graphically scaled by Windows - that's why these programs look blurry and why Screen.PixelsPerInch still returns 96. As soon as you have the extended manifest (or call SetProcessDPIAware) it's up to you to react to the changed screen PPI. If you do nothing, your forms will look quite small. All the necessary scaling needs to be implemented by the developer. Calling Form.ScaleBy(PixelsPerInch, Screen.PixelsPerInch) for each form created by the program is just the first step for reacting on the changed screen PPI.

    So far it looks like if there is no difference between extending the manifest or calling SetProcessDPIAware. In Delphi SetProcessDPIAware must be called before the initialization of the VCL (create a separate unit, add it as first in the uses clause and within this unit call SetProcessDPIAware in the initialization section - Windows version must be newer than XP.

    ReplyDelete
  22. There is no problem to start using either Manifest or SetProcessDPIAware on Vista+. You will start seing
    Screen.PixelsPerInch=120
    Application.DefaultFont.PixelsPerInch=120
    isProcessDPIAware=True
    Form.Font.PixelsPerInch=120
    Form.Scaled=True
    Form.TextHeight=13
    Form.Canvas.TextHeight('0')=16
    for Tahoma in 125% scaling instead of blurry (or is it?)
    Screen.PixelsPerInch=96
    Application.DefaultFont.PixelsPerInch=96
    isProcessDPIAware=False
    Form.Font.PixelsPerInch=96
    Form.Scaled=True
    Form.TextHeight=13
    Form.Canvas.TextHeight('0')=13
    in 100%. Text looks smallish in bigger buttons now. Scaled=True changed geometry of the form appropiately to DPI change, but the font size still the same.
    And what about XP-2003?

    ReplyDelete
  23. Ilya S I don't get your point here: is there a problem, or is there no problem?

    ReplyDelete
  24. Well, to make the matter simpler let's forget about pre-Vista OS. In Vista+ you have a choice to make about HighDPI:
    1) forbid it (dpiAware=false) AND (Form.Scaled=False)
    2) allow HighDPI virtualization made by Windows resulting in blurry fonts and controls (not sure what combination of factors leads to this)
    3) handle it (dpiAware=true) AND (Form.Scaled=True) and anything other that appears in the process
    Am I correct about these points yet?

    ReplyDelete
  25. Ilya S I'm not sure, as HighDPI is still on my research list.

    ReplyDelete
  26. Ilya S We are still investigating in making Delphi software high DPI aware. At least it looks like a good decision to use the desktop font (Screen.IconFont) for all our forms. We use this principle now for more than 7 years. This already required a lot of work to react on font size differences between the font used for development and the actual font/font size used on the system.
     
    And to be honest: so far I really don't know how many other problems have been solved already just by using DevExpress components for the user interface.
    I should write down what we have found out so far in a blog post and publish this here.

    ReplyDelete
  27. Fred Ahrens a blog post might be very helpful for others and me at least to consider is it worth to delve into HighDPI problem. Nevertheless, it promise to be very interesting reading. I've read many articles about it last year, but without practical application and examples they just explain what's going on, and not what to do.

    ReplyDelete
  28. Ilya S I am afraid that it is not that simple. What you are describing worked in Vista, but it doesn't work in Windows 7/8. There Windows will enlarge (blur) your app only at 150% or larger scale, and at 125% your app will either fall apart (if you turn on Form.Scaled) or will have smaller fonts than your users expect.

    The only way to properly deal with HighDPI on all systems starting with XP is to make your app DPI aware and make sure that all controls and forms scale properly at 125% and 150%. From my experience if it looks right at 150% it will look right on larger scale too.

    ReplyDelete
  29. Jeroen Wiert Pluimers The only problem there is, is that some included Delphi controls do not scale properly. Also styled VCL doesn't work well on HighDPI. I don't know how well 3rd party controls handle scaling.

    ReplyDelete
  30. Dalija Prasnikar not sure why Windows 7 behavior compared to Vista have changed, at least I couldn't find it in this article http://kynosarges.org/WindowsDpi.html
    Could you please describe steps how do you make sure that all controls scale properly at 150% if you design the form in 100%?

    ReplyDelete
  31. Ilya S There are two steps. First you have to make sure that control responds well to scaling (most of Delphi controls do). That means that control has to change its size and font. Next you have to make sure that you leave enough room in your design for textual data to expand. This is where integer rounding in font sizes can bite you. 
    The only difference between 125% and 150% scale is that text can have enough room at 125% scale and not enough at 150%.

    ReplyDelete
  32. Ilya S I am not sure why TBitBtn is not working properly for you. I am using XE4 and it works fine here.

    ReplyDelete
  33. Ilya S Thanks for bringing out my styled form QC report. It has been closed As designed some time ago, and I didn't realize that it is opened again.

    ReplyDelete
  34. Ilya S OK, windows 8.1 completely messed things up with HighDPI. I didn't realize how much until now.
    I was busy with other things so I didn't retest HighDPI on Windows 8.1, and I thought that only users that have monitors with different DPI would be affected by it.

    ReplyDelete
  35. Windows 8.1 Per-Monitor DPI support cannot be implemented without hacking through VCL and FMX TScreen and TForm classes so I added following QC report for the issue.
    http://qc.embarcadero.com/wc/qcmain.aspx?d=124640

    ReplyDelete
  36. The issue of form scaling is a limited solution, so long as font sizes are expressed in integer points. The difficulty is that the incremental changes are large percentages where you need the smallest steps. 

    I thought in looking at C# and in .NET in general, that we would finally move to points as floats, but apparently not.

    Lacking the more general solution, forms with the sort of complexity I am accustomed to working on (no big empty space like Word, but many controls) will be compromised, at best, unless supported by hand-tweaked code to adjust them.

    ReplyDelete

Post a Comment