Forum > LCL
Selective disabling of LCL Scaling
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