Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Do Jul 17, 2025 13:39

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Form mehrfach aus DLL Laden
BeitragVerfasst: Mi Nov 26, 2003 18:44 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Hier mein Problem :
Ich habe eine dll Datei in der befindet sich ein normales TForm mit diversen Schaltflächen. Nun importiere ich dieses Formular aus der dll Datei in mein Hauptprogramm. Dabei lege weise ich dem Formular ein TPanel als Parent zu um das ganze besser unter Kontrolle zu haben. Das funktioniert so weit auch ohne Probleme.

Hier ein kleiner Code Ausschnitt(nur falls dort schon Fehler stecken)

Code:
  1.  
  2. var
  3.    MainWnd : hwnd;  
  4. ...
  5.    dlldata.dllhandle := LoadLibrary(pchar(ExtractFileDir(Application.ExeName)+'\Objects'+ObjectFile));
  6.    if dlldata.dllhandle <>0 then
  7.    begin
  8.         @dlldata.StartMainWnd       := GetProcAddress(dlldata.dllhandle,'StartMainWnd');
  9.         @dlldata.StartMainWndEx     := GetProcAddress(dlldata.dllhandle,'StartMainWndEx');
  10.    end;
  11.    MainWnd:=dlldata.StartMainWndEx(BackgroundPanel.Handle);
  12.  


Nun habe ich aber folgende Probleme.
1. Ich möchte das das Formular der dll Datei Transparent angezeigt wird. Es sollen also nur die Schaltflächen sichtbar sein. Der Rest soll so Transparent sein das der Hintergrund des HauptFormulars der Anwendung angezeigt wird. Das Problem ist das sämtliche gesetzte Eigenschaften wie AlphaBlend,Trasparenz oder Canvas.Brush.Style:=bsnone nach dem importieren in die Hauptanwendung keine Wirkung zeigen.

2. Das Zweite problem ist das das erste importierte Fenster sofort verschwindet wenn ich den Code nochmals mit der selben dll Datei ausführe. Es ist jedoch verdammt wichtig das es irgendwie funktioniert das ich zwei mal die selbe dll lade und die Formulare unabhängig voneinander importieren kann. Nur wie mache ich das?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 19:02 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Anstelle von normalen DLL's könnten Packages hilfreich, weil man sie wie units einbinden und damit auch Klassen exportieren kann.
Vielleicht erübrigt sich dann dein Problem, weil die Form dann so in die VCL eingebunden werden kann, als wäre sie in einer unit.


Zuletzt geändert von LarsMiddendorf am Mi Nov 26, 2003 19:04, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 19:03 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Es müssen unbedingt dll sein weil diese unterschiedliche im nachträglich veränderbare Objekte darstellen die von der Anwendung nur geladen werden sollen...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 19:52 
Offline
DGL Member

Registriert: Mo Jan 20, 2003 20:10
Beiträge: 424
Wohnort: nähe Starnberg
Packages sind DLLs, die nur besser, da eine Schnittstelle existiert, von der VCL integriert werden.

Jedoch dürfte das dein Problem nicht lösen. Wie sieht die DLL aus?

Gruß
KidPaddle

_________________
http://www.seban.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Nov 26, 2003 20:33 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
In der DLL existiert das MainForm welches dann in der Haupt Anwendung angezeigt wird. Die DLL exportiert eine Funktion mit der die HauptAnwendung das MainForm der DLL starten kann. Der rest was in dem MainForm der DLL geschieht wird komplett über die DLL gesteuert. Es ist dann absolut nicht mehr Sache der Hauptanwendung. Die Hauptanwendung läft nur das MainForm der DLL und zeigt dieses auf seinem Haupt Formular an.

Die exporitere funktion der DLL

Code:
  1.  
  2. function StartMainWndEx(handle : Hwnd): hwnd;
  3. begin
  4.   try
  5.     if MainWnd = nil then
  6.     begin
  7.       MainWnd := TMainWnd.Create(nil);
  8.       MainWnd.ParentWindow := handle;
  9.       ...
  10.       MainWnd.show;
  11.     end
  12.     else begin
  13.       MainWnd.ParentWindow := handle;
  14.       MainWnd.show;
  15.     end;
  16.     result := MainWnd.Handle;
  17.   except
  18.     result := 0;
  19.   end;
  20. end;
  21.  


Die Hauptanwendung lädt dann dieses Formular und zeigt es auf seinem Formular an. Geladen wird das ganze in der Hauptanwendung :

