MFC Globale Messages



  • Ich erläutere zuerst meine Programstruktur, zwecks besserer Beurteilung:

    Ich habe eine dialogbasierte (!) Anwendung erstellt, die bestimmte Dinge errechnet, zeichnet und auf normale Messages reagiert - alles in einem Dialog.
    Diese Anwendung erzeugt manuell 1 weiteren CDialog, der selbst wiederum exakt 10 Custom Controls anzeigt, der Inhalt selbiger wird natürlich über CWnds gezeichnet die in einer seperaten Klassen liegen (ebenso wie der 2. CDialog). Nun reagiere ich auf einen Doppelklick innerhalb der CWnds, erstelle einen CColorDialog und lese das Ergebnis aus. Eben dieses soll an den ursprünglichen, ersten CDialog (sozusagen die Basis aller Dinge) übergeben werden. Ich will aber keine umständlichen Objektbeziehungen schaffen sondern das Ergebnis per globaler Message raushauen.

    Die enstprechende Message habe ich bereits über

    ::RegisterWindowMessageW
    

    erstellen und speichern lassen, und zwar in einem

    static const UINT
    

    in einem Header, der bei allen Klassen eingebunden wird.

    Die empfangende Klasse (wir erinnern uns: der 1. CDialog) hat folgendes in der .cpp stehen:

    ON_REGISTERED_MESSAGE(msg_colorchange, OnColorChange)
    

    , die Methode

    afx_msg LRESULT OnColorChange(WPARAM, LPARAM)
    

    wurde natürlich deklariert und definiert.

    Die sendende Klasse "schreit" auf diese Art u. Weise:

    ::SendWindowMessageW(HWND_BROADCAST, msg_colorchange, (WPARAM)id, (LPARAM)dialog.GetColor())
    

    --> der Rückgabewert ist in diesem Fall ungleich 0, was ja laut MSDN "erfolgreich" bedeuten soll.

    Nun ist meine Fragestellung einfach:
    Habe ich etwas vergessen? Wieso funkioniert das nicht?

    P.S.: msg_colorchange ist natürlich der static const UINT, der über

    RegisterWindowMessageW
    

    erstellt wurde - man sollte evtl. erwähnen dass es immer (!) eine Zahl grösser als 1024 (und somit grösser als WM_USER) ist.

    P.P.S.: die empfangende Methode im 1. CDialog wird niemals betreten, es kommt also scheinbar auch nichts an.



  • Ich denke, ich habe mit etwas "wie dumm waren die MFC-Entwickler WIRKLICH?" - Überlegung die Ursache gefunden:

    Systemweite Messages werden sinnloserweise nicht an Child-Windows weitergereicht, und eben jenes ist ein CDialog, wenn man den ProjektAsisstenten verwendet 🤡

    MFC ist scheisse.



  • (1) Die Lösung ist ein bißchen schwach. Das übergeben des Parent-Dialogs ist nun wirklich kein Kunststück.

    Im schlimmsten Fall kannst du in der MFC mittels GetParent dir den Parent-Dialog holen, mit IsKindOf() prüfen, ob es tatsächlich eine Instanz deiner Klasse ist und dann dorthin casten.

    (2) Wenn mein Killerprogramm dummerweise bei deiner Message blockiert, hängt deine Anwendung. Wenn ich das in einem Workerthread mache, läuft meine Anwendung munter weiter, deine nicht.

    (3) HWND_BROADCAST ist ein Broadcast an alle Top Level Windows. So haben sich das die Jungs von der Win32 API überlegt, und ich bin sehr froh daß sie Broadcast messages nicht blind an tausende von Fenstern weiterreichen (Falls eine Anwendung as braucht, kann sie's ja selbst machen - SendmessageToDescendants), und das die Jungs von der MFC die Message genauso behandeln wie die WIn32 API auch.

    (4) Registrierte Messages sind eine begrenzte Ressource, die nur verwendet werden sollten wenn wirklich nötig.



  • peterchen schrieb:

    (1) Die Lösung ist ein bißchen schwach. Das übergeben des Parent-Dialogs ist nun wirklich kein Kunststück.

    Tu ich aber nicht ... ich HOLE mir den Parent-Dialog

    peterchen schrieb:

    Im schlimmsten Fall kannst du in der MFC mittels GetParent dir den Parent-Dialog holen, mit IsKindOf() prüfen, ob es tatsächlich eine Instanz deiner Klasse ist und dann dorthin casten.

    IsKindOf() hatte ich vergessen, danke

    peterchen schrieb:

    (2) Wenn mein Killerprogramm dummerweise bei deiner Message blockiert, hängt deine Anwendung. Wenn ich das in einem Workerthread mache, läuft meine Anwendung munter weiter, deine nicht.

    Es soll ja auch kein funktioniertAbsolutImmerweilichderbesteProgrammiererderWeltbin - Programm werden ... is eher eine Machbarkeitsstudie / Lernprojekt

    peterchen schrieb:

    (3) HWND_BROADCAST ist ein Broadcast an alle Top Level Windows. So haben sich das die Jungs von der Win32 API überlegt, und ich bin sehr froh daß sie Broadcast messages nicht blind an tausende von Fenstern weiterreichen (Falls eine Anwendung as braucht, kann sie's ja selbst machen - SendmessageToDescendants), und das die Jungs von der MFC die Message genauso behandeln wie die WIn32 API auch.

    SendMessageToDescendants is aber genau die falsche Richtung - ich will / muss ja von UNTEN nach OBEN und nicht umgekehrt ...

    peterchen schrieb:

    (4) Registrierte Messages sind eine begrenzte Ressource, die nur verwendet werden sollten wenn wirklich nötig.

    0xFFFF - 0xC000 = 16383 dezimal. Nicht wirklich das, was man als "begrenzt" bezeichnen würde ... diese Bandbreite spielt (wenn überhaupt) nur bei (schlecht programmierten) Spielen oder Belastungstests u. wissenschaftlichen Applikationen (evtl. Protein Folding oder ähnliches, aber die verwenden bestimmt keine MFC-Messages) eine Rolle


Log in to reply