Sources :
TControl.Constraints
peut être utiliser pour définir les dimensions max et min d'un Control.
published property OnChange: TNotifyEvent; // [rw] Event handler for a change in the constraints. property MaxHeight: TConstraintSize; // [rw] The maximum height. property MaxWidth: TConstraintSize; // [rw] The maximum width. property MinHeight: TConstraintSize; // [rw] The minimum height. property MinWidth: TConstraintSize; // [rw] The minimum width. end;
Un exemple d'utilisation est donné ci-dessous dans la section AdjustClientRect
Source : https://lazarus-ccr.sourceforge.io/docs/lcl/controls/tcontrol.getlogicalclientrect.html
La fonction TControl.GetLogicalClientRect
a pour rôle d'obtenir les dimensions de la zone cliente d'un contrôle en tenant compte des coordonnées logiques. Cela signifie qu'elle retourne la zone disponible pour les composants enfants, excluant les bordures et autres éléments non-clients, en tenant compte des transformations ou des échelles logiques appliquées au contrôle.
Rôle de GetLogicalClientRect :
Source : https://lazarus-ccr.sourceforge.io/docs/lcl/controls/twincontrol.adjustclientrect.html
TWinControl.AdjustClientRect est une méthode appelée pour ajuster la zone cliente d'un contrôle fenêtré, c'est-à-dire l'espace disponible pour ses composants enfants. Elle permet de :
Les classes descendants peuvent redéfinir cette méthode pour modifier Rect, représentant la zone cliente, afin de gérer précisément l'espace intérieur du contrôle.
Exemple d'utilisation : Utiliser les Constraints
pour definir une largeur et hauteur minimale
type TMyControl = class(TWinControl) protected procedure AdjustClientRect(var Rect: TRect); override; //surcharge de la méthode end; procedure TMyControl.AdjustClientRect(var ARect: TRect); begin inherited AdjustClientRect(ARect); // Appeler la méthode héritée pour ajustements de base ARect.Height:=max(Constraints.MinHeight,ARect.Height); // Empêche la hauteur d'etre inferieur à la hauteur minimale contenue dans Contraints ARect.Width:=max(Constraints.MinWidth,ARect.Width); // Pareil pour la largeur end;
Comme indiqué dans le code, la méthode AdjustClientRect
est appelée fréquemment, donc n'y mettez pas de code coûteux, ou mettez en cache le résultat.
{------------------------------------------------------------------------------ TWinControl AdjustClientRect ------------------------------------------------------------------------------} procedure TWinControl.AdjustClientRect(var ARect: TRect); begin // Can be overriden. // It's called often, so don't put expensive code here, or cache the result end;
function TControl.GetBoundsRect: TRect; begin Result.Left := FLeft; Result.Top := FTop; Result.Right := FLeft+FWidth; Result.Bottom := FTop+FHeight; end;
{------------------------------------------------------------------------------ function TControl.ClientToScreen(const APoint: TPoint): TPoint; ------------------------------------------------------------------------------} function TControl.ClientToScreen(const APoint: TPoint): TPoint; var P : TPoint; begin P := ClientOrigin; Result.X := APoint.X + P.X; Result.Y := APoint.Y + P.Y; end; function TControl.ClientToScreen(const ARect: TRect): TRect; var P : TPoint; begin P := ClientToScreen(Point(0, 0)); Result := ARect; Result.Offset(P); end;
En surchargeant la function :function TWinControl.AutoSizeDelayed: boolean;
on peut bloquer le redimensionnement.
Je pense qu'il faut aussi surcharger : AutoSizeDelayedReport
et AutoSizeDelayedHandle
{------------------------------------------------------------------------------ function TWinControl.AutoSizeDelayed: boolean; ------------------------------------------------------------------------------} function TWinControl.AutoSizeDelayed: boolean; begin Result:=(csDestroyingHandle in ControlState) or (inherited AutoSizeDelayed); end; function TWinControl.AutoSizeDelayedReport: string; begin if csDestroyingHandle in ControlState then Result:='csDestroyingHandle' else Result:=inherited AutoSizeDelayedReport; end; {------------------------------------------------------------------------------ TWinControl AutoSizeDelayedHandle Returns true if AutoSize should be skipped / delayed because of its handle. A TWinControl needs a parent handle. ------------------------------------------------------------------------------} function TWinControl.AutoSizeDelayedHandle: Boolean; begin Result := (Parent = nil) and (ParentWindow = 0); end;
AddHandlerOnResize
, une logique permettant à un contrôle personnalisé de répondre aux événements de redimensionnement de son Parent.SetParent
, lorsqu'un changement de parent a lieu, il désinscrit l'ancien parent des événements de redimensionnement et inscrit le nouveau parent, garantissant ainsi que OnParentResizeHandler
est appelé chaque fois que le parent est redimensionné.TMyControl = class(TCustomControl) private procedure OnParentResizeHandler(Sender: TObject); protected procedure SetParent(NewParent: TWinControl); override; public ... end; procedure TMyControl.OnParentResizeHandler(Sender: TObject); begin Debugln('%s.OnParentResizeHandler PWith[%d]', [Name, Parent.ClientWidth]); end; procedure TMyControl.SetParent(NewParent: TWinControl); var vOldParent: TWinControl; begin vOldParent := Parent; inherited SetParent(NewParent); if Parent <> vOldParent then begin if assigned(vOldParent) then vOldParent.RemoveHandlerOnResize(@OnParentResizeHandler); if assigned(Parent) then Parent.AddHandlerOnResize(@OnParentResizeHandler, False); end; end;
protected procedure WndProc(var TheMessage: TLMessage); override; ... procedure TMyControl.WndProc(var TheMessage: TLMessage); var vWMSize: TWMSize; begin inherited WndProc(TheMessage); if TheMessage.Msg = WM_SIZE then begin vWMSize := TWMSize(TheMessage); DebugLn('%s.WndProc : Le parent a été redimensionné, SizeType[%d] H[%d] W[%d]', [Name, vWMSize.SizeType, vWMSize.Height, vWMSize.Width]); // Le parent a été redimensionné // Implémenter ici la logique de redimensionnement du contrôle end; end;
le paramétre SizeType peut avoir les valeurs suivantes :
{ WM_SIZE message } SIZE_MAXHIDE = 4; SIZE_MAXIMIZED = 2; SIZE_MAXSHOW = 3; SIZE_MINIMIZED = 1; SIZE_RESTORED = 0;
Il peut arriver que les valeurs soit :
SizeType = 6
procedure TWinControl.SendMoveSizeMessages(SizeChanged, PosChanged: boolean); begin ... with SizeMsg do begin Msg := LM_SIZE; SizeType := 6; // force realign ... Width := FWidth; Height := FHeight; ... WindowProc(TLMessage(SizeMsg)); end;