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/)
-   -   Delphi Registrierung für Broadcast für Window Messages umgehen (https://www.delphipraxis.net/120036-registrierung-fuer-broadcast-fuer-window-messages-umgehen.html)

christophspaeth 4. Sep 2008 20:04


Registrierung für Broadcast für Window Messages umgehen
 
Hallo zusammen,

ich habe einen WebService für Apache 2.2.3, der dummerweise die unit Forms einbindet und damit wird die Anwendung anscheinend automatisch registriert, Broadcasts für WindowsMessages anzunehmen.

Wenn jetzt keine (geeignete?) Message Loop vorhanden ist, ist es nicht mehr möglich, Einstellungen im Internet Explorer zu ändern, weil der beim Übernehmen der Änderung eine Nachricht an alle Fenster schickt (laut Spy++ könnte das WM_SETTINGSCHANGE sein), und dann so lange wartet bis die Nachricht überall abgearbeitet ist (oder der entsprechende Prozess beendet).

Bevor jemand anders die berechtigte Frage stellt, warum man Forms in einen Webservice einbindet: Altlast, die leider nicht von heute auf morgen entsorgt werden kann.

Das ich nicht drum rum komme, die ganzen Units aufzuräumen ist klar, aber wenn jemand einen Tipp hätte, wie ich das Problem bis dahin umgehen kann, bzw. was überhaupt *genau* dafür verantwortlich ist, das wär super!
Ich bin auch noch nicht dahintergekommen, ob Forms jetzt dafür verantwortlich ist, dass der Apache überhaupt benachrichtigt wird, oder ob da eher was verbogen wird, das verhindert, dass der Apache die Message richtig verarbeitet.

Um das Problem zu reproduzieren, muss man dem Delphi erstmal Apache 2.2 beibringen, dann ein einfaches Apache-Modul machen eben z.B. einen WebService und irgendwo Forms einbinden.
In Apache einbinden, Apache starten und versuchen, die Interneteinstellungen in IE zu ändern -> IE hängt. Apache beenden -> IE sollte weitermachen und Settings-Fenster solte zugehen. Forms raus, kompilieren, apache starten, interneteinstellungen ändern -> funzt wieder.

Den naheliegenden Pfusch/Workaround, in einem Modul einen Thread zu starten, der dann nur damit beschäftigt ist, alle paar (hundert) Millisekungen (Forms.)Application.ProcessMessages() aufzurufen hab ich auch schon probiert, hatte aber keinen Erfolg damit.

Noch ein Hinweis: Im Apache 1.3 macht Forms anscheinend keine Probleme.

Danke für's Lesen (und noch mehr Dank für's Antworten *g*)
Chris

Apollonius 4. Sep 2008 20:13

Re: Registrierung für Broadcast für Window Messages umgehen
 
Das Problem ist, dass das Application-Objekt ein Fenster hat. Eine äußerst unsaubere Lösung wäre es, entweder einen Hook zu installieren, um die Fenstererstellung zu verhindern, oder aber im Initialization-Abschnitt einer Unit, die vor Forms und Controls eingebunden wird, IsLibrary auf True zu setzen. TApplication.Create prüft den Wert dieser Variablen. Ein Problem ist jedoch, dass dann auch andere Initialization-Abschnitte den falschen Wert von IsLibrary verwenden.

Meiner Meinung nach ist das jedoch auch ein Bug im Internet Explorer. Er sollte SendMessageTimeout o.Ä. verwenden.

christophspaeth 5. Sep 2008 08:56

Re: Registrierung für Broadcast für Window Messages umgehen
 
Hallo Apollonius,

danke für die Antwort.

Das mit dem IsLibrary werde ich mal als workaround probieren. Wenn ich die Delphi-Hilfe richtig verstehe, sollte das aber sowieso schon auf true stehen, weil mein Modul ja eine dll ist.
Folglich sehe ich momentan auch kein Problem bzw. keine Unschönheit darin, das selber richtig zu setzen, falls das fälschlicherweise auf false steht. Bitte korrigieren, wenn ich falsch liege!

Und Bug ist so ein hartes Wort. Sagen wir "Unschönheit". *Wenn* alle anderen Programme ihre Messages richtig verarbeiten, hat der IE ja auch kein Problem ;-)

Schönen Freitag!
Chris

Edit: Das mit dem IsLibrary := true; scheint nicht zu funktionieren; der IE bleibt immer noch stehen. Ich hab jetzt mal eine "leere" unit erstellt:
Delphi-Quellcode:
unit Unit1;
interface
implementation
initialization
  IsLibrary := true;
end;
und in mein Testprojekt eingefügt:
Delphi-Quellcode:
unit IMyImpl;
interface
uses
  Unit1,        //IsLibrary := true;
  Windows,
  Types,
  InvokeRegistry,

  Forms, // wenn ich die rausschmeiße gehts

  XSBuiltIns,
  IMyIntf;
type
  ...

christophspaeth 10. Sep 2008 09:58

Re: Registrierung für Broadcast für Window Messages umgehen
 
Hallo zusammen,

anscheinend ist es nicht nur die Unit Forms, die Probleme macht. Wir haben jetzt aus einem Projekt mit Hilfe eines Dependency Scanners alle vorkommnisse von Forms und Dialogs entfernt, da Problem besteht aber weiterhin. Vor allem haben wir festgestellt, dass wir gar nicht alle WebServices komplett von Forms befreien können, weil wir z.B. auf die Unit Printer zugreifen müssen, die wiederum Forms mitbringt.

Fallen jemandem noch andere kritische Units ein, die eigenmächtig Fenster erzeugen? Oder wie ich z.B. für Debugausgaben erstmal sämtliche Fenster auflisten kann.
Ich bin für jeden Tipp dankbar.
Apollonius, wie hattest du das mit dem Hook denn gemeint?

Gruß Chris

P.S.1: Ich hab immer von IE 6 geredet; erste Tests erwecken den Eindruck, dass der IE 7 sogar ein Timeout verwendet
P.S.2: Ich hab jetzt etwas widersprückliche Angaben erhalten, aber anscheinend ist der Apache 1.3 auch davon betroffen

Apollonius 10. Sep 2008 16:45

Re: Registrierung für Broadcast für Window Messages umgehen
 
Ah, ich hatte nicht mitbekommen, dass es sich um eine DLL handelt.

Ich vermute weiterhin, dass irgendein Fenster erzeugt wird. Ich habe aber keine Ahnung, wo das sein könnte - Application fällt anscheinend raus. Du könntest versuchen, mit Debug-DCUs zu kompilieren und dann mit dem Debugger durch den gesamten Initialisierungscode zu laufen und nach Aufrufen von CreateWindowEx zu suchen. Etwas besseres fällt mir gerade nicht ein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:09 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