LCL Internals - Resizing, Moving/fr

From Free Pascal wiki

English (en) français (fr)

Présentation

La bibliothèque LCL a beaucoup de propriétés de redimensionnement (Left, Width, Anchors, Align, AnchorSide, AutoSize, Constraints, ChildSizing, ...) et des hooks(points d'encrage) où les applications peut modifier le comportement (OnResize, OnChangeBounds, ...). Toutes ces choses ne peuvent pas être calculés en une seule étape, ainsi les commandes peuvent se déplacer énormément avant les coordonnées finales sortent . Pour réduire le scintillement la bibliothèque LCL n'envoit pas tous les déplacements ou redimensionnement à l'interface de la bibliothèque LCL. Par exemple, au cours des Begin/EndAlign et csLoading aucun move/resize est envoyée à l'interface. Le widgetset va essayer de suivre les conseils de la bibliothèque LCL, mais il y a quelques cas, où il ne les suit pas. Par exemple, les forms (fenêtres de haut niveau) sont limités 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 peu changer. Cela laisse la taille et la position du TGroupBox inchangé, mais l'espace client peut changer. 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, une 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, une message LM_MOVE est envoyé

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

Quand une form 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 courante (gauche et de 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ées par l'interface de la bibliothèque LCL pour réduire le scintillement en offrant de bonnes valeurs avant que la poignée soit créée.

GetWindowRelativePosition(Handle,NewLeft,NewTop)

Renvoie les Left, Top courant 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 quelle 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 leur propriétés Left,Top ne changent pas. Pour le faire défiler, utilise 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 au top, left de la poignée. En d'autres termes, c'est équivalent à:

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