AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

In DLLs wird kein OnClose ausgelöst?

Offene Frage von "jaenicke"
Ein Thema von mcinternet · begonnen am 13. Apr 2019 · letzter Beitrag vom 14. Apr 2019
Antwort Antwort
mcinternet

Registriert seit: 22. Apr 2010
Ort: Odenwald
193 Beiträge
 
Delphi 10.3 Rio
 
#1

In DLLs wird kein OnClose ausgelöst?

  Alt 13. Apr 2019, 15:33
Hallo zusammen,

irgendwie verstehe ich die Welt nicht mehr

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
Jörg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#2

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 13. Apr 2019, 15:47
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
  Mit Zitat antworten Zitat
mcinternet

Registriert seit: 22. Apr 2010
Ort: Odenwald
193 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 13. Apr 2019, 15:52
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 .
Ich habe jetzt mal den Destructor Destroy; override; eingebaut - auch dieser wird nicht abgearbeitet. ..... seltsam....

Gruss

mcinternet
Jörg
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#4

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 13. Apr 2019, 15:56
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

Geändert von EWeiss (13. Apr 2019 um 16:12 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.170 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 13. Apr 2019, 16:29
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.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
mcinternet

Registriert seit: 22. Apr 2010
Ort: Odenwald
193 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 13. Apr 2019, 16:36
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
Jörg
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
672 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 14. Apr 2019, 11:44
Hallo zusammen,

irgendwie verstehe ich die Welt nicht mehr

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.
Peter Below
  Mit Zitat antworten Zitat
EWeiss
(Gast)

n/a Beiträge
 
#8

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 14. Apr 2019, 12:37

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

Geändert von EWeiss (14. Apr 2019 um 12:56 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.330 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: In DLLs wird kein OnClose ausgelöst?

  Alt 14. Apr 2019, 21:00
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:24 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