Reputation: 475
I have simple VCL form application in Delphi XE5. In the main form there are hudreds of TEdit components. Now I realized that setting visibility of all these edits is pretty slow. It takes ca 1 second on my computer while they are hidden/shown.
Please note that this is sample intended only for demostrate the issue. I know that this can be solved by inserting edits to a panel and hiding/showing the panel. But this is not possible in our application where edits are inserted to a form by an end user. Also we don't know which edits visibility will be controlled.
How to get it faster?
Note that when I use TLabel (TGraphicControl) instead of TEdit (TWinControl) then it is fast!
procedure TForm1.CheckBox1Click(Sender: TObject);
var
C: TControl;
i: Integer;
begin
for i := 0 to ControlCount - 1 do
begin
C := Controls[i];
if C.ClassName <> 'TCheckBox' then
C.Visible := CheckBox1.Checked;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
C: TEdit;
i: Integer;
j: Integer;
begin
for i := 0 to 60 do
for j := 0 to 20 do
begin
C := TEdit.Create(Self);
C.Width := 40;
C.Left := 20 + 50 * j;
C.Top := 50 + 25 * i;
C.Parent := Self;
end;
end;
Upvotes: 2
Views: 1815
Reputation: 613441
Your controls are parented directly by the form. Instead create a panel with alClient
align and set the panel's Parent
to be the form.
When you create the edit controls, make their Parent
be the panel. When you wish to hide the edit controls, hide the panel.
If you don't want to, or cannot, make such a drastic change, then you can batch the changes with BeginDeferWindowPos
, DeferWindowPos
and EndDeferWindowPos
. You might have code along these lines:
const
Flags = SWP_NOZORDER or SWP_NOOWNERZORDER or SWP_NOACTIVATE or SWP_NOSIZE or
SWP_NOMOVE or SWP_HIDEWINDOW;
var
i: Integer;
wpi: HDWP;
wnd: HWND;
begin
wpi := BeginDeferWindowPos(10);
Win32Check(wpi <> 0);
Try
for i := 1 to 10 do begin
wnd := (FindComponent('Edit' + IntToStr(i)) as TWinControl).Handle;
Win32Check(DeferWindowPos(wpi, wnd, 0, 0, 0, 0, 0, Flags) <> 0);
end;
Finally
Win32Check(EndDeferWindowPos(wpi));
End;
end;
Clearly you'll use a different mechanism to obtain your window handles, but I don't feel that detracts from this example.
Upvotes: 2