Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   In DLLs wird kein OnClose ausgelöst? (https://www.delphipraxis.net/200361-dlls-wird-kein-onclose-ausgeloest.html)

mcinternet 13. Apr 2019 15:33

In DLLs wird kein OnClose ausgelöst?
 
Hallo zusammen,

irgendwie verstehe ich die Welt nicht mehr :shock:

Ich habe eine Applikation in viele Dlls aufgeteilt, welche an TabSheets an der Mainform angedockt werden (CreateParented).
Das funktioniert soweit so gut. Nun habe ich eine DLL, welche selbst ein weiteres Formular an ein Panel andockt. Wenn diese DLL geladen ist, wird beim Schließen der Applikation ein Fehler ausgeworfen: Im Projekt ... ist eine Exception der Klasse EOSError mit der Meldung 'Systemfehler', Code 1400. Ungültiges Fensterhandle aufgetreten.
Beim Debuggen stelle ich fest, dass beim Beenden des Programmes das OnClose-Ereignis in den DLL-Forms NICHT ausgelöst wird.

Die dlls sind dynamisch, Aufbau:

Code:
library Kunden;


uses
  Sharemem,
  System.SysUtils,
  VCL.Forms,
  Windows,
  System.Classes,
  formdll in '..\Common\formdll.pas' {DllForm},
  uConsts in '..\Common\uConsts.pas',
  uDbMain in '..\Common\uDbMain.pas';

{$R *.res}

procedure Create_Form(pn:HWND; dbm : TDbMain; gl : TGlobals; re, nr : Integer);
begin
  frmKunden            := TfrmKunden.CreateParented(pn); // hier wird angedockt
  frmKunden.BorderStyle := bsNone;
  frmKunden.Globals    := gl;
  frmKunden.dbm        := dbm;
  frmKunden.Recht      := re;
  frmKunden.PageNr     := nr;
  frmKunden.Init;
  frmKunden.Show;    // Muss zuletzt sein, da sonst gl und dbm nicht definiert sind
end;

exports
Create_Form;



begin
end.
Alles andere funktioniert wirklich gut, nur halt gibt es bei einer Form (sie sind alle gleich) das Problem mit dem ungültigen Handle beim Schließen. - Diese Form erzeugt wieder selbst eine weitere (kleine) Form, welche mittels ... parent = Panel1 angedockt wird.

Und das Wundersame ist, dass in den Dlls das OnClose nicht ausgelöst wird!

Gruss

mcinternet

EWeiss 13. Apr 2019 15:47

AW: In DLLs wird kein OnClose ausgelöst?
 
Zitat:

Beim Debuggen stelle ich fest, dass beim Beenden des Programmes das OnClose-Ereignis in den DLL-Forms NICHT ausgelöst wird.
Wie wird OnClose aufgerufen?

Kann es sein das du die Form die mit dem Parent dieser Form erstellt wird nicht vorher geschlossen wird?
Du musst also erst die kleine Form frei geben bevor du die Form freigibst welche dieses Fenster erzeugt.

gruss

mcinternet 13. Apr 2019 15:52

AW: In DLLs wird kein OnClose ausgelöst?
 
Zitat:

Zitat von EWeiss (Beitrag 1430226)
Wie wird OnClose aufgerufen?

Kann es sein das du die Form die mit dem Parent dieser Form erstellt wird nicht vorher geschlossen wird?
Du musst also erst die kleine Form frei geben bevor du die Form freigibst welche dieses Fenster erzeugt.

gruss

Das OnClose ist an die jeweilige Form gebunden, jede hat diverse Klassen, welche freigegeben werden müssen. Das Wundersame ist dabei, dass, obwohl das OnClose nicht abgefeuert wird, keine Fehlermeldungen aufgepoppt sind.
Das Beenden des Programmes läuft auch über eine der eingebetteten DLLs welche hat das Untermenü "Beenden" hat, oder halt über den Klick oben Rechts :roll: .
Ich habe jetzt mal den Destructor Destroy; override; eingebaut - auch dieser wird nicht abgearbeitet. ..... seltsam....

Gruss

mcinternet

EWeiss 13. Apr 2019 15:56

AW: In DLLs wird kein OnClose ausgelöst?
 
Trenne dich einfach von deinem Event ich denke so wird dein OnClose aufgrufen..
Und versuche es mal testweise mit einer einfachen Message.

Prüfen ob das Parent existiert.. (Das kleine Fenster)
dann Post oder besser SendMessage WM_DESTROY an das jeweilige Fenster schicken.

Anschließend dein Fenster mit OnClose beenden wenn es nicht geht auch hier ein WM_DESTROY abschicken.

PS:
Aber auch ein DestroyWindow(dein Handle) sollte die gewünschte Aktion auslösen.
Es ist von jeher ein Problem Delphi VCL (Forms) innerhalb DLL's zu implementieren.
Ich erstelle meine Fenster alle von Hand und kann die VCL getrost vergessen.
Hatte noch nie Probleme damit ein Fenster(nicht Form) in einer DLL zu beenden.

gruss

Bernhard Geyer 13. Apr 2019 16:29

AW: In DLLs wird kein OnClose ausgelöst?
 
Zitat:

Zitat von mcinternet (Beitrag 1430223)
Ich habe eine Applikation in viele Dlls aufgeteilt, welche an TabSheets an der Mainform angedockt werden (CreateParented).

Und wieso macht man sowas und holt sich die BPL-Hölle freiwillig ins Haus.

ich hoffe du nutzt gemeinsame Runtime-Packages. Sonst ist dein Ansatz ein Reines Glückspiel "lebende" Objekte zwischen Exe und Dll auszutauschen.

mcinternet 13. Apr 2019 16:36

AW: In DLLs wird kein OnClose ausgelöst?
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1430231)
Und wieso macht man sowas und holt sich die BPL-Hölle freiwillig ins Haus.