Code:
  1.  
  2. type
  3.     Tdllhandle = record
  4.                   dllhandle : THandle;
  5.                   StartMainWndEx     : function(owner : Hwnd): hwnd;
  6.                   StartMainWnd       : function :hwnd ;
  7.                   ...
  8.                  end;
  9.  
  10.     TDesktopObject = object
  11.                       dlldata : Tdllhandle;                      
  12.                       ObjectFile : String;
  13.                       ID : integer;
  14.                       PosX,PosY : integer;
  15.                       Width,Height : integer;
  16.                       BackgroundPanel : TPanel;
  17.                       MainWnd : hwnd;
  18.                       procedure LoadObject;
  19.                      end;
  20.  
  21. var
  22.     DesktopObjects : array of TDesktopObject;
  23.  
  24.  
  25. procedure TDesktopObject.LoadObject();
  26. begin
  27.      if dlldata.dllhandle<>0 then
  28.      begin
  29.           BackgroundPanel.Free;
  30.           freelibrary(dlldata.dllhandle);
  31.      end;
  32.      dlldata.StartMainWndEx:=nil;
  33.      dlldata.StartMainWnd:=nil;
  34.      dlldata.dllhandle:=0;
  35.  
  36.      BackgroundPanel := TPanel.Create(MainForm);
  37.      ...
  38.      try
  39.         dlldata.dllhandle := LoadLibrary(pchar(ExtractFileDir(Application.ExeName)+'\Objects'+ObjectFile));
  40.         if dlldata.dllhandle <>0 then
  41.         begin
  42.              @dlldata.StartMainWnd       := GetProcAddress(dlldata.dllhandle,'StartMainWnd');
  43.              @dlldata.StartMainWndEx     := GetProcAddress(dlldata.dllhandle,'StartMainWndEx');
  44.         end;
  45.         MainWnd:=dlldata.StartMainWndEx(BackgroundPanel.Handle);
  46.         BackgroundPanel.Show;                
  47.      except
  48.  
  49.      end;
  50. end;
  51.  

hier liegt halt nun das Problem vor das ich jede dll nur genau einmal verwenden kann...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 08:33 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jul 12, 2002 07:15
Beiträge: 916
Wohnort: Dietzhölztal / Hessen
Programmiersprache: C/C++, Obj-C
Ich hatte sowas auch mal. Dabei gibt es noch ein anderes Problem: Wenn Du die Form in der DLL erstellst und 'nem Handle der Haupt-Anwendung zuweist, dann werden so Tastatur-Befehle wie "Tab" einfach ignoriert. Denn innherlab der Form befindet sich ebenfalls ein Applicaiton-Objekt welches die eine eigene Nachrichten-Verarbeitung hat. Das beste in so einem Fall ist wirklich, das ganze per BPL zu regeln. Evtl. Hillft Dir das PlugIn-System der Jedis im Umgang mit BPLs. Und, wie immer in solchen Fällen, die Delphi-Hilfe bemühen. Da gibt's 'ne Menge Tipps!

_________________
Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 09:58 
Offline
DGL Member

Registriert: Mo Jan 20, 2003 20:10
Beiträge: 424
Wohnort: nähe Starnberg
Wenn ich dich richtig verstehe, hast Du eine DLL die von 2 Anwendungen verwendet wird. Sobald Du die zweite Anwendung startest, verschwindet das Formular aus der ersten Anwendung.

Oder Du hast eine Anwendung in der Du zwei mal das gleiche Formular aus der DLL anzeigen willst?

Gruß
KidPaddle

_________________
http://www.seban.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 13:17 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Ich hab eine Anwendung in der 2 mal das gleiche Formular genutzt werden soll. Aber es soll nicht nur 2 mal das gleiche Formular sonder eigentlich 2 mal die dll und deren Code genutzt werden. Also beide Formulare sollen voneinandern unabhängig sein...
Ich hab z.B. eine dll auf dessen Formular ein TImage und ein TLabel sind. Die Anwendung soll dies laden und im TImage Bild 1 und im Label Tex1 anzeigen. Dann soll die Anwendung das ganze nochmal an eine andere Stelle laden und Bild 2 und Text2 anzeigen. Das was in dem Formular angezeigt wird also welches Bild und welcher Text ist kein Problem. Dafür habe ich schon eine lösung. Nur verschwindet das erste Formular wenn ich das zweite erzeuge...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 14:01 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Du müsstest bei dir eine Fensterverwaltung einbauen. Also müsste deine Methoden mehrere Fenster gleichzeitig verwalten können. (TList)
Aber sobald du mehrere Fenster haben willst kommst du logischerweise nicht mit einer Instanz der Klasse (eine Variable) aus. Du benötigst für jedes Fenster, was du verwenden möchtest, eine eigene Instanz.

