WndProc



  • Ich hab ein Problemo:

    Ich schaffe es absolut nicht meine WndProc objektorientiert zu Kappseln. (bastle gerade an einem Game)
    Kann mal bitte jemand ein Beispiel schreiben, wie ich das machen könnte???





  • Ich kann dir vielleicht helfen, hab das nämlich vor Kurzem erst selber gemacht...

    Wenn ich dich richtig verstehe willst du eine Klasse die eine klasseneigene Windowprozedur hat.

    Ich würde das dann so machen:

    //Definition in der Klasse am besten als private
    LRESULT CALLBACK (*pfWndProc)(HWND, UINT, WPARAM, LPARAM);
    

    Dann machst du dir noch Kapselungsfunktionen:

    // Setmethode
    void SetWndProc(LRESULT CALLBACK (*_pfWndProc)(HWND, UINT, WPARAM, LPARAM))
    {
        pfWndProc = _pfWndProc;
    }
    
    // Getmethode
    LRESULT CALLBACK (*GetWndProc())(HWND, UINT, WPARAM, LPARAM)
    {
        return pfWndProc;
    }
    

    So kannst du jetzt eine jeder Klasse eine eigene Windowprozedur verpassen

    // Instanz der Klasse
    TheClass FirstInstance;
    TheClass SecondInstance;
    
    // WndProc-Definieren
    LRESULT CALLBACK FirstWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        //...
    }
    
    LRESULT CALLBACK SecondWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        //...
    }
    
    // Jetzt kannst du jedem Object eine andere WndProc geben
    FirstInstance.SetWndProc(FirstWndProc);
    SecondInstance.SetWndProc(SecondWndProc);
    
    // ... der Rest sollte dann ja klar sein!
    

    Ich hoffe das war jetzt das was du wissen wolltest.

    Mfg Nico



  • nur wie kommt der Instanzzeiger (this) in die WndProc ?



  • Hmm ...

    Also ich würde einfach eine eigene Nachricht definieren

    // Eigene Nachricht definieren
    #define WM_THISPOINTER (WM_USER + 1)
    

    In die WndProc reagierst du dann auf deine Message (z.B. so):

    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
        // Zeiger auf die zugehörige Instanz (also this-Zeiger)
        static TheClass* pInstance;
    
        switch(msg)
        {
        //...
    
        case WM_THISPOINTER:
            pInstance = (TheClass*)wParam;
            break;
    
        //...
        }
    
        //...
    
    }
    

    Und jetzt musst du dir nur noch, nachdem du die Prozedur deiner Instanz übergeben hast der Prozedur eine Nachricht schicken.
    Z.B. kannste dafür ne Funktion schreiben oder das gleich bei der Set-Funktion der WndProc (oben hatte ich sie SetWndProc() genannt) erledigen

    // Setmethode
    void SetWndProc(LRESULT CALLBACK (*_pfWndProc)(HWND, UINT, WPARAM, LPARAM))
    {
        pfWndProc = _pfWndProc;
    
        // Nachricht an die Fenster-Prozedur schicken
        // Den Fensterhandle brauchste halt noch aber den kannste ja irgendwo 
        // speichern... aber das bekommste ja sicher hin!
    
        SendMessage(hwnd, WM_THISPOINTER, (WPARAM)this, 0);
    }
    

    Dann haste den this-Zeiger in der WndProc drinne!

    Mfg Nico



  • wie wäre es den This-Zeiger bei WM_CREATE zu übergeben
    und ihn mit SetWindowLong im User-Bereich zu speichern ...

    Aber hast recht, da könnte man sich auch an das Tut der FAQ halten, das wäre zu einfach aber 😡



  • Klar das wäre generell auch möglich.
    Das Problem ist halt dann nur das du das Fenster innerhalb der Klasse erstellen musst...
    Da gibts wahrscheinlich undendlich viele Möglichkeiten...
    Man könnte eine globale Variable definieren.
    Den this-Zeiger über eine Nachricht reinschicken (so würde ich es machen)
    Du kannst den Zeiger theoretisch in eine Datei oder die Zwischenablage schreiben und innerhalb der WndProc als Reaktion auf WM_CREATE oder eine andere Nachricht wieder auslesen...

    Doch was dann wirklich sinnvoll ist wird wohl sehr schnell klar!
    Ich würds mit ner Nachricht machen aber das bleibt natürlich jedem selbst überlassen!



  • Sehr sinnfrei das Ganze. Funktioniert doch eh nur für ein einziges Fenster wie du es gemacht hast.



  • Ja sag ich ja das das meiste Blödsinn ist.

    Aber wieso soll das nur für ein Fenster funktionieren ?



  • Alle GUI-Frameworks benutzen die Moeglichkeit, die schon erwaehnt wurde, naemlich bei CreateWindow() den Parameter "lpParam" zu setzen und in WM_CREATE wieder abzufragen, und anschliessend z.B. mit SetWindowLongPtr( ... GWL_USERDATA ... ) zu speichern und bei anderen Messages mit GetWindowLongPtr( ... GWL_USERDATA ... ) wieder auszulesen.



  • Ocin schrieb:

    Ja sag ich ja das das meiste Blödsinn ist.

    Aber wieso soll das nur für ein Fenster funktionieren ?

    static TheClass* pInstance;



  • Power Off schrieb:

    Alle GUI-Frameworks benutzen die Moeglichkeit, die schon erwaehnt wurde, naemlich bei CreateWindow() den Parameter "lpParam" zu setzen und in WM_CREATE wieder abzufragen, und anschliessend z.B. mit SetWindowLongPtr( ... GWL_USERDATA ... ) zu speichern und bei anderen Messages mit GetWindowLongPtr( ... GWL_USERDATA ... ) wieder auszulesen.

    Alle außer die die es anders machen.



  • lpParam schrieb:

    Alle außer die die es anders machen.

    Genau! 😉

    (haette vielleicht "so gut wie alle" schreiben sollen! 😉 )



  • Aso wegen dem static.
    Gut aber er hat ja gesagt das er eine WndProc in einer Klasse haben will.
    Wenn ich dann jeder Instanz der Klasse eine eigene WndProc geben, dann geht das problemlos. Erst wenn man dann mehreren Instanzen eine gemeinsame WndProc gibt, dann wirds wieder nichtmehr funktionieren das stimmt.

    Ich weis ja net ob er das überhaupt braucht (mehrere die eine WndProc gemeinsam haben), aber wenn das so ist müsste man es wieder anders lösen.
    Dann stellt sich wieder die Frage ob jede Klasse/WndProc ihr eigenes Fenster hat oder welche gemeinsam nutzt....

    Ich finde wir sollten aufhören uns hier irgendwelche Dinge auszudenken. Der soll mal genau sagen was er braucht dann bekommt er die beste Lösung! 😉



  • falsch!



  • °° schrieb:

    falsch!

    ok 😋



  • Nagut, ich werd mal alles probieren.

    Aber erstmal Danke, falls es auch nicht funktioniert.


Anmelden zum Antworten