Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
prog:lazarus:classes:tcontrols:dimensions [27/08/2024 18:44]
thierry [Bloquer le redimensionnement]
prog:lazarus:classes:tcontrols:dimensions [02/09/2024 18:58] (Version actuelle)
thierry [TControl.BoundsRect]
Ligne 68: Ligne 68:
  
 </​code>​ </​code>​
-===== Capter le changement de Size du Parent ===== +==== TControl.BoundsRect ​==== 
-==== Parent.AddHandlerOnResize ​==== +<code pascal> 
-  * Le code ci-dessous met en place, grace a ''​AddHandlerOnResize'',​ une logique permettant à un contrôle personnalisé de répondre aux événements de redimensionnement de son Parent. +function TControl.GetBoundsRect:​ TRect; 
-  * Grace a la surcharge de la procédure ''​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é+begin 
-  ​* Cette fonctionnalité pourrait être utilisée pour ajuster dynamiquement le contrôle enfant en fonction des dimensions de son parent. +  ​Result.Left :FLeft; 
-  +  ​Result.Top ​:= FTop
-<code delphi>​ +  ​Result.Right ​:= FLeft+FWidth
-  TMyControl ​class(TCustomControl) +  ​Result.Bottom := FTop+FHeight;​ 
-  ​private +end;
-    procedure OnParentResizeHandler(SenderTObject)+
-  ​protected +
-    procedure SetParent(NewParentTWinControl);​ override+
-  ​public ..+
-  end;+
  
 +</​code>​
 +==== TControl.ClientToScreen ====
  
-procedure TMyControl.OnParentResizeHandler(SenderTObject);+<code pascal>​ 
 +{------------------------------------------------------------------------------ 
 +  function TControl.ClientToScreen(const APointTPoint): TPoint; 
 +------------------------------------------------------------------------------} 
 +function TControl.ClientToScreen(const APoint: TPoint): TPoint; 
 +var 
 +  P : TPoint;
 begin begin
-  ​Debugln('​%s.OnParentResizeHandler PWith[%d]',​ [Name, Parent.ClientWidth]);+  ​P := ClientOrigin;​ 
 +  Result.X := APoint.X + P.X; 
 +  Result.Y := APoint.Y + P.Y;
 end; end;
  
-procedure TMyControl.SetParent(NewParentTWinControl);+function TControl.ClientToScreen(const ARectTRect): TRect;
 var var
-  ​vOldParentTWinControl;+  ​TPoint;
 begin begin
-  ​vOldParent ​:= Parent; +  ​:= ClientToScreen(Point(0, 0)); 
-  inherited SetParent(NewParent); +  ​Result := ARect; 
-  ​if Parent <> vOldParent then +  ​Result.Offset(P); 
-  ​begin +end; 
-    if assigned(vOldParent) then +
-      vOldParent.RemoveHandlerOnResize(@OnParentResizeHandler); +
-    if assigned(Parent) then +
-      Parent.AddHandlerOnResize(@OnParentResizeHandler,​ False); +
-  ​end; +
-end;        ​+
 </​code>​ </​code>​
 +
 +
 +
 +
 ===== Redimensionnement (AutoSize) ===== ===== Redimensionnement (AutoSize) =====
 ==== Bloquer le redimensionnement ==== ==== Bloquer le redimensionnement ====
Ligne 139: Ligne 143:
 end;                                  ​ end;                                  ​
 </​code>​ </​code>​
 +
 +==== Capter le changement de Size du Parent ====
 +=== Avec le Handler OnResize du Parent ===
 +  * Le code ci-dessous met en place, grace a ''​AddHandlerOnResize'',​ une logique permettant à un contrôle personnalisé de répondre aux événements de redimensionnement de son Parent.
 +  * Grace a la surcharge de la procédure ''​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é.
 +  * Cette fonctionnalité pourrait être utilisée pour ajuster dynamiquement le contrôle enfant en fonction des dimensions de son parent.
 + 
 +<code delphi>
 +  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;        ​
 +</​code>​
 +=== Avec interception du message WM_SIZE ​ ===
 +<code pascal>
 +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;
 +
 +</​code>​
 +== TWMSize.SizeType ==
 +le paramétre SizeType peut avoir les valeurs suivantes :
 +<code pascal unit Windows (\fpc\3.2.2\source\rtl\win\wininc\defines.inc)>​
 +  { WM_SIZE message ​ }
 +     ​SIZE_MAXHIDE = 4;
 +     ​SIZE_MAXIMIZED = 2;
 +     ​SIZE_MAXSHOW = 3;
 +     ​SIZE_MINIMIZED = 1;
 +     ​SIZE_RESTORED = 0;
 +</​code>​
 +Il peut arriver que les valeurs soit : 
 +  * SizeType = 6 : Force le realignement (voir ci-dessous)
 +  * SizeType = 128 : JE NE SAIS PAS ???
 +
 +**SizeType = 6**
 +<code pascal unit Controls (\lcl\include\wincontrol.inc)>​
 +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;                                              ​
 +</​code>​
 +
 +
 +