LCL Internals - Resizing, Moving/fr

From Lazarus wiki

English (en) français (fr)

Présentation

La bibliothèque LCL possède de nombreuses propriétés de redimensionnement (Left, Width, Anchors, Align, AnchorSide, AutoSize, Constraints, ChildSizing, ...) et des points d'ancrage (hooks)avec lesquels les applications peuvent modifier le comportement de l'application (OnResize, OnChangeBounds, ...). Comme tous ces éléments ne peuvent pas être calculés en une seule étape, les contrôles peuvent beaucoup se déplacer avant que les coordonnées finales ne soient disponibles. Pour réduire les risques de scintillement, la bibliothèque LCL n'envoie pas tous les déplacements ou redimensionnements à l'interface de la bibliothèque LCL. Par exemple, au cours des Begin/EndAlign et csLoading, aucun move/resize n'est envoyé à l'interface. Le widgetset va essayer de suivre les conseils de la bibliothèque LCL, mais il y a quelques cas où il ne le fera pas. Par exemple, les fiches(fenêtres de haut niveau) sont limitées par les politiques de gestion de fenêtres, et TPage dépend entièrement de la taille et du thème de TNotebook.

Comment la bibliothèque LCL indique à l'interface de redimensionner / déplacer une poignée(handle)

Dans TWinControl.DoSendBoundsToInterface la fonction widget SetBounds est appelée

 TWSWinControlClass(WidgetSetClass).SetBounds(Self, Left, Top, Width, Height);

Comment l'interface dit à la bibliothèque LCL de redimensionner / déplacer une poignée

Quand la zone client d'une poignée a été redimensionnée

Note: Si le thème change, le cadre d'un TGroupBox peut changer. Cela laisse la taille et la position du TGroupBox inchangées, mais ce n'est pas le cas pour l'espace client. L'interface appelle

 LCLControl.InvalidateClientRectCache(false);

et envoie un message LM_SIZE comme ci-dessous.

Quand une poignée d'un TWinControl a été redimensionnée / déplacée

Tout d'abord, l'interface de la bibliothèque LCL envoie un message LM_WINDOWPOSCHANGED

  • x := Left (par rapport à 0,0 de la zone cliente du parent)
  • y := Top
  • cx := Width
  • cy := Height

Ensuite, un message LM SIZE est envoyé

  • Width
  • Height
  • SizeType est un drapeau d'un bit contenant Size_SourceIsInterface plus une des valeurs SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN.

Ensuite, un message LM_MOVE est envoyé

  • MoveType := Move_SourceIsInterface;
  • XPos := Left (par rapport à 0,0 de la zone cliente du parent)
  • YPos := Top

Quand une fiche est à son maximum, minimisée ou restaurée, l'interface envoie un message LM_SIZE

  • Width
  • Height
  • SizeType est un drapeau d'un bit contenant Size_SourceIsInterface plus une des valeurs SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN.

Comment la bibliothèque LCL obtient la taille/la position de la poignée de l'interface de la bibliothèque LCL

LCLIntf.GetWindowSize(Handle, InterfaceWidth, InterfaceHeight)

Renvoie la largeur et la hauteur courante d'une poignée.

LCLIntf.GetClientRect(Handle, Result)

Retourne la largeur et la hauteur actuelles(gauche et haut sont toujours à 0) de la zone cliente d'une poignée (= zone intérieure à l'intérieur des frontières / cadre d'un contrôle).

TWSWinControlClass(WidgetSetClass).GetDefaultClientRect(Self, Left, Top, Width, Height, Result)

Cette fonction est appelée en premier lieu par la bibliothèque LCL pour obtenir le ClientRect. Si elle retourne false, la bibliothèque LCL va utiliser la fonction GetClientRect si une poignée a déjà été créée, sinon les valeurs chargées à partir du fichier .lfm. Si tout cela échoue, la valeur par défaut est Rect(0,0,Width,Height). GetDefaultClientRect peut être utilisée par l'interface de la bibliothèque LCL pour réduire le scintillement en offrant de bonnes valeurs avant que la poignée ne soit créée.

GetWindowRelativePosition(Handle,NewLeft,NewTop)

Renvoie les valeurs Left et Top actuelles d'une poignée relative à l'espace client (0,0) de son parent.

Contraintes

La bibliothèque LCL demande à l'interface les contraintes(min, max pour la largeur et la hauteur) avec la fonction

 GetControlConstraints

Par exemple: sous gtk, une barre de défilement horizontale a une hauteur fixe.

Taille préférée

Pour un redimensionnement automatique d'un contrôle (par exemple, un TButton ou un TLabel), la bibliothèque LCL demande à l'interface la taille minimale pour rendre le contrôle agréable :

 TWSWinControlClass(WidgetSetClass).GetPreferredSize(Self, PreferredWidth, PreferredHeight, WithThemeSpace);

Défilement

La bibliothèque LCL fait défiler les contrôles fils seulement virtuellement. Cela signifie que leurs propriétés Left et Top ne changent pas. Pour les faire défiler, utilisez la fonction d'interface

 TWSScrollingWinControlClass(WidgetSetClass).ScrollBy(Self, DeltaX, DeltaY);

Divers

LCLIntf.GetClientBounds(Handle,Result);

Retourne le rectangle du client qui n'a pas défilé par rapport aux propriétés Top et Left de la poignée. En d'autres termes, c'est équivalent à :

 CurClientBounds := GetClientRect(Handle)
 OffsetRect(CurClientBounds,FrameBorderLeft,FrameBorderTop);