Différences
Ci-dessous, les différences entre deux révisions de la page.
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(Sender: TObject); | + | |
- | protected | + | |
- | procedure SetParent(NewParent: TWinControl); override; | + | |
- | public ... | + | |
- | end; | + | |
+ | </code> | ||
+ | ==== TControl.ClientToScreen ==== | ||
- | procedure TMyControl.OnParentResizeHandler(Sender: TObject); | + | <code pascal> |
+ | {------------------------------------------------------------------------------ | ||
+ | function TControl.ClientToScreen(const APoint: TPoint): 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(NewParent: TWinControl); | + | function TControl.ClientToScreen(const ARect: TRect): TRect; |
var | var | ||
- | vOldParent: TWinControl; | + | P : TPoint; |
begin | begin | ||
- | vOldParent := Parent; | + | P := 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> | ||
+ | |||
+ | |||
+ | |||