[Lazarus] Zooming a form

Mattias Gaertner nc-gaertnma at netcologne.de
Tue Jun 21 13:45:19 CEST 2016


On Tue, 21 Jun 2016 04:05:04 +0200
Martin Grajcar <maaartinus at gmail.com> wrote:

>[...]Despite that, it works fine for all controls with Anchors
> = [akLeft, akTop]. For controls with other anchors, nothing works[...]
> The problem seems to lie in TControl.UpdateBaseBounds when
> the FBaseParentClientSize gets stored, which happens to be (0, 0) at this
> point. If I hack it to keep the previously stored value, it somehow works.

BoundsRect (Left,Top,Width,Height) is the current position/size.

When a form's width is changed the LCL has to adapt the right anchored
controls - aka changing the Left so that the distance of the right
side is restored. The right distance is computed from BaseBounds
and BaseParentClientSize.

BaseBounds/BaseParentClientSize is set when you call SetBounds (e.g.
when setting Left, Top, Width, Height). When the LCL computes the
autosized values it calls SetBoundsKeepBase, so it changes
BoundsRect and keeps BaseBounds/BaseParentClientSize.


> The zero-client-size parent is a TPage, but I can't claim it guilty as I
> couldn't reproduce my problem in a small example.

Do you mean it does work in a small example, but it does not in your
complex application?

 
> So I wonder:
> 
>    - Is it forbidden to change position and/or size of a component when
>    it's not shown?

It is allowed and a pretty normal thing.

>    - If not, how can I deal with right-aligned controls? Simply setting
>    c.Left := c.Left * Factor doesn't seem to work (though it should as in this
>    step all positions and all sizes simply get scaled up; anchoring is used
>    when the parent resizes and not the component itself, right?).

Maybe you forget to disable the autosize updates during the changes?

Simple example:

MainControl.DisableAlign;
try
  MainControl.SetBounds(Width*f,Height*f);
  for aControl in List do
    aControl.SetBounds(aControl.Left*f,aControl.Top*f,aControl.Width*f,aControl.Height*f);
finally
  MainControl.EnableAlign;
end;

Note: This algorithm has rounding errors, so multiple zooms will
destroy your layout.


Mattias



More information about the Lazarus mailing list