2016-05-12 5 views
1

heute habe ich eine Frage über Frames, die in Paketen sind. Ich habe ein Paket, das einen einfachen Rahmen enthält:Delphi erstellen Frame, der in einem Paket ist

unit fraMain; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
    System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, 
    Vcl.StdCtrls; 

type 

    TFrame1 = class(TFrame) 
    Label1: TLabel; 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

implementation 

{$R *.dfm} 

initialization 
    RegisterClass(TFrame1); 

finalization 
    UnRegisterClass(TFrame1); 

end. 

Ich habe das Paket und ein neues projexct erstellen, die sie verwenden. Das Projekt hat eine einfache Form und es ist Code ist dies:

unit main; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, 
    System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, 
    System.Actions, Vcl.ActnList, Vcl.PlatformDefaultStyleActnCtrls, Vcl.ActnMan, 
    Vcl.StdCtrls; 

type 
    TfrmMain = class(TForm) 
    mnuMain: TMainMenu; 
    mnuFile: TMenuItem; 
    mnuModuli: TMenuItem; 
    mFilCloseModules: TMenuItem; 
    mModModulo1: TMenuItem; 
    mModModulo2: TMenuItem; 
    N1: TMenuItem; 
    mFilExit: TMenuItem; 
    actManager: TActionManager; 
    actExit: TAction; 
    actModulo1: TAction; 
    actModulo2: TAction; 
    procedure actExitExecute(Sender: TObject); 
    procedure actModulo1Execute(Sender: TObject); 
    private 
    FPackageHandle: Integer; 
    public 
    { Public declarations } 
    end; 

const 
    DIRPACK1 = 'C:\Users...'; 

var 
    frmMain: TfrmMain; 

implementation 

{$R *.dfm} 


{ Chiusura applicazione } 
procedure TfrmMain.actExitExecute(Sender: TObject); 
begin 
    Application.Terminate; 
end; 

procedure TfrmMain.actModulo1Execute(Sender: TObject); 
var 
    AClass: TClass; 
    AFrame: TFrame; 
begin 
    if FPackageHandle = 0 then begin 
    FPackageHandle := LoadPackage(DIRPACK1 + 'Pack_01.bpl'); 
    AClass := GetClass('TFrame1'); 
    if AClass <> nil then begin 

    end; 
    end; 
end; 

end. 

Wo DIRPACK1 ist der Pfad, wo die BPL ist. In der Aktion "actModuloExecute" möchte ich den Rahmen erstellen. Wie Sie sehen können, bekomme ich die Klasse, aber nachdem ich nicht weiß, wie man den Rahmen instanziiert. Welches ist die Art und Weise, um den Rahmen zu erstellen?

+1

Warum laden Sie das Paket auf diese Weise? Das ist dein grundlegendes Problem. Laden Sie es dynamisch und Sie haben keinen Zugriff auf die Typen. Warum lädst du es nicht statisch? Dann verschwinden alle deine Probleme. Warum hörst du nicht auf, Pakete zu benutzen und dein Leben noch einfacher zu machen? Beachten Sie, dass 'GetClass ('TFrame1')' in der ausführbaren Datei und nicht in Ihrem Paket nachsehen wird. –

+0

Hallo David, meine Absicht ist es, eine modulare Anwendung zu realisieren, so dass einige Funktionen für eine Gruppe von Benutzern und andere für eine andere Gruppe verfügbar sind. Ich dachte, aus diesem Grund sone Pakete mit den erforderlichen Features zu erstellen. – Eros

+0

Das ist eine wirklich mühsame Art, es zu tun. Ich würde dynamisch geladene Pakete nicht als zweckdienlich betrachten. –

Antwort

1

Zum Beispiel:

AClass := GetClass('TFrame1'); 
    if Assigned(AClass) and AClass.InheritsFrom(TCustomFrame) then 
    begin 
    AFrame := TCustomFrameClass(AClass).Create(Self); 
    AFrame.Parent := Self; 
    AFrame.Align := alClient; 
    AFrame.Show; 
    end; 

Wenn Sie nicht RegisterClass verwenden möchten dann eine andere Art und Weise, ist dies:

AClass := GetProcAddress(FPackageHandle, '@[email protected]@'); 

(die Konvention ist <at><unit_name><at><class_name><at>).

+1

Es ist auch von entscheidender Bedeutung, dass die ausführbare Host-Datei mit aktivierten Laufzeit-Paketen kompiliert wird und dass mindestens die Pakete 'rtl' und' vcl' darunter enthalten sind. Andernfalls werden 'RegisterClass' und' GetClass' in verschiedenen Kontexten aufgerufen (das Paket verwendet die Laufzeit '.dcp' und der Host benutzt die RTL-Quelle) und das Finden der Klasse wird fehlschlagen. –