Recent

Author Topic: Correct order in setting Parent and Align properties  (Read 266 times)

simsee

  • Full Member
  • ***
  • Posts: 194
Correct order in setting Parent and Align properties
« on: October 08, 2024, 05:29:10 pm »
As known, if Align is set to a value other than alNone or alCustom, the alignment is tied to the Parent control. This assumes that Parent is already assigned and, for this reason, in the case of dynamically created components, first I set Parent, then Align. But I noticed that sometimes this determines that for a very short period of time, the control appears before the alignment, creating an annoying visual effect. So what is the correct order to follow?

rvk

  • Hero Member
  • *****
  • Posts: 6575
Re: Correct order in setting Parent and Align properties
« Reply #1 on: October 08, 2024, 05:36:55 pm »
But I noticed that sometimes this determines that for a very short period of time, the control appears before the alignment, creating an annoying visual effect.
Where do you create those controls?
I normally do this in FormCreate and in that case the form isn't yet visible, so there is no annoying flicker.

Otherwise, if you REALLY need to do it later, you might first create the control with visible set to false.
And as a last resort, if you are on Windows, you have two options to freeze the screen or control (with LockWindowUpdate or SendMessage/WM_SETREDRAW).

simsee

  • Full Member
  • ***
  • Posts: 194
Re: Correct order in setting Parent and Align properties
« Reply #2 on: October 08, 2024, 06:26:44 pm »
Thanks rvk, your answer partially clarifies my doubt. I show an example to better explain the problem.

In the attached program, when I press the button, sometimes but not always, the dynamically created scrollbox appears for a moment in reduced size, before adapting to the size of the parent control. This is if in the Parent scrollbox it is set before Align. By reversing the order, the problem does not arise.

So my questions are: 1) why the unwanted visual effect described above appears randomly, not constantly; 2) if it is conceptually correct to set Align before Parent in a control.

I use the latest version of Lazarus in Windows 10 - 64 bit.

Thanks.

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, StdCtrls;
  9.  
  10. type
  11.  
  12.   { TScrollBox }
  13.  
  14.   TScrollBox=class(Forms.TScrollBox)
  15.     protected
  16.       procedure DoOnResize; override;
  17.   end;
  18.  
  19.   { TForm1 }
  20.  
  21.   TForm1 = class(TForm)
  22.     Button1: TButton;
  23.     PageControl1: TPageControl;
  24.     procedure Button1Click(Sender: TObject);
  25.   private
  26.     ScrollBox : TScrollBox;
  27.     TabSheet1 : TTabSheet;
  28.   public
  29.  
  30.   end;
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35. implementation
  36.  
  37. {$R *.lfm}
  38.  
  39. { TScrollBox }
  40.  
  41. procedure TScrollBox.DoOnResize;
  42. begin
  43.   inherited DoOnResize;
  44.   with HorzScrollBar do
  45.     begin
  46.       Page:=ClientWidth;
  47.       Range:=High(integer);
  48.       Increment:=ClientWidth div 16;
  49.     end;
  50.   with VertScrollBar do
  51.     begin
  52.       Page:=ClientHeight;
  53.       Range:=High(integer);
  54.       Increment:=ClientHeight div 16;
  55.     end;
  56. end;
  57.  
  58. { TForm1 }
  59.  
  60. procedure TForm1.Button1Click(Sender: TObject);
  61. begin
  62.   TabSheet1:=PageControl1.AddTabSheet;
  63.   ScrollBox:=TScrollBox.Create(TabSheet1);
  64.   ScrollBox.Parent:=TabSheet1;
  65.   ScrollBox.Align:=alClient;
  66.   ScrollBox.AutoScroll:=False;
  67.   ScrollBox.HorzScrollBar.Visible:=True;
  68.   ScrollBox.VertScrollBar.Visible:=True;
  69. end;
  70.  
  71. end.
  72.  
  73.  
« Last Edit: October 08, 2024, 06:30:25 pm by simsee »

rvk

  • Hero Member
  • *****
  • Posts: 6575
Re: Correct order in setting Parent and Align properties
« Reply #3 on: October 08, 2024, 06:56:59 pm »
In the attached program, when I press the button, sometimes but not always, the dynamically created scrollbox appears for a moment in reduced size, before adapting to the size of the parent control. This is if in the Parent scrollbox it is set before Align. By reversing the order, the problem does not arise.

So my questions are: 1) why the unwanted visual effect described above appears randomly, not constantly; 2) if it is conceptually correct to set Align before Parent in a control.
1. It depends on when this happens. If you first set align to client and then assign the parent, the control can be directly be created including the alignment. Otherwise you have a split second where the control is viewed in the normal state.

2. Yes. It should be ok the set Align before Parent.
I think in LCL the Parent is checked before anything is done to the parent during Align of it's sub-components.
So there are "if (Parent<>nil) then" checks for this in the source.

But... if you are under Windows and you want to freeze a control when you do visual stuff to it (that also works for filling the control) you can use LockWindowUpdate. It returns a boolean if the locking is successful. Don't forget to release the lock with NUL (0 in this case). Below I show this with a try/finally. I added a sleep(500) to make the problem more apparent.

Code: Pascal  [Select][+][-]
  1. uses Windows;
  2.  
  3. procedure TForm1.Button1Click(Sender: TObject);
  4. var
  5.   wl: boolean;
  6. begin
  7.   // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-lockwindowupdate
  8.   wl := LockWindowUpdate(PageControl1.Handle);
  9.   try
  10.     TabSheet1 := PageControl1.AddTabSheet;
  11.     ScrollBox := TScrollBox.Create(TabSheet1);
  12.     ScrollBox.Align := alClient;
  13.     ScrollBox.Parent := TabSheet1;
  14.     ScrollBox.AutoScroll := False;
  15.     ScrollBox.HorzScrollBar.Visible := True;
  16.     ScrollBox.VertScrollBar.Visible := True;
  17.   finally
  18.     if wl then LockWindowUpdate(0);
  19.   end;
  20. end;

 

TinyPortal © 2005-2018