![]() |
Re: Dll Forms... oder ligt es nicht daran ??
Sascha, schnapp mal eine Runde frische Luft, dann sieht Du das Problem auch ;-)
Du greifst auf die DLL zu, rufst die Procedure auf und gibst danach die DLL wieder frei, welche auch die Form in der DLL zerstört. Auf was sollte bitte gewartet werden? Du musst auf die DLL zugreifen und erst später (Programmende?) wieder per FreeLibrary schließen. [edit]Ich würde Dir noch vorschlagen, eine Klasse zu schreiben, die erstmal alle dlls im Plugin-Ordner in eine Liste einfügt. Sobald dann ein Plugin benötigt wird, lädt die Klasse die DLL in den Speicher. Bevor nun die DLL-Form geschlossen wird, sendet diese eine Nachricht an das Hauptprogramm, darauf hin schließt sich die Form und die Klasse gibt per FreeLibrary die DLL frei. Soweit der theoretische Ansatz. Jetzt ist Dein Grips gefragt. :) [/edit] |
Re: Dll Forms... oder ligt es nicht daran ??
Wie soll ich denn eine Nachricht an die Dll schicken ?? oder von der DLL in das Hauptprogramm.
Etwa mit Messages ?? wenn ja das habe ich noch nie gemacht und kenne mich damit nicht aus. Aber wenn jemand einen Rat hat oder eine Tutorial dann würde das Helfen.. Ich versuch mal die DLL zu öffnen ohne das Befreien vom speicher ! Gruss Sascha |
Re: Dll Forms... oder ligt es nicht daran ??
Zitat:
Zur Kommunikation DLL <-> Hauptprogramm empfehle ich Dir diesen und die nachfolgenden Posts: ![]() |
Re: Dll Forms... oder ligt es nicht daran ??
Habe Jetzt die Zeile :
Delphi-Quellcode:
Procedure gelöscht.
KundendatenF.Release;
die Handle Variable als Global variable gesetzt und einen 2. Button auf das Hauptformular gesetzt. Es ist richtig das ich automatisch den speicher wieder frei gebe. Nun gebe ich den Speicher bei Klick auf den 2. Button wieder frei. und das Formular Funktioniert. Aber wie kann ich das vermeiden das ich extra einen Button anklicken muss. Habe schon oft von msg gehört. Kann ich an die DLL eine Message schicken bzw. von der DLL an das HauptProgramm ?? |
Re: Dll Forms... oder ligt es nicht daran ??
Hi Sascha,
ich würde, wie gesagt, erst mal eine Klasse "drumrum" bauen, die die DLLs aufruft. Ich denke, dass Du ja nicht nur ein PlugIn haben wirst. Lieber jetzt ein bisschen mehr Zeit (und Nerven) investieren, aber dafür hast Du dann hinterher einen sauberen, erweiterbaren Aufbau einer PlugIn-Klasse. Aber das ist Dir überlassen (ich kenne ja Dein Projekt nicht). Zum Message verschicken, schau Dir mal ![]() ![]() |
Re: Dll Forms... oder ligt es nicht daran ??
Muhkuh : Du hast recht. Aber auch das ist neuland für mich. Begebe mich da in ein Komplettes Neuland für mich.
Habe biser immer nur formulare gemacht und das als Exe Fertig. da habe ich weder Messages gebraucht noch Klassen erstellen müssen. Ist der Link den du mir da genannt hast eine Anleitung für die Klassen ?? oder ist das etwas anderes ? |
Re: Dll Forms... oder ligt es nicht daran ??
Hi Sascha,
der Link (im vorherigen Post), ist eine Anleitung für ein Interface, dass die Kommunikation Hauptprogramm <-> DLL abdeckt. Klassen an sich, sind nichts "schweres". ![]() |
Re: Dll Forms... oder ligt es nicht daran ??
Ich hab da auch noch nen guten Link zu
![]() |
Ergebnis bis jetzt !
Also habe nun Lektüre gelesen und gemacht und getan und habe folgendes zusammen bekommen.
Hauptprogramm bestehend aus folgenden dateien : MainF.pas Interfaces.pas filefinder.pas (werde ich aber mal nicht mit hinzufügen. denke sieht jeder selbst was der machen soll) interfaces.pas :
Delphi-Quellcode:
MainF.pas
unit interfaces;
interface uses classes, forms; const IID_Plugin: TGUID = '{664AAC6B-BF3B-4539-8682-1C33AC692D62}'; IID_PluginForm: TGUID = '{70B82481-A4E5-4E3F-BAF3-1697EA771FAD}'; IID_App: TGUID = '{AC519934-9997-432C-9055-E80FD001F502}'; type IPlugin = Interface(IInterface) ['{664AAC6B-BF3B-4539-8682-1C33AC692D62}'] function GetName: PChar; stdcall; function GetVersion: Integer; stdcall; End; IPluginForm = Interface(IInterface) ['{70B82481-A4E5-4E3F-BAF3-1697EA771FAD}'] End; implementation end.
Delphi-Quellcode:
nun die dll :
unit MainF;
interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Menus, ActnList, interfaces, filefinder, inifiles; type TForm1 = class(TForm) MainMenu1: TMainMenu; Programm1: TMenuItem; Beenden1: TMenuItem; Plugin1: TMenuItem; ActionList1: TActionList; Action1: TAction; Memo1: TMemo; procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Beenden1Click(Sender: TObject); procedure Action1Execute(Sender: TObject); private // app: IApp; hDLL : HWND; iPlg: IPlugin; iPlgForm : IPluginForm; public { Public-Deklarationen } end; var Form1: TForm1; AktDll : Integer; ProgDir : String; LibDir : String; implementation {$R *.DFM} procedure TForm1.Action1Execute(Sender: TObject); type TProcInitPlg = function(PApp: TApplication; PForm: TForm): IPluginForm; stdcall; var fProc: TProcInitPlg; begin @fProc := GetProcAddress(hDLL, 'RunPlugin'); if fProc(Application,Form1) <> nil then begin iPlgForm := fProc(Application,Form1); end; end; procedure TForm1.Beenden1Click(Sender: TObject); begin Close; end; procedure TForm1.FormCreate(Sender: TObject); type TProcInitPlg = function: IPlugin; stdcall; var fProc: TProcInitPlg; New_Entry_Plugin : TMenuItem; begin ProgDir := extractfilepath(paramstr(0)); LibDir := copy(ProgDir,0,Pos('bin',ProgDir)-1) + 'lib\'; messageDlg('folgender Pfad wird durchsucht : ' + LibDir, mtInformation, [mbOK],0); Memo1.Lines := FindPlugins(LibDir); // Bibliothek laden und Interface holen messageDlg('Versuche folgende DLL zu laden : ' + LibDir + Memo1.Lines[0], mtInformation, [mbOK],0); hDll := LoadLibrary(PCHAR(libdir + Memo1.Lines[0])); @fProc := GetProcAddress(hDLL, 'InitPlugin'); if fProc <> nil then begin iPlg := fProc; New_Entry_plugin := TMenuItem.Create(self); Action1.Caption := PCHAR(iPlg.GetName); New_Entry_Plugin.Action := Action1; Plugin1.Add(New_Entry_Plugin); end; end; procedure TForm1.FormDestroy(Sender: TObject); var i : Integer; begin // PlugIn zerstören iplg := nil; iPlgForm := nil; // Bibliothek entladen FreeLibrary(hDLL); // Application-Interface zerstören // app := nil; end; end. kMain.pas interfaces.pas kundendaten.dpr / projektdatei so nun erstmal die dpr
Delphi-Quellcode:
library Kundendaten;
uses SysUtils, Classes, forms, kMain in 'kMain.pas' {KundendatenF}, interfaces in '..\..\units\interfaces.pas'; {$E dll} {$R *.res} function InitPlugin: IPlugin; stdcall; begin Result := TPlugin.Create; end; Function RunPlugin(pApp: TApplication; PForm: TForm) : IPluginForm; Stdcall; var tmpForm : TPluginForm; begin tmpForm := TPluginForm.create(pApp,PForm); Result := tmpForm; end; exports InitPlugin, RunPlugin; begin end. die kMain.pas
Delphi-Quellcode:
So Funktioniert auch so weit. Ich kann das Programm starten und das MDIChild öffnen. Alles super. Es wird auch korrekt geschlossen. Aber sobald ich das Programm Beenden möchte Gibt er mir eine Fehlermeldung raus.
unit kMain;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, interfaces; type TKundendatenF = class(TForm) Button2: TButton; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button2Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; TPluginForm = Class(TInterfacedObject, IPluginForm) private ClientForm : TKundendatenF; protected public constructor create(PApp: TApplication; PForm: TForm); destructor Destroy; override; End; TPlugin = class(TInterfacedObject, IPlugin) private function GetName: PChar; stdcall; function GetVersion: Integer; stdcall; protected // hier die Methoden von system.TInterfacedObject reinkopieren public end; var KundendatenF: TKundendatenF; dllApp: TApplication; PluginForm : TPluginForm; implementation constructor TPluginForm.create(PApp: TApplication; PForm: TForm); begin dllApp := Application; Application := PApp; ClientForm := TKundendatenF.Create(Application); end; destructor TPluginForm.Destroy; begin ClientForm.free; end; { TPlugin } function TPlugin.GetName: PChar; begin Result := '&Kundendaten'; // "T" unterstrichen im Menü end; function TPlugin.GetVersion: Integer; begin Result := (1 shl 16) or 0; // 1.0 end; {$R *.dfm} procedure TKundendatenF.Button2Click(Sender: TObject); begin close; end; procedure TKundendatenF.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; end. Ich habe schon versucht mit verschiedenen mitteln denn ich denke das der grund hier ligt :
Delphi-Quellcode:
habe auch schon versucht das wieder an das Programm zurückzugeben aber ohne erfolg Macht keinen unterschied ! hat jemand einen Rat ?
dllApp := Application; <<----- Geschätzte uhrsache !!
Application := PApp; ClientForm := TKundendatenF.Create(Application); Gruss Sascha |
Re: Dll Forms... oder ligt es nicht daran ??
Delphi-Quellcode:
So sollte es funktionieren. Die Variable Application wird von Delphi bereits benutzt, die sollte man nicht vermurksen :)
constructor TPluginForm.create(PApp: TApplication; PForm: TForm);
begin ClientForm := TKundendatenF.Create(PApp); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz