Windowsnachricht an eigene Klasse



  • Hallo zusammen

    Ich möchte eine eigene Windowsnachricht aus einem Workerthread an meinen GUI-Thread senden. Diese Nachricht soll signalisieren, dass z.B. neue Daten empfangen wurden.

    Wenn ich die Nachricht an mein Fenster schicke, klappt das natürlich und die eingetragene Methode wird aufgerufen. Nun möchte ich das aber an ein anderes Objekt schicken, welches eigentlich keine GUI-Klasse ist.

    Damit ich nun aber Nachrichten empfangen kann, habe ich mir überlegt, diese Klasse zusätzlich von CWnd erben zu lassen. Nun kann ich mit DECLARE_MESSAGE_MAP() usw. eine Messagemap definieren und auch für die entsprechende Nachricht eine Methode hinterlegen. Aber leider wird diese nicht aufgerufen, wenn ich aus dem anderen Thread die Nachricht versende (PostMessage).

    Worauf muss ich achten, damit ich eine Nachricht an ein bestimmtes Objekt schicken kann? Und welche Vorgaben muss dieses Objekt erfüllen, damit es die Fähigkeit hat, Nachrichten zu empfangen?

    Ich möchte damit den "Umweg" vermeiden, alles über mein Fenster laufen zu lassen. Denn sonst müsste dieses alle internen Nachrichten kennen und bei Empfang einer Nachricht, diese an das entsprechende Objekt weiterleiten.



  • Momentan habe ich es so umgesetzt, dass der GUI-Thread nach Änderungen schaut, wenn er im Idle ist ( wenn WM_KICKIDLE im Dialog empfangen wird). Aber auch diese Lösung gefällt mir nicht so gut, da ich hierbei nicht auf spezielle Ereignisse reagieren kann. Ich muss nachsehen, ob sich was getan hat.



  • DarkGuardian schrieb:

    Worauf muss ich achten, damit ich eine Nachricht an ein bestimmtes Objekt schicken kann? Und welche Vorgaben muss dieses Objekt erfüllen, damit es die Fähigkeit hat, Nachrichten zu empfangen?

    Wenn ich mich nicht irre, dann kannst du ein HWND dem PostMessage mitgeben (das dürfte dann aber nicht die Methode PostMessage aus der MFC sein sondern ::Postmessage()).
    Die zweite Frage hast du schon beantwortet: du brauchst eine MessageMap und auch Methoden, um auf gewisse Nachrichten reagieren zu können. Die Variante mit dem Idle ist genauso tricky wie sich in einer Klasse ständig mit GetMessage() nach Nachrichten zu lauschen.



  • Hallo AndyDD

    Ich habe aber nur ein HWND in meiner Klasse, wenn diese auch ein GUI-Element ist. Nun habe ich aber eine Logikklasse (also ohne GUI), die Nachrichten empfangen soll.

    Als Test habe ich diese trotzdem von CWnd erben lassen. Zwar konnte ich dann eine MessageMap einstellen und auch ein HWND war verfügbar. Aber über die Nachrichten wurden keine Methode ausgelöst. Wenn ich das Ganze in mein Hauptfenster verlagere, werden die Methoden bei Nachrichten aufgerufen. Daher vermute ich, dass da noch etwas Anderes benötigt wird, damit die Nachrichten entgegengenommen werden.

    Ich möchte auch nicht zyklisch GetMessage aufrufen, da ich dazu auch ein entsprechendes Konstrukt einbauen muss. Und die Fensterklassen machen das ja auch automatisch.

    Irgendeine Idee, wie ich das umsetzen kann?


  • Mod

    Dann zeig mal Code.



  • Hi

    Leider habe ich meinen Versuch nicht mehr vorliegen. Daher kann ich das nicht mal eben hier reinstellen. Das ist natürlich ärgerlich, aber ich kann es momentan auch nicht eben wieder neu bauen. Da fehlt mir die Zeit zu.

    Kennt denn jemand ein entsprechendes Beispiel, bei dem ein Objekt, welches eigentlich keine GUI ist, trotzdem Nachrichten wie ein GUI-Element empfängt? Mit der Borland VCL habe ich das schön öfters gemacht, aber mit MFC scheint das doch etwas anders zu gehen.


  • Mod

    Es gibt keine Nachrichten ohne Fenster...
    D.h. man kann nicht eine Klasse erzeugen und dieser etwas sendenmit Send/PostMessage.

    Ausnahme sind Threadnachrichten (PostThreadMessage). Aber selbst für die benötigt man eine laufende Nachrichtenschleife. In diesem Fall ist der Empfänger ein CWinThread Objekt.



  • Da es keine Nachrichten ohne Fenster gibt, habe ich ja die Klasse vom Fenster erben lassen. Mit den VCL-Elementen reicht das schon und man kann Nachrichten direkt empfangen (der Umweg über das sonst unsinnige Erben vom Fenster ist natürlich unschön).

    Wenn ich meine Klasse von CWnd erben lassen, empfängt diese aber nicht gleich Nachrichten, auch wenn eine Messagemap definiert ist. Wahrscheinlich muss das Objekt noch in die Messagepump eingehängt werden, damit die Nachrichten auch ankommen. Und ich vermute, dass dieses mit VCL TForm durch die Wrapperklasse automatisch erledigt wird.

    Gibt es denn in der MFC die Möglichkeit, ein Objekt in die Messagepump einzuhängen? Oder geht das nur durch die Parentbeziehung zu einem anderen GUI-Element? Wenn ich mich recht erinnere, werden ja die Nachrichten vom Hauptfenster weiter an die Children geleitet (hierarchische Struktur). Das würde natürlich meine Idee ad absurdum führen, da der Aufwand der Umstrukturierung nicht mehr im Verhältnis zum Nutzen steht.


  • Mod

    Nein!
    Wenn das fenster erzeugt wurde, dann bekommst Du auch Nachrichten. Punkt.
    Da ist gar nichts extra zu machen. Sofern das Fenster eben auch in dem Thread erzeugt wurde, das eine Messagepunp hat.

    Grundsätzlich gibt es keine hierarchische Struktur. Es gibt für WM_COMMAND Nachrichten nur ein Routing...

    Zeige Code, was nicht geht!


Anmelden zum Antworten