![]() |
WM_USER-Nachricht an alle Dialogelemente schicken
Hallo zusammen,
ich möchte gerne eine WM_USER-Nachricht an alle Dialogelemente meiner Anwendung, die aus verschiedenen Formularen besteht, schicken. Ich habe dazu eine eigene Klasse von TStaticText erstellt, die in ihrer überschriebenen Prozedur WndProc auf diese Nachricht entsprechend reagieren soll:
Delphi-Quellcode:
Ich löse die Nachticht mit
interface
type TMyStaticText = class(TStaticText) procedure WndProc(var: Msg : TMessage);override; end; var WM_MEINENACHRICHT : Cardinal; implementation procedure TMyStaticText.WndProc(var Msg : TMessage); begin if Msg.Msg = WM_MEINENACHRICHT then begin // mach jetzt etwas end; inherited WndProc(var Msg : TMessage); end; begin WM_MEINENACHRICHT := RegisterWindowMessage('Meine Nachricht'); end.
Delphi-Quellcode:
aus.
PostMessage(HWND_BROADCAST,WM_MEINENACHRICHT,Integer(self),0)
Das funktioniert leider nicht, ich habe nach längerer WWW- und Forumssuche kapiert, daß die Nachricht nur an die Top-Level-Fenster geschickt wird, nicht aber an die untergeordneten Fenster bzw. Dialogelemente. Nun habe ich eine - in meinen Augen - ziemlich unelegante Lösung gefunden, indem ich die Prozedur WndProc der einzelnen Formulare überschreibe und dort dann bei Vorliegen der Nachricht WM_MEINENACHRICHT diese explizit an die Handles aller TStaticText-Elemente des jeweiligen Formulars weiterreiche. Diese Lösung befriedigt mich nicht, weil sie meiner Menung nach unnötigen Programmieraufwand bedeutet. Meine Frage lautet nun, ob es eleganter möglich ist, eine selbst generierte Nachricht an alle Dialogelemente aller Formulare einer Anwendung zu schicken? Danke & Grüße, Lagopus. |
Re: WM_USER-Nachricht an alle Dialogelemente schicken
Huhu!
Also du brauchst die WNDProc nicht überschreiben. eine definition einer funktion reicht da vollkommen aus:
Delphi-Quellcode:
damit hast du dann die message ohne das überschreiben in deinen formularen.
uses
Windows; const UM_MEINENACHRICHT = WM_USER + 1337; procedure UMMEINENACHRICHT(var Message: TMessage); message UM_MEINENACHRICHT; dort kannst du dann mit
Delphi-Quellcode:
an die Statics weitergeben.
for i:= 0 to ComponentCount - 1 do
begin if Components[i] is TMeinStaticText then begin (Components[i] as TMeinStaticText).MachWas(); end; end; Um den Broadcast zu umgehen könntest du auch beim erzeugen des formulars dich in eine globale programmliste eintragen und sagen "hier sind meine static's bitte sag denen bescheid wenn du irgendwas tun magst". diese lösung wäre dann geeignet wenn du keine nachrichten hin und her blasen magst. ich hoffe das hier is fehlerfrei.. gerade ausm gedächtnis getippt Gruß Reli |
Re: WM_USER-Nachricht an alle Dialogelemente schicken
Hallo Christopher,
erst einmal vielen Dank für Deine schnelle Antwort. Dein Ansatz sieht sehr vielversprechend aus, ich teste das gleich mal aus und gebe dann Bescheid. Danke einstweilen und Grüße, Lagopus. |
Re: WM_USER-Nachricht an alle Dialogelemente schicken
Ah ganz übersehen war ja dein erster Beitrag :-) da fehlt ja noch das obligatorische "Willkommen in der DP" :dp:
Gruß Reli |
Re: WM_USER-Nachricht an alle Dialogelemente schicken
Hallo Christopher,
Zitat:
Zitat:
Zitat:
Danke & Grüße, Lagopus. Nachtrag: Das Problem liegt definitiv daran, daß PostMessage(HWND_BROADCAST,...) nicht bei den Formularen ankommt. Sende ich explizit via PostMessage(FormX.Handle,...), dann klappt's. |
Re: WM_USER-Nachricht an alle Dialogelemente schicken
Hm okay. Das hab ich nicht bedacht.
Bau dir eine Klasse, dessen objekt irgendwo für alle zugänglich liegt. sobald ein formular startet meldet es sich an dem objekt an (FormularListe.AddForm( self );) und beim abmelden schmeisste die form wieder aus der liste (FormularListe.RemoveForm( self );). wenn du jetzt an alle deine nachricht schicken möchtest dann gehst du die liste durch und schickst an jede form die da drin ist die nachricht (FormularListe.SendToAll;)
Delphi-Quellcode:
gruß
for i:=0 to ForularListe.Count -1 do
begin Postmessage( FormularListe[i].Handle, UM_DEINENACHRICHT, 0, 0 ); end; reli |
Lösung:
Hallo zusammen,
hallo Christopher, nachdem ich ziemlich oft beim Durchsuchen des WWW und des Forums gelesen habe, daß ein Broadcast via PostMessage(HWND_BROADCAST,...) nicht ganz ungefährlich ist, da so JEDE auf dem System laufende Applikation diese Meldung erhält, habe ich mein Problem entsprechend anders gelöst, dank der Mithilfe von Christopher: Ich suche mir einfach alle Formulare meiner Applikation zusammen und schicke dann expliziert an ihre Handles meine Nachricht, das sieht dann so aus:
Delphi-Quellcode:
In den jeweiligen Formularen binde ich eine eigene Prozedur ein, die die Nachricht WM_MEINENACHRICHT empfängt und auf die gewünschten Komponenten verteilt:
Procedure TForm1.Button1Click(Sender:TObject);
var i : integer; begin For i := 0 to Application.ComponentCount-1 do begin if Application.Components[i] is TForm then begin PostMessage((Application.Components[i] as TForm).Handle,WM_MEINENACHRICHT,Integer(self),0); end; end; end;
Delphi-Quellcode:
So funktioniert's und die böse Broadcast-Methode ist vermieden.
type
TForm1 = class(TForm) . . procedure WMMEINENACHRICHT(var Msg : TMessage);message WM_MEINENACHRICHT; . . end; implementation procedure TForm1.WMMEINENACHRICHT(var Msg:Tmessage); var i : integer; begin for i:= 0 to ComponentCount - 1 do begin if Components[i] is TMeinStaticText then begin (Components[i] as TMeinStaticText).MachWas(); end; end; end; Vielen Dank an Christopher für die Hilfe! Grüße, Lagopus. |
Re: WM_USER-Nachricht an alle Dialogelemente schicken
Hallo Christopher,
Zitat:
Grüße, Lagopus. P. S.: Danke auch für Deinen Willkommensgruß hier im Forum, ich nehme an, es wird nicht mein letzter Thread hier sein ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:27 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz