Jump to content
John Dorlon

TVirtualStringTree and DPI Awareness=GDI Scaling

Recommended Posts

Hello,

 

  I am using Delphi version 11.1  and TVirtualStringTree version 7.6.1.

 

  I have created a very simple test project, just dropping a TEdit and TVirtualStringTree on a form, adding a node to VST so it paints some text.

 

  When I set project options -> DPI Awareness to "GDI scaling" and run my project on a 4K display with 200% scaling, the VST shows pixelated and the TEdit shows it smooth.    

 

  In my "real" app, almost all controls show the text smoothly, but VST does not.     Does anyone know why?

 

I have attached a sample app and some screen shots.

 

Thanks.

 

John

 

 

  

project1.zip

Share this post


Link to post

With GDI Scaling - controls don't really do anything special - the OS is doing the scaling - it's not really the best option here. VST uses small bitmaps - which when scaled will look pretty poor - VST has no idea the OS is scaling things.  

 

I would go with Per Monitor V2 - which VST does support quite well (I use it and did some of the work on VST high dpi support) - it knows when scaling happens and it can redraw things like the arrow bitmaps rather than scale them.  

Share this post


Link to post

Hi Vincent,

 

  Thank you for the reply.  I first tried with Per Monitor V2, but my app (with hundreds of forms) is MDI.   In general, I got the app looking good right by setting the ParentFont and Scaling props.   But we've also got all combinations of imbedded forms, docked forms, fsStayOnTop, and I had a long list of problems to fix.  For example, a particular form looks great as a normal MDI Child, but when the same form is embedded in a fsStayOnTop form, everything is too small.  With GDI, I just have 2 problems to fix.  VST and images (which are the right size, just pixely)

 

  Back to GDI - I see what you mean about the bitmaps.  I found them in the TBaseVirtualTree.PaintTree procedure.   If I include poUnbuffered in the PaintOptions, then I see it painting smoothly.  Of course, that makes it flicker too.  I wonder if there is any other way to prevent flicker.  Maybe we could use a TControlCanvas instead of NodeBitmap.Canvas?   Or maybe there is some way to get the OS to scale on NodeBitmap's canvas?

 

Thanks for all your contributions to the Delphi world.  

 

-John

Edited by John Dorlon

Share this post


Link to post

Hi again Vincent.

 

I think I solved it by using a TControlCanvas for the buffering instead of TBitmap.Canvas.  This code scales the text nicely under GDI Scaling.

 

I only changed TBaseVirtualTree.PaintTree.  You can search for "Dorlon" to see my changes, and I left the old code there, commented out.   Please let me know what you think.


Thanks again

 

John

 

Edit:  

   Hmm, actually, this change is only fine and not flickery when I mouse over nodes.  When I mouse over the column headers, the nodes flicker and look like they are painted twice with a small offset the 2nd time.  😞   I think I'm getting close though.

 

TBaseVirtualTree.PaintTree.pas

Edited by John Dorlon

Share this post


Link to post

Hello John,

I've tried your code but I get some side effects like black rows, bad row separators and wrong scrollbars:

 

image.png.33267d582109342698829f5d5cec57c6.png

 

image.png.c37c0d3da280fa2cc0f3d245466c5863.png

 

image.png.e3d5cca59cc30598ac06fbb9281c43a2.png

 

Do you have any improved version? Thank you very much in advance.

 

Regards,

Jaroslaw

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×