Dessin des Controls

Méthode PAINT

Quand est appelée PAINT ?

La méthode Paint d'un TControl est appelée dans plusieurs circonstances liées à la nécessité de redessiner l'interface utilisateur. Voici les principaux moments où cette méthode est appelée :

1. Lors de la création du contrôle : Quand un contrôle est créé pour la première fois, la méthode `Paint` est appelée pour dessiner l'apparence initiale du contrôle.

2. Lors d'un rafraîchissement ou d'une invalidation : Si le contrôle est explicitement invalidé en appelant la méthode `Invalidate` ou `Repaint`, le système de rendu de Windows planifie un message de peinture, et la méthode `Paint` sera appelée pour redessiner le contrôle.

3. Lorsqu'une partie du contrôle est recouverte puis découverte : Par exemple, si une autre fenêtre recouvre partiellement le contrôle, puis est déplacée, la méthode `Paint` sera appelée pour redessiner la partie découverte.

4. Lors de la redimensionnement du contrôle : Si les dimensions du contrôle changent (par exemple, si l'utilisateur redimensionne la fenêtre contenant le contrôle), la méthode `Paint` est appelée pour ajuster et redessiner le contenu en fonction des nouvelles dimensions.

5. Lors du défilement (scrolling) : Si le contrôle est dans une zone défilable et que le contenu est déplacé par défilement, `Paint` peut être appelée pour dessiner les nouvelles parties du contrôle qui deviennent visibles.

6. Lors du changement de style ou de propriétés visuelles : Si certaines propriétés visuelles du contrôle changent (comme la couleur, le style de police, etc.), la méthode `Paint` est appelée pour redessiner le contrôle avec les nouvelles propriétés.

La méthode `Paint` fait partie du cycle de peinture des contrôles dans l'API Windows. C'est une méthode clé pour assurer que les contrôles graphiques sont correctement affichés à l'écran, réagissant aux changements de l'état visuel ou de la disposition du formulaire.

Bloquer l'affichage du control lors d'un Update

Il est possible que l'on ai besoin de “figer” le contrôle, lorsque l'on met a jour ses enfants par exemple, pour éviter le scintillement de celui-ci.

Malheureusement, TControl, n'implemente pas BeginUpdate et EndUpdate.

par SendMessage

Source : https://stackoverflow.com/questions/3792217/how-can-i-disable-screen-update-which-updating-a-lot-of-controls

Non tésté !
begin
  // Defer updates
  SendMessage(Handle, WM_SETREDRAW, WPARAM(False), 0);
  try
    // Create all your controls here
  finally
    // Make sure updates are re-enabled
    SendMessage(Handle, WM_SETREDRAW, WPARAM(True), 0);
    // Invalidate;  // Might be required to reflect the changes  
  end;
end;

via LockWindowUpdate

Source : https://forum.lazarus.freepascal.org/index.php?topic=43638.0

LockWindowUpdate(Control.Handle);
try
  //...
finally
  LockWindowUpdate(0);
end;

ControlStyle et "transparence"

Pour qu'un control puisse prendre la couleur du Parent, il faut definir : ParentColor et ControlStyle

  ParentColor:=true;
  ControlStyle := ControlStyle + [csOpaque];
  Canvas.Pen.Color:=clWhite;
  canvas.Pen.Style:=psDot;
  Canvas.Frame(vRect);

TControlBorderSpacing

TControlBorderSpacing est une classe utilisée pour gérer l'espacement autour d'un contrôle.
Elle est particulièrement utile pour définir les marges (espace vide) entre un contrôle et les autres contrôles environnants, ou entre un contrôle et les bords de son conteneur parent.

Rôle de TControlBorderSpacing

Le rôle principal de TControlBorderSpacing est de fournir une manière standard et flexible de gérer les marges d'un contrôle. Cela permet de s'assurer qu'un contrôle n'est pas collé directement à d'autres contrôles ou aux bords de son conteneur, améliorant ainsi l'apparence visuelle et l'organisation de l'interface utilisateur.

Propriétés principales de TControlBorderSpacing

Voici les propriétés les plus courantes de TControlBorderSpacing :

  • Around : Définit l'espace autour du contrôle, c'est-à-dire une marge uniforme de tous les côtés (haut, bas, gauche, droite).
  • Top : Spécifie la marge au-dessus du contrôle.
  • Bottom : Spécifie la marge en dessous du contrôle.
  • Left : Spécifie la marge à gauche du contrôle.
  • Right : Spécifie la marge à droite du contrôle.
  • InnerBorder : Détermine l'espace intérieur autour du contrôle lui-même, souvent utilisé dans des conteneurs pour créer un padding (remplissage interne).
  • OuterBorder : Contrôle l'espace extérieur autour du contrôle.

Exemple d'utilisation

Supposons que vous ayez un TButton placé dans un TPanel, et que vous souhaitiez ajouter un espace de 10 pixels autour du bouton pour qu'il ne touche pas directement les bords du panneau. Vous pourriez configurer TControlBorderSpacing comme suit :

Button1.BorderSpacing.Around := 10;

Ou, pour spécifier des marges différentes pour chaque côté :

Button1.BorderSpacing.Left := 5;
Button1.BorderSpacing.Top := 10;
Button1.BorderSpacing.Right := 5;
Button1.BorderSpacing.Bottom := 10;

En utilisant TControlBorderSpacing, vous pouvez contrôler précisément l'espacement des contrôles dans une interface utilisateur, ce qui est particulièrement utile lorsque vous travaillez avec des layouts dynamiques ou des interfaces utilisateur complexes.

Savoir quelle partie (TRect) du Control est affiché

La fonction TMyControl.GetVisibleRect ci-dessous calcule la partie visible d'un contrôle personnalisé sous forme d'un TRect, en tenant compte des limites imposées par ses parents dans la hiérarchie visuelle.
Elle traverse tous les parents du contrôle, réduisant progressivement le rectangle visible à l'intersection avec chaque parent. Le résultat est le rectangle visible final en coordonnées locales, retourné par la fonction.

function TMyControl.GetVisibleRect: TRect;
var
  vParent: TWinControl;
  vRect, vParentRect: TRect;
  vP:      TPoint;
begin
  assert(assigned(Parent));
 
  vRect := BoundsRect; // Le TControl en entier, pas juste ClientRect
  if assigned(Parent) then
  begin
    vParent := Parent;
    vP      := ControlOrigin;
    vRect.Offset(vP);
 
    { On scan tous les Parents }
    while assigned(vParent) and not (vRect.IsEmpty) do
    begin
      vParentRect := vParent.ClientToScreen(vParent.ClientRect);
      vRect       := vRect.Intersect(vRect, vParentRect);
      vParent     := vParent.Parent;
    end;
 
    if not vRect.IsEmpty then vRect.Offset(-vP.X, -vP.y);
 
  end;
 
  Result := vRect;
 
end;

Utilité de la fonction TMyControl.GetVisibleRect

La fonction `TMyControl.GetVisibleRect` permet de déterminer quelle partie d'un contrôle est réellement visible à l'écran, en tenant compte des limitations imposées par ses parents dans la hiérarchie des contrôles.

Contexte d'utilisation

  • Rendu graphique : Identifie quelles portions du contrôle doivent être redessinées en fonction de leur visibilité.
  • Détection de clics : Vérifie si une interaction utilisateur, comme un clic, se produit dans une zone visible du contrôle.
  • Optimisation : Aide à concentrer les ressources sur la partie visible du contrôle pour améliorer les performances.

Autres applications

  • Défilement automatique : Lorsqu'un contrôle est contenu dans un `ScrollBox`, la fonction aide à gérer le défilement en ajustant dynamiquement la partie visible.
  • Animations ou effets visuels : Pour des effets qui doivent se limiter aux zones visibles, cette fonction garantit que seules les parties pertinentes du contrôle sont affectées.
  • Validation et gestion des collisions : Dans des applications comme les jeux ou les simulations, elle peut servir à déterminer les parties visibles d'un objet pour des vérifications ou interactions précises.
Vous pourriez laisser un commentaire si vous étiez connecté.