2017-02-22 5 views
-1

Ich versuche, ein Formular und ein Frame in Delphi-made DLL nur mit Handles zu erstellen. Das Formular wird normalerweise in der Hostanwendung angezeigt, der Rahmen wird jedoch nicht angezeigt.Delphi Formular in DLL funktioniert, aber Delphi Frame - nicht

Was könnte falsch sein?

Im Folgenden stelle ich ein Stück Code, der sowohl Rahmen und Fenster erzeugt:

library DLL1; 

{ Important note about DLL memory management: ShareMem must be the 
    first unit in your library's USES clause AND your project's (select 
    Project-View Source) USES clause if your DLL exports any procedures or 
    functions that pass strings as parameters or function results. This 
    applies to all strings passed to and from your DLL--even those that 
    are nested in records and classes. ShareMem is the interface unit to 
    the BORLNDMM.DLL shared memory manager, which must be deployed along 
    with your DLL. To avoid using BORLNDMM.DLL, pass string information 
    using PChar or ShortString parameters. } 

uses 
    System.SysUtils, 
    System.Classes, 
    DllMain in 'DllMain.pas', 
    Winapi.Windows, 
    Vcl.Forms, 
    Vcl.Controls {DLLFrame1: TFrame}, 
    DllForm in 'DllForm.pas' {Form1}; 

{$R *.res} 

type 
    TSingleton = class 
    private 
    fra: TDLLFrame1; 
    frm: TForm1; 
    class var __instance: TSingleton; 
    class function __getInstance(): TSingleton; static; 
    public 
    class property Instance: TSingleton read __getInstance; 
    procedure CreateDLLFrame(AppHandle, ParentWindow: HWND); 
    procedure CreateDLLForm(AppHandle, ParentWindow: HWND); 
    procedure DestroyDLLFrame(); 
    procedure DestroyDLLForm(); 
    end; 

procedure CreateDLLFrame(AppHandle, ParentWindow: HWND); stdcall; 
begin 
    TSingleton.Instance.CreateDLLFrame(AppHandle, ParentWindow); 
end; 

procedure CreateDLLForm(AppHandle, ParentWindow: HWND); stdcall; 
begin 
    TSingleton.Instance.CreateDLLForm(AppHandle, ParentWindow); 
end; 

procedure DestroyDLLFrame(); stdcall; 
begin 
    TSingleton.Instance.DestroyDLLFrame(); 
end; 

procedure DestroyDLLForm(); stdcall; 
begin 
    TSingleton.Instance.DestroyDLLForm(); 
end; 

exports 
    CreateDLLFrame, 
    CreateDLLForm, 
    DestroyDLLFrame, 
    DestroyDLLForm; 

procedure TSingleton.CreateDLLFrame(AppHandle, ParentWindow: HWND); 
begin 
    Application.Handle := AppHandle; 
    fra := TDLLFrame1.CreateParented(ParentWindow); 
    fra.Show(); 
end; 

procedure TSingleton.DestroyDLLForm(); 
begin 
    frm.Free(); 
end; 

procedure TSingleton.DestroyDLLFrame(); 
begin 
    fra.Free(); 
end; 

procedure TSingleton.CreateDLLForm(AppHandle, ParentWindow: HWND); 
begin 
    Application.Handle := AppHandle; 
    frm := TForm1.CreateParented(ParentWindow); 
    frm.Show(); 
end; 

class function TSingleton.__getInstance(): TSingleton; 
begin 
    if __instance = nil then 
    __instance := TSingleton.Create(); 
    Result := __instance; 
end; 

end. 

Die DLLFrame:

unit DllMain; 

interface 

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

type 
    TDLLFrame1 = class(TFrame) 
    mmoText: TMemo; 
    pnlSend: TPanel; 
    edtSend: TEdit; 
    btnSend: TButton; 
    private 
    public 
    constructor Create(AOwner: TComponent); override; 
    end; 

implementation 

{$R *.dfm} 

{ TDLLFrame1 } 

constructor TDLLFrame1.Create(AOwner: TComponent); 
begin 
    inherited; 
    if AOwner = nil then 
    MessageBox(0, 'Frame owner is NIL', 'Debug', 0) 
    else 
    MessageBox(0, PWideChar(AOwner.Name), 'Debug', 0); 
end; 

end. 
+0

Wo ist Ihre Definition für TDLLFrame1? – Dsm

+0

Aktualisiert. Der Code ist jetzt auch da. – Paul

+0

Wie wäre es mit DLLForm.pas? Wie wäre es mit einem Beispielcode, der CreateDLLForm und CreateDLLFrame aufruft? –

Antwort

1

Delphi TFrame stammen von Twincontrol (und damit TControl), haben sie eine Besitzer und sie haben ein Elternteil (oft sind diese gleich). Der Besitzer steuert die Lebensdauer des Frames, während der Parent steuert, wo er angezeigt wird (d. H. Welcher Fenstergriff verwendet werden soll). In einer VCL-App mit 2 Form-Units und einer Frame-Unit könnten Sie zum Beispiel ein Frame instanziieren, dessen Besitzer das Application-Objekt oder das erste Form-Objekt ist, während es das zweite Formular ist. Der Frame würde auf dem zweiten Formular angezeigt, obwohl der erste Frame der Besitzer war.

What is the difference between Owner and Parent of a control?

Dieses kleine Beispiel verwendet keine DLLs, aber es zeigt, wie der Rahmen nicht ohne Eltern angezeigt zugewiesen werden:

unit CreateFrameAtRunTimeForm; 

interface 

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

type 
    TForm2 = class(TForm) 
    Label1: TLabel; 
    Button1: TButton; 
    Button2: TButton; 
    procedure Button1Click(Sender: TObject); 
    procedure Button2Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form2: TForm2; 

implementation 

uses CreateFrameAtRunTimeFrame; 

{$R *.dfm} 

procedure TForm2.Button1Click(Sender: TObject); 

var 
    F : TFrame3; 

begin 
    F := TFrame3.Create(self); 
    F.Name := 'Frame'+Random(1000000).ToString; 
    F.Panel1.Caption := 'Frame '+F.Name; 
    F.Left := 200; 
    F.Top := 100; 
end; 

procedure TForm2.Button2Click(Sender: TObject); 

var 
    F : TFrame3; 

begin 
    F := TFrame3.Create(self); 
    F.Name := 'Frame'+Random(1000000).ToString; 
    F.Panel1.Caption := 'Frame '+F.Name; 
    F.Left := 200; 
    F.Top := 100; 
    F.Parent := self; 
end; 

end. 

Ich bin sicher, dass Ihr Problem ist, dass Der Frame hat kein Parent-Steuerelement und ich denke nicht, dass es möglich ist, einen zu setzen, wenn Sie nur Fenstergriffe herumreichen.

+0

Ich dachte, dass "CreateParented" ist ein Äquivalent der Einstellung "Eltern" oder Aufruf von "Winapi.Windows.SetParent". Aber ich habe festgestellt, dass 'TFrame' keinen' CreateWindowEx' Aufruf hat. – Paul

+0

Ich dachte das auch. In meinem Beispiel habe ich versucht, das ParentWindow des Frames nur auf den Handle oder WindowHandle des Forms zu setzen, ohne Erfolg. Die TWinControl-Eigenschaft "Parent" scheint mehr zu enthalten als nur die Handles. –

+0

@Dave Dies ist nur möglich, wenn Sie Laufzeitpakete verwenden. –

Verwandte Themen