2015-11-15 108 views
1

我听说德尔福应用程序使用“懒加载”,推迟表单组件的装载,直到他们实际上引用。它在another post中提到 - “这就是为什么我们将TPageControl更改为延迟加载 - Delphi IDE的选项对话框加载时间过长!”德尔福 - 是否有可能禁用Delphi的延迟加载形式?

我认为这也适用于用Delphi创建以及应用程序,但我找不到在VCL源延迟加载任何提及,这也许就是所谓的别的东西,如果它确实存在。

在正常使用情况下,应用程序不经常启动并且运行很长时间的情况下,可能需要放弃更快的启动时间,并且在第一次实际使用VCL组件时可以更快地进行绘制。

请问Delphi程序员都在这个任何控制? (LazyLoad := false ;没有工作;-)

+0

阅读Danny Thorpe的回答,在发布的链接中更仔细。它指的是*特定控件*(TPageControl)和修改的行为。它没有说关于* Delphi应用程序*的任何信息。即使你(不准确)引用的部分说* TPageControl *而不是*一般的Delphi应用*。一般来说,Delphi应用程序的* lazy loading *不会创建表单直到你需要它们(IOW,不要使用自动创建的表单)。你有没有解决特定问题? –

+0

@Ken Danny正在谈论VCL按需创建窗口。 –

+0

@ross我不知道按需创建VCL窗口是一个问题。你有一个例子吗? –

回答

5

考虑以下的简单示范项目:

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; 

此外,TTabSheetVisible财产公布如下:

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执行,并且窗口句柄被创建。

这就是为什么在表单创建时使所有页面可见的技巧具有您所期望的效果。

现在,以上所有内容都是以页面控制为中心的。对于许多其他控件,窗体首先在创建窗体时创建,如果控件可见。如果您对特定表单有特定问题,那么最好分享具体的详细信息。