考虑以下的简单示范项目:
Project1.dpr
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Unit1.pas
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls;
type
TButton = class(Vcl.StdCtrls.TButton)
protected
procedure CreateWnd; override;
end;
TForm1 = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TButton.CreateWnd;
begin
inherited;
Writeln('Window created: ' + Name);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
AllocConsole;
end;
end.
1单元.dfm
object Form1: TForm1
Caption = 'Form1'
ClientHeight = 299
ClientWidth = 635
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object PageControl1: TPageControl
Left = 40
Top = 40
Width = 537
Height = 233
ActivePage = TabSheet1
object TabSheet1: TTabSheet
Caption = 'TabSheet1'
object Button1: TButton
Caption = 'Button1'
end
end
object TabSheet2: TTabSheet
Caption = 'TabSheet2'
object Button2: TButton
Caption = 'Button2'
end
end
object TabSheet3: TTabSheet
Caption = 'TabSheet3'
object Button3: TButton
Caption = 'Button3'
end
end
end
end
当你运行这个,控制台窗口说:
Window created: Button1
正如你依次选择每个页面的其他按钮创建,如在控制台窗口:
Window created: Button1
Window created: Button2
Window created: Button3
现在更改OnCreate
事件处理函数,以在创建窗体时强制每个页面可见:
procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
AllocConsole;
for i := 0 to PageControl1.PageCount-1 do begin
PageControl1.Pages[i].Visible := True;
end;
end;
现在,当第一次显示形式,控制台窗口上写着:
Window created: Button1
Window created: Button2
Window created: Button3
这是因为,正如丹尼说,没有创建的窗口,直到它们被显示。现在
,关于页面控件的细微差别是网页的能见度处理。的TTabSheet
构造函数包含此:
Visible := False;
此外,TTabSheet
的Visible
财产公布如下:
property Visible stored False;
这意味着,当一个页面控制开始它的生命,它的页面是隐藏的,在具有Visible
等于False
的VCL感。正如Danny所说,窗口控件首先在显示控件时创建。出现这种情况的内部TWinControl.UpdateShowing
这是这样开始的:
Page.BringToFront;
Page.Visible := True;
设置Visible
:
procedure TWinControl.UpdateShowing;
var
ShowControl: Boolean;
I: Integer;
begin
ShowControl := (FVisible and (not (csDesigning in ComponentState) or not (csDesignerHide in ControlState)) or
((csDesigning in ComponentState) and not (csDesignerHide in ControlState)) and
not (csNoDesignVisible in ControlStyle)) and
not (csReadingState in ControlState) and not (csDestroying in ComponentState);
if ShowControl then
begin
if WindowHandle = 0 then CreateHandle; // <-- this is the key
if FWinControls <> nil then
for I := 0 to FWinControls.Count - 1 do
TWinControl(FWinControls[I]).UpdateShowing;
end;
....
end;
的网页一开始不显示,然后当他们在TPageControl.ChangeActivePage
成为积极为新激活的页面,执行如下到True
导致TWinControl.UpdateShowing
执行,并且窗口句柄被创建。
这就是为什么在表单创建时使所有页面可见的技巧具有您所期望的效果。
现在,以上所有内容都是以页面控制为中心的。对于许多其他控件,窗体首先在创建窗体时创建,如果控件可见。如果您对特定表单有特定问题,那么最好分享具体的详细信息。
阅读Danny Thorpe的回答,在发布的链接中更仔细。它指的是*特定控件*(TPageControl)和修改的行为。它没有说关于* Delphi应用程序*的任何信息。即使你(不准确)引用的部分说* TPageControl *而不是*一般的Delphi应用*。一般来说,Delphi应用程序的* lazy loading *不会创建表单直到你需要它们(IOW,不要使用自动创建的表单)。你有没有解决特定问题? –
@Ken Danny正在谈论VCL按需创建窗口。 –
@ross我不知道按需创建VCL窗口是一个问题。你有一个例子吗? –