考虑以下简单的演示项目:
项目1.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.
单元1.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
当你运行它时,控制台窗口会显示:
创建的窗口:Button1
当您依次选择每个页面时,会创建其他按钮,如控制台窗口所示:
创建的窗口:Button1
创建的窗口:Button2
创建的窗口: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;
现在,当表单首次显示时,控制台窗口显示:
创建的窗口:Button1
创建的窗口:Button2
创建的窗口:Button3
这是因为,正如 Danny 所说,在显示之前不会创建窗口。
现在,关于页面控件的细微差别是页面可见性的处理。的构造函数TTabSheet
包含以下内容:
Visible := False;
此外, 的Visible
属性TTabSheet
是这样发布的:
property Visible stored False;
这意味着当一个页面控件开始它的生命时,它的页面是隐藏的,在 VCL 意义上Visible
等于False
. 正如 Danny 所说,窗口控件是在显示控件时首先创建的。这发生在里面TWinControl.UpdateShowing
,开始是这样的:
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
,将对新活动页面执行以下操作:
Page.BringToFront;
Page.Visible := True;
设置Visible
为True
导致TWinControl.UpdateShowing
执行,并创建窗口句柄。
这就是为什么在表单创建时使所有页面可见的上述技巧具有您想要的效果。
现在,以上所有内容都非常以页面控制为中心。对于许多其他控件,如果控件可见,则在创建窗体时首先创建窗口。如果您对特定表格有特定问题,那么最好分享具体细节。