Ich würde das in etwa so aufbauen.
CreateWindow(Handle): Integer; // erstellt fenster und liefert deren Index in der TList zurück.
DestroyWindow(Index); // Zerstört das Fenster an der aktuellen Position der Liste
ShowWindow(Index); // Wie der Name schon sagt.
Etc. Was man halt zum Leben braucht

In dem CreateWindow würdest du dann jedes Mal eine Instanz deiner Klasse ablegen.

Zu dem Problem von SchodMC. Es sollte genügen, wenn du deine Fenster mittels der Applicationklasse deiner Anwendung erstellst. Wie dies geschieht siehst du in der dpr. Du müsstest dann deine Applicationklasse an die DLL übergeben. Könnte evtl ein Parameter der CreateWindow sein. Aber das ist auch nur so eine Idee von mir. Will da aber nix ins Feuer legen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 14:58 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
aber wie lade ich eine dll mehrfach, also wie erzeuge ich mehrere Instancen von einer dll? LoadLibary lädt die dll in den Prozess der Anwendung. Wurde sie bereits rein geladen erzeugt er keine neue Instanc sondern verweißt nur auf die bereits geladene...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 15:51 
Offline
DGL Member

Registriert: Mo Jan 20, 2003 20:10
Beiträge: 424
Wohnort: nähe Starnberg
Garnicht, Du kannst eine DLL nur einmal laden. Es macht keinen Sinn, den gleichen Code mehrmals in den Speicher zu holen, da DLLs geschrieben wurden, um den Speicherverbrauch zu senken.

Wie Lossy Ex schon schrieb, must Du eine eigene Fenterverwaltung implementieren.

Gruß
KidPaddle

_________________
http://www.seban.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 15:56 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Jul 12, 2002 07:15
Beiträge: 916
Wohnort: Dietzhölztal / Hessen
Programmiersprache: C/C++, Obj-C
Eine andere Möglichkeit wäre, ein Interface für die Form zu erstellen. Mit Hilfe von Interfaces kann man Objekte innerhalb von DLLs erstellen und nur die freigegebenen Prozeduren exportieren. Funktioniert recht gut. Allerdings wird das ganze für ein VCL-Objekt wie z.B. einer Form, Buttons etc. etwas aufwendig, aber machbar. Schau einfach mal in der Delphi-Hilfe zu dem Thema nach. BTW, da fällt mir gerade ein, dass ich ja mal ein tut dazu machen wollte...

_________________
Und was würdest Du tun, wenn Du wüsstest, dass morgen Dein letzter Tag auf dieser Erde ist?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Nov 27, 2003 16:47 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Du könntest auch eine Funktion exportieren die die Basisklasse für alle DLL Formen als Type des Rückgabewertes hat und dann diese Klasse ganz normal verwenden. Dafür müssen aber alle Methoden und auch der constructor als virtual deklariert sein.
Mit Packages geht es flexibler.
Man kann eine Package mit LoadPackage wie eine DLL laden.
Im initializaion Block der Unit wird die Form Klasse dann mit registerclass registriert. Dann kann man im Hauptprogramm anhand des Namens mit findclass die Klasse ermitteln und ganz normal verwenden.

In diesem Artikel wird das ausführlich beschrieben:
http://bdn.borland.com/article/0,1410,27178,00.html


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 01, 2003 10:38 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Ich hab das ganze jetzt mal mit den Packages probiert. Das ganze funktioniert bis jetzt genau so wie ich es wollte :)

Da will ich gleich mal ein großes Lob für das Forum hier ausprechen. Ich habe mein Problem in 3 Delphi Foren gepostet. Die anderen sind um einiges größer und mehr besucht als dieses hier. Jedoch habe ich nur hier so schnell eine Antwort bekommen. :D


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Dez 01, 2003 20:43 
Offline
DGL Member
Benutzeravatar

Registriert: Di Jun 24, 2003 19:09
Beiträge: 732
Kaum funktioniert es halbwegs habe ich gleich ein anderes Problem. :wink:
Ich muß jedem Formular ja irgendwie mitteilen was es anders anzeigen soll als die anderen Formulare vom gleichen Typ. Das ist an sich kein Problem da jedes Formular die Daten aus der Registry über eine ID ziehen wird. D.h. ich muß jedem Formular seine ID mitteilen damit er die Daten aus der Registry lesen kann. Nur irgendwie finde ich keinen weg diese ID zu übergeben... :?


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 15 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.012s | 16 Queries | GZIP : On ]