Hallo zusammen,
komischer Titel, mir ist leider nichts besseres eingefallen.
Meine Anwendung arbeitet mit dynamischen Packages, in denen sich "Module" (Forms) befinden. Das Ganze wird realisiert mit einer Main-
MDI-Anwendung, die Module werden als
MDI-Childs dargestellt.
Zur Kommunikation zwischen Main-Programm und Modul verwende ich 2 Objekte: myDLLIN und myDLLOUT (nicht am Namen stören, ist ein Relikt aus vorherigen Experimenten).
Diese sind in einer von MailApp und den Modulen gemeinsam genutzten
Unit untergebracht:
Delphi-Quellcode:
unit DLLExchange;
interface
uses
Forms, ZConnection;
type
TDLLIN =
class
private
FApplication:
String;
FZConnection: TZConnection;
FUserID: integer;
procedure SetApp(aApplication:
string);
procedure SetZCon(aZConnection: TZConnection);
procedure SetUser(aUserID: integer);
public
property Application:
string read FApplication
write SetApp;
property Connection: TZConnection
read FZConnection
write SetZCon;
property UserID: integer
read FUserID
write SetUser;
end;
type
TDLLOUT =
class
private
FDBID: integer;
FModName:
String;
procedure SetDBID(aDBID: integer);
procedure SetModName(aModName:
String);
public
property DBID: integer
read FDBID
write SetDBID;
property ModName:
String read FModName
write SetModname;
end;
var
myDLLOUT: TDLLOUT;
implementation
...
Die Module (es soll immer nur eins aktiv sein WICHTIG!) werden von der MainApp so aufgerufen:
Delphi-Quellcode:
...
if PackageModule = 0
then PackageLoad(mySelData.FModName+'
.BPL');
//if the ExecuteChild procedure
//was found in the package, call it
if Assigned(Execute)
then
begin
myDLLOUT:=Execute(myDLLIN);
strPackageName:=myDLLOUT.ModName;
end;
end;
...
Die "Execute"-Methode eines Moduls sieht so aus, wobei myDLLIN im Impmentation-Abschnitt eines Moduls mit myDLLIN: TDLLIN; deklariert ist:
Delphi-Quellcode:
function Execute(aDLLIN: TDLLIN): TDLLOut;
begin
myDLLIN:=aDLLIN;
TFrmDummy.Create(Application);
myDLLOut:=TDLLOut.Create;
myDLLOut.DBID:=1234;
myDLLOUT.ModName:='TESTMODUL';
Result:=myDLLOut;
end;
In meiner MainApp kann ich jetzt auf myDLLOUT zugreifen, funktioniert soweit.
Wenn ein Modul über einen manuell auf die Modulform gesetzten "Schliessen"-Button geschlossen wird (habe bsnone gesetzt) passiert im Modul folgendes:
Delphi-Quellcode:
procedure TfrmDUMMY.SpeedButton1Click(Sender: TObject);
begin
Close;
end;
und
Delphi-Quellcode:
procedure TfrmDUMMY.FormClose(Sender: TObject; var Action: TCloseAction);
begin
myDLLOUT.Free;
myDLLOUT:=nil;
Action:=caFree;
end;
In der MainApp gibt jetzt allerdings ein
if Assigned(myDLLOUT)
ein "True" zurück. Eigentlich wollte ich so abfragen, ob ein Modul = MDIChild manuell geschlossen wurde, was leider nicht funktioniert. Hierdurch möchte ich das Modul entladen, wenn das Modulfenster vom User explizit geschlossen wird. Der andere Fall des "Modulentladens" folgt jetzt:
Will der Anwender aus dem Menü ein anderes Modul aufrufen, mache ich folgendes, was offensichtlich funktioniert - sprich das bisherige myDLLOUT-Objekt wird zerstört -, denn der Aufruf eines neuen Moduls erstellt ja wieder ein neues myDLLOUT-Objekt, mit dem ich problemlos arbeiten kann.
Delphi-Quellcode:
// Unload Package if Form exists
if frmMain.MDIChildCount>0
then
begin
frmMain.ActiveMDIChild.Close;
frmMain.ActiveMDIChild.Free;
UnloadPackage(PackageModule);
PackageModule:=0;
strPackageName:='
';
end;
Gruß Igotcha