Forum > LCL

Selective disabling of LCL Scaling

(1/3) > >>

simsee:
My question arises, in part, from another thread I started (https://forum.lazarus.freepascal.org/index.php/topic,64696.0.html).

In an application I use a TScrollBox with dynamically created TGraphicControl instances inside. I need the coordinates (Left,Top) of these objects not to change when the PPI changes. In other words, I should disable LCLScaling. I know you can do this globally at the application level with TApplication.Scaled, but I want to disable automatic scaling only for specific controls, not for all those in the application. It's possible? Thank you.

wp:

--- Quote from: simsee on October 31, 2023, 04:32:06 pm ---In an application I use a TScrollBox with dynamically created TGraphicControl instances inside. I need the coordinates (Left,Top) of these objects not to change when the PPI changes. In other words, I should disable LCLScaling.

--- End quote ---
I don't understand: When you create a control a runtime and you place it at Left = 100, it will always be at Left =100 no matter what the current resolution is. LCLScaling is executed only when a form is loaded from lfm, or when the resolution of the monitor changes at runtime (in some modes), and only for those controls which handle the resolution change in their DoAdjustLayout method.

To my knowledge it is not possible to exclude some specific controls from LCLScaling. At form level, however, this is possible by switching the Scaled property of the form to false.

Even if it were possible to exclude controls from LCLScaling there is the issue that these controls would become super-small when your application runs on a super-high-res monitor... Are you sure that your scrollbox handles LCL scaling for its child controls correctly? What do you want to achieve?

Here is an excerpt from the wiki page on high-dpi (https://wiki.lazarus.freepascal.org/High_DPI#High_DPI_in_Lazarus_1.8_and_above)

--- Quote ---If you create controls run-time, scale all coordinates, sizes etc that have to be DPI-aware with TControl.Scale96ToForm() or ScaleDesignToForm() (depending on your choice of default PPI) or prepare your container (e.g. panel with controls) as it was with 96 PPI and then call TControl.AutoAdjustLayout(lapAutoAdjustForDPI, 96, ParentFormOfTheContainer.PixelsPerInch, 0, 0);
--- End quote ---

jamie:
its possible that his control has been installed and he just does a drop on it.


in the control class override the "ChangeScale" procedure. each control living on a form will receive that call while scaling is taking place.

 when you override it,  you can either ignore the inherited or just pass it two equal values do it does nothing .

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls; type TShape = Class(ExtCtrls.TShape)   Procedure ChangeScale(A,B:Integer); Override; end;   { TForm1 }   TForm1 = class(TForm)    Shape1: TShape;    procedure Shape1MouseUp(Sender: TObject; Button: TMouseButton;      Shift: TShiftState; X, Y: Integer);  private   public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Shape1MouseUp(Sender: TObject; Button: TMouseButton;  Shift: TShiftState; X, Y: Integer);begin  ScaleBy(96,98);end; procedure TShape.ChangeScale(A,B:Integer);Begin  A:=96; B:=96;  Inherited;  Beep;end; end. 

simsee:
Thank you for the precious information, on the basis of which I am making some reflections.


--- Quote from: wp on October 31, 2023, 05:23:11 pm ---I don't understand: When you create a control a runtime and you place it at Left = 100, it will always be at Left =100 no matter what the current resolution is.

--- End quote ---

Consider the attached project (coming from my other thread).

DesignTimePPI=96 -> Left=300 Top=300
DesignTimePPI=144 -> Left=200 Top=200

As a consequence, in the first case the rectangle line is not displayed.


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs; type   TGraph=TScrollBox;   { TForm1 }   TForm1 = class(TForm)    procedure FormCreate(Sender: TObject);  private    Graph : TGraph;  public   end;   { TGraphObject }   TGraphObject=class(TGraphicControl)    private      fGraphOwner : TGraph;    public      Pt1, Pt2 : TPoint;      constructor Create(Graph : TGraph; Rect : TRect); virtual; overload;      constructor Create(Graph : TGraph; X1,Y1,X2,Y2 : integer); virtual; overload;  end;   { TLine }   TLine=class(TGraphObject)    protected      procedure Paint; override;    public      constructor Create(Graph: TGraph; Rect: TRect); override; overload;      constructor Create(Graph : TGraph; X1,Y1,X2,Y2 : integer); override; overload;  end;  var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject);begin  Graph:=TGraph.Create(Self);  Graph.Parent:=Self;  Graph.Align:=alClient;  TLine.Create(Graph,Rect(200,200,300,400));end; { TGraphObject } constructor TGraphObject.Create(Graph: TGraph; Rect: TRect);begin  inherited Create(Graph);  fGraphOwner:=Graph;  Rect.NormalizeRect;  with Rect do    SetBounds(Left,Top,Width,Height);  Parent:=Graph;end; constructor TGraphObject.Create(Graph: TGraph; X1, Y1, X2, Y2: integer);begin  Create(Graph,Rect(X1,Y1,X2,Y2));end; { TLine } procedure TLine.Paint;begin  inherited;  writeln(Left,' ',Top);  Canvas.Line(Pt1.X-Left,Pt1.Y-Top,Pt2.X-Left,Pt2.Y-Top);end; constructor TLine.Create(Graph: TGraph; Rect: TRect);begin  inherited Create(Graph, Rect);  Pt1:=Rect.TopLeft;  Pt2:=Rect.BottomRight;end; constructor TLine.Create(Graph: TGraph; X1, Y1, X2, Y2: integer);begin  Create(Graph,Rect(X1,Y1,X2,Y2));end; end.

jamie:
@simsee

Look, I am not going to write it for you, I show you an example of using a Tshape to intercept the changescale process.

 You need to actually look at it and study it, it's simple, then when you figure it out, apply the same principle to your control.

It's as simple as that.

Navigation

[0] Message Index

[#] Next page

Go to full version