考慮以下的簡單示範項目:
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窗口是一個問題。你有一個例子嗎? –