ich hoffe du nutzt gemeinsame Runtime-Packages. Sonst ist dein Ansatz ein Reines Glückspiel "lebende" Objekte zwischen Exe und Dll auszutauschen.

Ja, alles ist gemeinsame Runtime. Zwischen den Modulen werden, außer den Startparametern keine Daten übergeben.

Gruss

mcinternet

peterbelow 14. Apr 2019 11:44

AW: In DLLs wird kein OnClose ausgelöst?
 
Zitat:

Zitat von mcinternet (Beitrag 1430223)
Hallo zusammen,

irgendwie verstehe ich die Welt nicht mehr :shock:

Ich habe eine Applikation in viele Dlls aufgeteilt, welche an TabSheets an der Mainform angedockt werden (CreateParented).
Das funktioniert soweit so gut. Nun habe ich eine DLL, welche selbst ein weiteres Formular an ein Panel andockt. Wenn diese DLL geladen ist, wird beim Schließen der Applikation ein Fehler ausgeworfen: Im Projekt ... ist eine Exception der Klasse EOSError mit der Meldung 'Systemfehler', Code 1400. Ungültiges Fensterhandle aufgetreten.
Beim Debuggen stelle ich fest, dass beim Beenden des Programmes das OnClose-Ereignis in den DLL-Forms NICHT ausgelöst wird.

Alles andere funktioniert wirklich gut, nur halt gibt es bei einer Form (sie sind alle gleich) das Problem mit dem ungültigen Handle beim Schließen. - Diese Form erzeugt wieder selbst eine weitere (kleine) Form, welche mittels ... parent = Panel1 angedockt wird.

Und das Wundersame ist, dass in den Dlls das OnClose nicht ausgelöst wird!

Gruss

mcinternet

Tue Dir einen Gefallen und verwende packages, nicht DLLs. Anyway: wenn Du eine Form nicht als top-level window verwendest, sondern sie in ein child window (control) verwandelst, ändert sich einiges in der Art der messages, die das Form im gedockten Zustand bekommt. Dadurch funktionieren einige der events nicht mehr, da das Form einfach die messages nicht mehr bekommt, die den event auslösen (OnClose ist so ein Fall). Das wird noch verschärft, wenn Du ein Form mit CreateParented an einen Parent bindest und nicht durch setzten der Parent-Eigenschaft. Dadurch wird einiges umgangen, was die VCL sonst bei der Verwaltung von Controls macht, z. B. werden nicht mehr alle der VCL-internen messages, die von der message loop in TApplication.Run erzeugt werden, an das eingebettete Form und seine Controls weitergegeben.

Alles in allem ist dein Ansatz grundlegend falsch (sorry). Forms sind nicht dafür gedacht, als Controls irgendwo eingebettet zu werden; dafür gibt es Frames. CreateParented sollte nur verwendet werden, wenn man ein Delphi-Control in ein nicht-VCL Control einbetten will. Und diese ganze Verteilerei von UI-Elementen auf verschiedenen Module (plug-in Architektur) ist zwar durchaus ein gutes Design für manche Anwendungen, aber es funktioniert nur mit Packages vernünftig, da nur dadurch eine vollständige Integration in die Hostanwendung möglich wird. Bei DLLs ist das nicht im gleichen Maße gegeben, auch wenn man alle Module mit run-time packages baut.

Egal ob man DLLs oder packages verwendet, für diese Art der Integration hat man immer noch die Notwendigkeit, das alle Module mit der gleichen Delphi-Version kompiliert werden müssen.

Es geht zwar auch anders, aber dann muss man eine andere Architektur verwenden, die es einerseits möglich macht, die plug-ins völlig unabhängig von der Hostanwendung zu halten (keine gemeinsame RTL oder VCL oder memory manager), und andererseits die Elemente nachflickt, die für eine reinbungslose Kommunikation von Host und Plugin notwendig sind (alle Interaktion geht über COM-kompatible Interfaces oder windows messages). Das ist nicht nur ein ziemlicher Aufwand, den man allerdings nur einmal betreiben muss (Stichwort Plug-in framework), sonder erfordert auch wirklich detailierte Kenntnisse darüber, wie die VCL solche Sachen wie Tab order, keyboard shortcuts, action configuation etc. realisiert, damit man sicherstellen kann, dass das alles auch für die eingebetteten Plugins funktioniert, auch wenn sie mit einer anderen VCL-Version gebaut wurden.

EWeiss 14. Apr 2019 12:37

AW: In DLLs wird kein OnClose ausgelöst?
 
:thumb:
Wie ich schon sagte..

Zitat:

Es ist von jeher ein Problem Delphi VCL (Forms) innerhalb DLL's zu implementieren.
Ich erstelle meine Fenster alle von Hand und kann die VCL getrost vergessen.
Hatte noch nie Probleme damit ein Fenster(nicht Form) in einer DLL zu beenden.
Forms sind von jeher nichts anderes als Container was sollte mich dazu veranlassen diese in eine DLL zu Importieren.

gruss

jaenicke 14. Apr 2019 21:00

AW: In DLLs wird kein OnClose ausgelöst?
 
Wir haben in unserer Standard-DLL-Schnittstelle auch eine Shutdown-Routine, die vor dem Entladen der DLL aufgerufen wird. Da werden dann alle Interface-Referenzen, Objekte (wie hier das Formular) usw. gekillt.

Auf diese Weise haben wir damit keine Probleme mehr.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz