Delphi-是否可以禁用Delphi的表格延迟加载? [英] Delphi - is it possible to disable Delphi's lazy loading of forms?

查看:63
本文介绍了Delphi-是否可以禁用Delphi的表格延迟加载?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我听说Delphi应用程序使用延迟加载",将表单组件的加载推迟到实际引用它们之前.在另一篇文章中提到了-这就是我们改变的原因TPageControl会延迟加载-Delphi IDE的选项对话框加载时间太长!"

I've heard that the Delphi application uses "lazy loading", deferring the loading of form components until they are actually referenced. It was mentioned in another post - "That's why we changed TPageControl to be lazy-load - the Delphi IDE's options dialog was taking too long to load!"

我认为这也适用于用Delphi创建的应用程序,但是我在VCL源文件中找不到任何延迟加载的提示,这表明如果确实存在,它可能被称为其他名称.

I assume this applies to applications created with Delphi as well, but I can't find any mention of lazy loading in the VCL sources, suggesting maybe it's called something else if it does exist.

在正常使用情况下,应用程序很少启动并运行很长时间的情况下,可能希望放弃更快的启动时间,并在首次实际使用VCL组件时具有更快的绘制速度.

In cases where in normal use an application is started infrequently and runs for a long time, it might be desirable to forgo a faster startup time and have faster painting of VCL components when they are actually used for the first time.

Delphi程序员对此有控制权吗?( LazyLoad:= false; 无效;-)

Does the Delphi programmer have any control over this? (LazyLoad := false ; didn't work ;-)

推荐答案

请考虑以下简单的演示项目:

Consider the following simple demonstration project:

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.

Unit1.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

运行此命令时,控制台窗口会显示:

When you run this, the console window says:


Window created: Button1

依次选择每个页面时,将创建其他按钮,如控制台窗口所示:

As you select each page in turn, the other buttons are created, as shown in the console window:


Window created: Button1
Window created: Button2
Window created: Button3

现在更改 OnCreate 事件处理程序,以在创建表单时强制显示每个页面:

Now change the OnCreate event handler to force each page to be visible when the form is created:

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;

现在,当第一次显示表单时,控制台窗口显示为:

Now when the form is first shown, the console window reads:


Window created: Button1
Window created: Button2
Window created: Button3

这是因为,正如Danny所说的,只有在显示窗口之后才创建窗口.

This is because, as Danny says, the windows are not created until they are shown.

现在,关于页面控件的细微差别是对页面可见性的处理. TTabSheet 的构造函数包含以下内容:

Now, the nuance with regards page controls is the handling of visibility of the pages. The constructor of TTabSheet contains this:

Visible := False;

此外, TTabSheet Visible 属性是这样发布的:

Further, the Visible property of TTabSheet is published like this:

property Visible stored False;

这意味着当页面控件开始其生存之时,就其VCL而言,其 Visible 等于 False 意味着其页面是隐藏的.正如Danny所说,显示控件时首先创建窗口控件.发生在 TWinControl.UpdateShowing 内部,该过程如下所示:

That means that when a page control starts its life, its pages are hidden, in the VCL sense of having Visible equal to False. As Danny said, window controls are first created when a control is shown. That happens inside TWinControl.UpdateShowing which begins like this:

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 中变为活动状态时,将对新活动的页面执行以下操作:

The pages start out not showing, and then when they become active in TPageControl.ChangeActivePage the following is executed for the newly active page:

Page.BringToFront;
Page.Visible := True;

Visible 设置为 True 会导致执行 TWinControl.UpdateShowing ,并创建窗口句柄.

Setting Visible to True results in TWinControl.UpdateShowing executing, and the window handle being created.

这就是为什么上面提到的在表单创建时使所有页面可见的技巧具有您想要的效果的原因.

And that's why the trick above of making all the pages visible at form creation time has the effect you desire.

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

Now, all of the above is very page control centric. For many other controls, the window is first created when the form is created, if the control is visible. If you a specific problem with a specific form then it would be best to share the specific details.

这篇关于Delphi-是否可以禁用Delphi的表格延迟加载?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