![]() |
Mainform aus DLL laden?
Hallo,
Ich hoffe ich habe hier das richtige Forum erwischt, denn das Thema ist ziemliches Neuland für mich. Also erstmal die Dinge die schon funktionieren(nur Hintergrundinfo): Ich habe eine Anwendung, die ich über das Kontextmenü im Windows Explorer bei bestimmten Dateien(MP3s) starten kann. Wenn ich also viele Dateien markiere wird das Programm auch mehrfach gestartet. Ich habe mit der ONEinst Unit von Luckie dafür gesorgt, dass mein Programm nur einmal gestartet wird und dass alle markierten Dateien an diese eine instanz übergeben werden. Soweit so gut. Das Problem ist jetzt, dass das gegebene Programm inzwischen relativ groß geworden ist und lange zum laden braucht. Erst recht wenn eben 100 Dateien markiert wurden und das Programm 100mal gestartet wird. Daher möchte ich mein ganzen Grundgerüst umwerfen und das Programm in DLLs verteilen, die immer nur dann geladen werden, wenn sie auch gebraucht werden. Auch die MainForm. Ich hab inzwischen ein wenig über DLLs gelesen und weiß wie ich sie erstelle und wie ich "von außen" darauf zugreifen. Wie schaffe ich es, dass ich die mainform als benutzer "normal" nutzen kann? Im Moment wird sie ja erzeugt und dan gleich wieder geschlossen... Bisher hab ich folgendes: Programm:
Delphi-Quellcode:
Die test.dll:
program bla;
uses windows, SysUtils; type TStarteMainForm = procedure; stdcall; procedure StartMainForm; Var DLL : THandle; {$R *.res} procedure StartMainForm; Var StarteForm : TStarteMainForm; begin DLL := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + 'test.dll')); If DLL <> 0 then begin @StarteForm := GetProcAddress(DLL, 'StartApplication'); If @StarteForm <> nil then StarteForm; end; end; begin DLL := 0; StartMainForm; if DLL <> 0 then FreeLibrary(DLL); end; end.
Delphi-Quellcode:
library MainDLL;
{ Haupt-DLL mit Hauptfenster } uses Forms, Unit1 in 'unit1.pas' {MainForm}; {$R *.res} procedure StartApplication; stdcall; begin Application.Initialize; Application.CreateForm(TForm1, MainForm); Application.Run; end; exports StartApplication; begin end. |
Re: Mainform aus DLL laden?
Ich denke mal das ist der falsche Weg. Du wirst Probleme bekommen zB. beim zuweisen und abrufen von Events ( beispielsweise FormButtonXYZClick etc.).
Selbst das Erstellen und Testen wird sich als schwierig erweisen. Die Formen nemen an sich nur wenig Platz ein das meiste sind Bilder, Sounds & der gleichen. Diese kann man aber einfach in eine DLL auslagern. Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Mainform aus DLL laden?
Zitat:
Ich denke, das wäre ein ziemlich guter Ansatzpunkt zur Optimierung :) |
Re: Mainform aus DLL laden?
Zitat:
Zitat:
Mit ParamStr() und ParamCount() die Strings in eine Liste verfrachten und gut ist. Ggf. noch Drag&Drop einbauen. |
Re: Mainform aus DLL laden?
Hallo,
Zitat:
Zitat:
Zitat:
Liebe Grüße Daniel |
Re: Mainform aus DLL laden?
Mahlzeit!
Ich kenne Dein Problem, und frage mich schon länger selbst, wie das andere Programme machen, wenn man X Dateien im Explorer öffnet, das da alle in das (läufende) Programm kommen, ohne das X Instanzen davon geladen werden. Da ich das noch nicht rausgefunden habe, eine kleine Alternative wäre, ein 2., winziges nonVCL Programm zu haben, was die Dateinamen zusammen schaufelt und dann in das laufende Programm sendet oder das Hauptprogramm startet und die Parameter übergibt. MfG, Sun |
Re: Mainform aus DLL laden?
Bei D&D bekommt man eine Dateiliste der zu droppenden Dateien... das andere ist DDE (Dynamic Data Exchange) glaube über OLE oder so.
Muss jetzt wech zum Besuch... ;) |
Re: Mainform aus DLL laden?
Zitat:
Dein Hinweis auf DDE hat mich leider nicht weitergebracht. Könntest du mir etwas genauer erklären, was du damit in meinem Fall meinst? Ansonsten habe ich jetzt eine Möglichkeit gefunden eine Form in eine DLL auszulagern. In der DLL erstelle ich die From modal. Ich hoffe, dass sie damit so lange angezeigt wird, wie ich das dann will. Nur leider kann ich es nicht testen, weil ich noch ein ganz anderes problem hab:
Delphi-Quellcode:
program bla;
uses windows, SysUtils; type TStarteMainForm = procedure; stdcall; procedure StartMainForm; Var DLL : THandle; {$R *.res} procedure StartMainForm; Var StarteForm : TStarteMainForm; begin DLL := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + 'test.dll')); If DLL <> 0 then begin @StarteForm := GetProcAddress(DLL, 'StartApplication'); If @StarteForm <> nil then StarteForm; end; end; begin DLL := 0; StartMainForm; if DLL <> 0 then FreeLibrary(DLL); end; // <-- Der Debugger will dieses end; WARUM? und wenn ich es einfüge, wird der Code vom begin bis zu dem end nicht ausgeführt?! end. |
Re: Mainform aus DLL laden?
Ich formatiere mal kurz um, was dein Compiler sieht:
Delphi-Quellcode:
Eine Form in der DLL ist keine schöne Lösung. Du nutzt dann das Applicationobject der DLL. Und da würde ich mir nicht sicher sein, ob das irgendwann einmal querschießt.
program bla;
uses windows, SysUtils; type TStarteMainForm = procedure; stdcall; procedure StartMainForm; //<--Hier ist der Fehler Var DLL : THandle; procedure StartMainForm; //Nested Procedure Var StarteForm : TStarteMainForm; begin DLL := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + 'test.dll')); If DLL <> 0 then begin @StarteForm := GetProcAddress(DLL, 'StartApplication'); If @StarteForm <> nil then StarteForm; end; end; begin //Procedure StartMainForm DLL := 0; StartMainForm; if DLL <> 0 then FreeLibrary(DLL); end; //begin end. |
Re: Mainform aus DLL laden?
Man könnte das Handle der App beim Aufrufen der DLL mit übergeben.
Quelle: ![]() Zitat:
|
Re: Mainform aus DLL laden?
Mit dem Handle mache ich das genau so wie von sunlight7 beschrieben.
Zitat:
Allerdings findet GetProcAddress() meine procedure in der DLL nicht. Und ich weiß einfach nicht warum nicht... Schreibweisen stimmen überein. habes mal mit name bei den exports versucht, aber das ging auch nicht. Ich vermute dass ich wieder irgendetwas im aufbau der DLL vermurksthabe, sodass der exports bereich nicht als exports bereich verstanden wird.
Delphi-Quellcode:
library MainDLL;
uses windows, Forms, sysutils, unTIM4 in 'unTIM4.pas' {MainForm}; {$R *.res} procedure MainForm(appHandle : THandle); stdcall; begin if appHandle = 0 then appHandle := GetActiveWindow; Application.Handle := appHandle; try with TMainForm.Create(Application) Do try ShowModal; finally free; end; except On E : exception Do Application.HandleException(E) end; Application.Handle := 0; end; exports MainForm; begin end. |
Re: Mainform aus DLL laden?
Und die Namensdifferenz von "MainForm" (DLL) und getProcAddress(...,'StartApplication'); hast du aufgehoben?
Ansonsten kannst du auch in die ExportListe der DLL gucken (z.B. mit GExperts - PE Informationen), was da so drin steht. |
Re: Mainform aus DLL laden?
Also an dem DLL Code liegts wohl nicht, habe folgendes getestet, funkt wunderbar, bis auf das, das die Form kein Icon hat.
Nur würde ich den Export vllt nicht gerade MainForm nennen, vllt beisst sich der Name mit etwas :gruebel:
Delphi-Quellcode:
library Project1;
uses Forms, Windows, SysUtils, Classes, Unit1 in 'Unit1.pas' {Form1}; procedure Test(AppHandle:THandle); stdcall; begin Application.Handle:=appHandle; try with TForm1.Create(Application) do begin ShowModal; Free; end; except On E : exception Do Application.HandleException(E); end; Application.Handle := 0; end; exports Test; begin end.
Delphi-Quellcode:
program Project1;
uses Windows, Forms; {$R *.RES} var Lib:Cardinal; Test:procedure(AppHandle:THandle); stdcall; begin Application.Initialize; Lib:=LoadLibrary('Project1.dll'); Test:=GetProcAddress(Lib, 'Test'); If Assigned(Test) then Test(Application.Handle); // Grad zu faul um Ress frei zu gegeben Application.Run; end. |
Re: Mainform aus DLL laden?
// edit: Okay der Fehler ist so doof, das es schon wehtut. Ich hatte zwei dlls in meinem verzeichnis. und in dem programm habe ich immer auf die alte verwiesen, die ich gar nicht mehr verändert habe -.- echt DOOF.
Naja aber es wäre ja nicht mein Quelltext wenn nicht gleich wieder ein Fehler auftauchen würde. Aber den find ich wenigstens logisch. Wie ich ihn umgehe, ist jetzt die frage. Ich möchte nicht wie sunlight7 forms einbinden um ein application-objekt zu erhalten. momentan weise ich der zu erstellenden Form dads Handle meines Threads zu. Das führt zu einem Fehler. Ich kenn mich da ja bnicht aus, aber ich nehm mal an das Windows zwischen den Handles von Threads und Fenstern unterschiede macht ;)
Delphi-Quellcode:
Daher dann auch der Fehler:
DLL := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + 'tim4_MainDLL.dll'));
If DLL <> 0 then begin @AMainForm := GetProcAddress(DLL, 'StartMainForm'); If @AMainForm <> nil then AMainForm(GetCurrentThread); end; Exceptiontyp: EOSError Meldung: Systemfehler. Code: 1400. Ungültiges Fensterhandle. Schade eigentlich. Vorschläge? edit2: ohne das ich der application in der dll ein neues handle zuweise geht es anscheinend. Kann die Form auch "bedienen" ohjne das irgendwelche fehler auftreten :) Nur bisher habe ich überall gelesen das es probleme mit messages geben wird, daher traue ich dem nicht ganz. Aber sind Mausklicks nicht auch messages? und die funktionieren auf den Buttons der form ja.. |
Re: Mainform aus DLL laden?
Die Warum-Stellen sind, weil Sunlight das Application-Objekt braucht, so wie es in der Hilfe Dokumentiert ist. Und dieses Objekt befindet sich in der Unit Forms.
Wenn du es anders machen willst, musst du dir das Application-Objekt genau ansehen. Edit: "Es funktioniert nicht" ist keine Fehlerbeschreibung. |
Re: Mainform aus DLL laden?
Also ne, ich brauch das Application Objekt sicher nicht :mrgreen:
Aber im ernst, wenn Deiner DLL das Handle fehlt treten merkwürdige Dinge auf, so zB das die Einträge in der Taskleiste doppelt sind und sowas... |
Re: Mainform aus DLL laden?
Zitat:
hmm ich werde es mal wieter probieren. Mal sehen ob bei mir ähnliches passiert. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:25 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 by Thomas Breitkreuz