Difference between revisions of "LCL Internals - Resizing, Moving"
Line 1: | Line 1: | ||
− | = Overview = | + | == Overview == |
The LCL has a lot of resizing properties (Left, Width, Anchors, Align, AnchorSide, AutoSize, Constraints, ChildSizing, ...) and hooks where applications can alter the behavior (OnResize, OnChangeBounds, ...). All these things can not be calculated in one step, so controls can move quite a lot before the final coordinates come out. To reduce flickering the LCL does not send every move/resize to the LCL interface. For example during Begin/EndAlign and csLoading no move/resize is sent to the interface. The widgetset will try to follow the advices of the LCL, but there are some cases, where it does not follow. For example forms (top level windows) are limited by the window manager policies. And TPage completely depends on the size and theme of the TNotebook. | The LCL has a lot of resizing properties (Left, Width, Anchors, Align, AnchorSide, AutoSize, Constraints, ChildSizing, ...) and hooks where applications can alter the behavior (OnResize, OnChangeBounds, ...). All these things can not be calculated in one step, so controls can move quite a lot before the final coordinates come out. To reduce flickering the LCL does not send every move/resize to the LCL interface. For example during Begin/EndAlign and csLoading no move/resize is sent to the interface. The widgetset will try to follow the advices of the LCL, but there are some cases, where it does not follow. For example forms (top level windows) are limited by the window manager policies. And TPage completely depends on the size and theme of the TNotebook. | ||
− | = How the LCL tells the interface to resize/move a handle = | + | == How the LCL tells the interface to resize/move a handle == |
In TWinControl.DoSendBoundsToInterface the widget function SetBounds is called | In TWinControl.DoSendBoundsToInterface the widget function SetBounds is called | ||
TWSWinControlClass(WidgetSetClass).SetBounds(Self, Left, Top, Width, Height); | TWSWinControlClass(WidgetSetClass).SetBounds(Self, Left, Top, Width, Height); | ||
− | = How the Interface tells the LCL to resize/move a handle = | + | == How the Interface tells the LCL to resize/move a handle == |
− | == When the client area of a Handle was resized == | + | === When the client area of a Handle was resized === |
''Note'': If the theme changes the frame of a TGroupBox can change. This leaves the Size and Position of the TGroupBox unchanged, but the client area can change. The interface calls | ''Note'': If the theme changes the frame of a TGroupBox can change. This leaves the Size and Position of the TGroupBox unchanged, but the client area can change. The interface calls | ||
Line 16: | Line 16: | ||
and sends a LM_SIZE message as below. | and sends a LM_SIZE message as below. | ||
− | == When a Handle of a TWinControl was resized/moved == | + | === When a Handle of a TWinControl was resized/moved === |
− | === First the LCL interface send a LM_WINDOWPOSCHANGED message === | + | ==== First the LCL interface send a LM_WINDOWPOSCHANGED message ==== |
* x := Left (relative to 0,0 of client area of parent) | * x := Left (relative to 0,0 of client area of parent) | ||
* y := Top | * y := Top | ||
Line 24: | Line 24: | ||
* cy := Height | * cy := Height | ||
− | === Then a LM_SIZE message is sent === | + | ==== Then a LM_SIZE message is sent ==== |
* Width | * Width | ||
Line 30: | Line 30: | ||
* SizeType is a bit flag containing Size_SourceIsInterface plus one of the values SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN. | * SizeType is a bit flag containing Size_SourceIsInterface plus one of the values SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN. | ||
− | === Then a LM_MOVE message is sent === | + | ==== Then a LM_MOVE message is sent ==== |
* MoveType := Move_SourceIsInterface; | * MoveType := Move_SourceIsInterface; | ||
Line 36: | Line 36: | ||
* YPos := Top | * YPos := Top | ||
− | == When a form is maximized, minimized or restored the interface sends a LM_SIZE message == | + | === When a form is maximized, minimized or restored the interface sends a LM_SIZE message === |
* Width | * Width | ||
Line 42: | Line 42: | ||
* SizeType is a bit flag containing Size_SourceIsInterface plus one of the values SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN. | * SizeType is a bit flag containing Size_SourceIsInterface plus one of the values SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN. | ||
− | = How the LCL gets the current size / position of a LCL interface handle = | + | == How the LCL gets the current size / position of a LCL interface handle == |
− | == LCLIntf.GetWindowSize(Handle, InterfaceWidth, InterfaceHeight) == | + | === LCLIntf.GetWindowSize(Handle, InterfaceWidth, InterfaceHeight) === |
Returns the current width and height of a Handle. | Returns the current width and height of a Handle. | ||
− | == LCLIntf.GetClientRect(Handle, Result) == | + | === LCLIntf.GetClientRect(Handle, Result) === |
Returns the current width and height (left and top are always 0) of the client area of a Handle (= inner area inside the border/frame of a control). | Returns the current width and height (left and top are always 0) of the client area of a Handle (= inner area inside the border/frame of a control). | ||
− | == TWSWinControlClass(WidgetSetClass).GetDefaultClientRect(Self, Left, Top, Width, Height, Result) == | + | === TWSWinControlClass(WidgetSetClass).GetDefaultClientRect(Self, Left, Top, Width, Height, Result) === |
This function is called first by the LCL to get the ClientRect. If it returns false, the LCL will use GetClientRect if it has already created a handle, otherwise the values loaded from the .lfm. If all this fails, the default is Rect(0,0,Width,Height). | This function is called first by the LCL to get the ClientRect. If it returns false, the LCL will use GetClientRect if it has already created a handle, otherwise the values loaded from the .lfm. If all this fails, the default is Rect(0,0,Width,Height). | ||
GetDefaultClientRect can be used by the LCL interface to reduce flickering by providing good values before the handle is created. | GetDefaultClientRect can be used by the LCL interface to reduce flickering by providing good values before the handle is created. | ||
− | == GetWindowRelativePosition(Handle,NewLeft,NewTop) == | + | === GetWindowRelativePosition(Handle,NewLeft,NewTop) === |
Returns the current Left, Top of a Handle relative to the client area (0,0) of its parent. | Returns the current Left, Top of a Handle relative to the client area (0,0) of its parent. |
Revision as of 22:00, 31 July 2007
Overview
The LCL has a lot of resizing properties (Left, Width, Anchors, Align, AnchorSide, AutoSize, Constraints, ChildSizing, ...) and hooks where applications can alter the behavior (OnResize, OnChangeBounds, ...). All these things can not be calculated in one step, so controls can move quite a lot before the final coordinates come out. To reduce flickering the LCL does not send every move/resize to the LCL interface. For example during Begin/EndAlign and csLoading no move/resize is sent to the interface. The widgetset will try to follow the advices of the LCL, but there are some cases, where it does not follow. For example forms (top level windows) are limited by the window manager policies. And TPage completely depends on the size and theme of the TNotebook.
How the LCL tells the interface to resize/move a handle
In TWinControl.DoSendBoundsToInterface the widget function SetBounds is called
TWSWinControlClass(WidgetSetClass).SetBounds(Self, Left, Top, Width, Height);
How the Interface tells the LCL to resize/move a handle
When the client area of a Handle was resized
Note: If the theme changes the frame of a TGroupBox can change. This leaves the Size and Position of the TGroupBox unchanged, but the client area can change. The interface calls
LCLControl.InvalidateClientRectCache(false);
and sends a LM_SIZE message as below.
When a Handle of a TWinControl was resized/moved
First the LCL interface send a LM_WINDOWPOSCHANGED message
- x := Left (relative to 0,0 of client area of parent)
- y := Top
- cx := Width
- cy := Height
Then a LM_SIZE message is sent
- Width
- Height
- SizeType is a bit flag containing Size_SourceIsInterface plus one of the values SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN.
Then a LM_MOVE message is sent
- MoveType := Move_SourceIsInterface;
- XPos := Left (relative to 0,0 of client area of parent)
- YPos := Top
When a form is maximized, minimized or restored the interface sends a LM_SIZE message
- Width
- Height
- SizeType is a bit flag containing Size_SourceIsInterface plus one of the values SIZENORMAL, SIZEICONIC, SIZEFULLSCREEN.
How the LCL gets the current size / position of a LCL interface handle
LCLIntf.GetWindowSize(Handle, InterfaceWidth, InterfaceHeight)
Returns the current width and height of a Handle.
LCLIntf.GetClientRect(Handle, Result)
Returns the current width and height (left and top are always 0) of the client area of a Handle (= inner area inside the border/frame of a control).
TWSWinControlClass(WidgetSetClass).GetDefaultClientRect(Self, Left, Top, Width, Height, Result)
This function is called first by the LCL to get the ClientRect. If it returns false, the LCL will use GetClientRect if it has already created a handle, otherwise the values loaded from the .lfm. If all this fails, the default is Rect(0,0,Width,Height). GetDefaultClientRect can be used by the LCL interface to reduce flickering by providing good values before the handle is created.
GetWindowRelativePosition(Handle,NewLeft,NewTop)
Returns the current Left, Top of a Handle relative to the client area (0,0) of its parent.