Ich habe ein großes Problem mit DLL Dateien...
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 weise ich dem Formular ein TPanel als Parent zu um das ganze besser unter Kontrolle zu haben. Das funktioniert so weit auch ohne Probleme.
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ädt nur das MainForm der DLL und zeigt dieses auf seinem Haupt Formular an.
Nur gibt es dabei ein großes Problem.
Sobald ich die dll nochmal laden will und ein neues Formular damit erzeuge(mit anderen Eigenschaften als dem vorherigen was ja bestehen bleiben soll) dann verschwindet das anderen durch die dll geladen Formular...
Hier die wichtigsten Code ausschnitte :
Die exporitere funktion der DLL
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| function StartMainWndEx(handle : Hwnd): hwnd; begin try if MainWnd = nil then begin MainWnd := TMainWnd.Create(nil); MainWnd.ParentWindow := handle; ... MainWnd.show; end else begin MainWnd.ParentWindow := handle; MainWnd.show; end; result := MainWnd.Handle; except result := 0; end; end; |
Die Hauptanwendung lädt dann dieses Formular und zeigt es auf seinem Formular an. Geladen wird das ganze in der Hauptanwendung :
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:
| type Tdllhandle = record dllhandle : THandle; StartMainWndEx : function(owner : Hwnd): hwnd; StartMainWnd : function :hwnd ; ... end;
TDesktopObject = object dlldata : Tdllhandle; ObjectFile : String; ID : integer; PosX,PosY : integer; Width,Height : integer; BackgroundPanel : TPanel; MainWnd : hwnd; procedure LoadObject; end;
var DesktopObjects : array of TDesktopObject;
procedure TDesktopObject.LoadObject(); begin if dlldata.dllhandle<>0 then begin BackgroundPanel.Free; freelibrary(dlldata.dllhandle); end; dlldata.StartMainWndEx:=nil; dlldata.StartMainWnd:=nil; dlldata.dllhandle:=0;
BackgroundPanel := TPanel.Create(MainForm); ... try dlldata.dllhandle := LoadLibrary(pchar(ExtractFileDir(Application.ExeName)+'\Objects\'+ObjectFile)); if dlldata.dllhandle <>0 then begin @dlldata.StartMainWnd := GetProcAddress(dlldata.dllhandle,'StartMainWnd'); @dlldata.StartMainWndEx := GetProcAddress(dlldata.dllhandle,'StartMainWndEx'); end; MainWnd:=dlldata.StartMainWndEx(BackgroundPanel.Handle); BackgroundPanel.Show; except
end; end; |
hier liegt halt nun das Problem vor das ich jede dll nur genau einmal verwenden kann...