2015-11-15 4 views
1

J'ai entendu dire que l'application Delphi utilise le «chargement paresseux», en reportant le chargement des composants de formulaire jusqu'à ce qu'ils soient réellement référencés. Il a été mentionné dans another post - "C'est pourquoi nous avons changé TPageControl pour être paresseux - la boîte de dialogue d'options de l'IDE Delphi prenait trop de temps à charger!" Je suppose que cela s'applique aussi aux applications créées avec Delphi, mais je ne trouve aucune mention de chargement paresseux dans les sources VCL, suggérant peut-être que ça s'appelle quelque chose d'autre s'il existe. Dans les cas où, en utilisation normale, une application est démarrée rarement et dure longtemps, il peut être souhaitable de renoncer à un temps de démarrage plus rapide et d'avoir une peinture plus rapide des composants VCL lorsqu'ils sont réellement utilisés pour la première fois.Delphi - est-il possible de désactiver le chargement paresseux de formulaires de Delphi?

Est-ce que le programmeur Delphi a un contrôle sur cela? (LazyLoad := false ; ne fonctionne pas ;-)

+0

Lire la réponse de Danny Thorpe plus attentivement dans le lien posté. Il se réfère à un * contrôle spécifique * (TPageControl) et au comportement modifié. Il ne dit rien sur l'application * Delphi *. Même la partie que vous avez (incorrectement) cité indique * TPageControl * et pas * les applications Delphi en général *. Le * chargement paresseux * pour les applications Delphi en général ne crée pas de formulaires tant que vous n'en avez pas besoin (IOW, n'utilisez pas les formulaires créés automatiquement). Avez-vous un problème * spécifique * que vous essayez de résoudre? –

+0

@Ken Danny parlait de la création de fenêtre VCL à la demande. –

+0

@ross Je ne suis pas au courant de la création de fenêtre VCL sur demande étant un problème. Avez-vous un exemple? –

Répondre

5

Considérons le projet de démonstration simple:

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. 

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

Lorsque vous exécutez cela, la fenêtre de console dit:

 
Window created: Button1 

Lorsque vous sélectionnez chaque page à son tour, les autres boutons sont créés, comme indiqué dans la fenêtre de la console:

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

Modifiez maintenant le gestionnaire d'événements OnCreate pour forcer la visibilité de chaque page lors de la création du formulaire:

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; 

Maintenant, quand la forme est d'abord affiché, la fenêtre de la console lit:

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

En effet, comme le dit Danny, les fenêtres ne sont pas créés jusqu'à ce qu'ils soient présentés.

Maintenant, la nuance en ce qui concerne les contrôles de page est la gestion de la visibilité des pages. Le constructeur de TTabSheet contient ceci:

Visible := False; 

En outre, la propriété Visible de TTabSheet est publié comme ceci:

property Visible stored False; 

Cela signifie que lorsqu'un contrôle de page commence sa vie, ses pages sont cachées, dans le sens VCL d'avoir Visible égal à False. Comme l'a dit Danny, les contrôles de fenêtre sont d'abord créés lorsqu'un contrôle est affiché.Cela se produit à l'intérieur TWinControl.UpdateShowing qui commence comme ceci:

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; 

Les pages commencent à ne pas montrer, et puis quand ils deviennent actifs dans TPageControl.ChangeActivePage ce qui suit est exécuté pour la nouvelle page actif:

Page.BringToFront; 
Page.Visible := True; 

Réglage VisibleTrue entraîne l'exécution de TWinControl.UpdateShowing et la création du handle de fenêtre.

Et c'est pourquoi l'astuce ci-dessus de rendre toutes les pages visibles au moment de la création de la forme a l'effet que vous désirez. Maintenant, tout ce qui précède est très centré sur le contrôle des pages. Pour de nombreux autres contrôles, la fenêtre est d'abord créée lorsque le formulaire est créé, si le contrôle est visible. Si vous avez un problème spécifique avec un formulaire spécifique, il serait préférable de partager les détails spécifiques.