[wxWidgets] WindowProc?



  • Hallo,

    ich freunde mich gerade mit wxWidgets an, doch fehlt mir die Nachrichten-Verarbeitung, wzb in der MFC als LRESULT CFrameWnd::WindowProc(UINT message,WPARAM wParam,LPARAM lParam).

    Gibts sowas bei wxWidgets garnicht, und man muss immer die member-Funktionen OnClick() usw. benutzen?

    Gruß, Max



  • Da wx Plattformunabhängig ist, gibt es das natürlich nicht.

    Natürlich hat unter Windows jedes Fenster seine WindowProc, ist ja schliesslich WinAPI. Aber die WindowProc ist nicht dokumentiert, daher auf eigenes Risiko:

    WXLRESULT wxWindow::MSWWindowProc (WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
    

    Kannst du überschreiben.



  • Ja, danke, dass hab ich mittlererweile auch gefunden, aber egal welche Nachricht ich abzufangen versuche - die WM_*-Messages treten nie ein.

    Gibt es dafür auch extra wx-Makros, wenn ja, weißt Du wo die gelistet sind?

    Danke,

    lg Max



  • Nö, das ist 'ne Stinknormale Virtuelle Funktion. Einfach überschreiben und fertig. Keine Markos erforderlich. Die Messages die dort ankommen sind 1:1 die WinAPI-Messages.

    Ich habe die aber bisher nur bei selbstgestrickten Controls sowie wxPanel und wxFrame verwendet (weil wx leider keine vernünftige Alternative bietet custom Messages abzufangen). Keine Ahnung, ob die bei den nativen Controls überhaupt verwendet wird.



  • Tschuldigung, das hier auf keinen Fall machen. Das zerstört die XPlatform-Ability von wxWidgets (bzw des Programms) und ist fehleranfällig, da man dann auch immer alle Events wie von wxWIdgets gewünscht behandeln muss.
    Für Events gibt es 2 Möglichkeiten:

    1.) Connector
    Es gibt die Möglichkeit auf Events mit der Funktion ConnectEvent() zu verbinden. Siehe Doku.

    2.) Makros
    Die (mMn) schönere Möglichkeit ist über das Event-Table ähnlich wie bei MFC:

    clas MyFrame() : public wxFrame
    {
    [..]
       void OnAbout();
    protected:
      DECLARE_EVENT_TABLE()
    };
    
    BEGIN_EVENT_TABLE(wxFrame, MyFrame)
    EVT_MENU_CLICK(wxID_ABOUT, OnAbout)
    END_EVENT_TABLE()
    // Der Code ist aus dem STEHGREIF! Ist nicht 100% korrekt ;). Siehe hierzu jedes beliebige Sample aus dem Ordner im wxVerzeichnis.
    

    Bitte sag mir mal, warum da direkt zugreifen möchtest. Dann kann ich dir vllt sagen wie der "wxWay" dazu ist :).
    Generell zu Events:
    http://docs.wxwidgets.org/trunk/overview_eventhandling.html
    rya.
    Scorcher24



  • Weil WX keine andere Möglichkeit bietet Messages, für die keine Event-Klasse vorhanden ist, zu behandeln.

    Und Fehleranfällig ist das keineswegs. Man behandelt nur die Messages, die einen interessieren, die reslichen werden einfach an die Window-Proc der Basisklasse weitergereicht.

    Logisch dass das nicht Plattformunabhängig sein kann. Aber das betrifft alle Sachen, die von einem Toolkit nicht abgedeckt werden. Muss man halt selbst machen und per #IFDEF für die einzelnen Plattformen verstecken.

    Klar, dass das kein Ersatz für Connect() sein soll. Aber wx kennt nunmal nur einen Bruchteil der möglichen WM_ Messages. Und wenn ich ein Programm von WinAPI nach WX portieren würde, würde ich zunächst auch einfach die WindowProc benutzen. Später wenn alles läuft, kann man dann anfagen die Messages die WX zufällig kennt auf das Wx-Event-System umzustellen.



  • Ja, wenn ein großer Wissensstand über ein Toolkit und des OS auf dem es läuft vorhanden ist, kann das eine praktikable Lösung sein. 🙂
    Ich vermute hier aber eher ein generelles "Umgewöhnungsproblem" von MFC auf wxWidgets. Deswegen interessiert mich das was genau hier versucht wird. Die Events, die nicht behandelt werden, sind doch meistens welche die entweder einen internen wxErsatz haben oder auf anderen Platformen evtl nicht vorhanden sind oder Events die vllt in einem von 1000 Programmen gebraucht werden. Und ich finde, man sollte IMMER erst die Möglichkeiten des Toolkits ausschöpfen, bevor man zu solchen Hacks greift :). wxWidgets ist umfangreicher als manche glauben und man auf den ersten Blick sieht. Nach einigen Jahren, die ich das Ding nun nutze, entdeck ich immer wieder neue Möglichkeiten *g*.
    Aber ich glaube, das ist hier eine reine Glaubenssache *gg*, von daher sollten wir uns um dieses Detail nicht streiten. Liegt nun alleine beim TE Licht in das Dunkel zu bringen.
    rya.



  • Ich weiss nicht worum es dem Original-Autoren ging. Mir geht es tatsächlich um Messages die WX nicht beherrscht.

    Das Problem ist in meinem Fall das beschissene Design von WX. Es sieht einfach keine Möglichkeit vor Messages abzufangen, die vom Toolkit-Entwickler nicht vorgesehen sind.

    Bei einem vernünftigen Toolkit würde ich einfach eine neue Event-Klasse erstellen, die diese Messages behandelt. Jeder Client des Events, würde einfach ein Connect auf dieses Event machen und gut ist. Nicht so bei WX. Dort ist die Event-Factory hardcoded, und die einzige Möglichkeit sein eigenes Event zu feuern ist das Überschreiben einer undokumentierten Funktion. Was noch viel schlimmer ist: Für jedes Fenster, für das man auf ein eigenes Event reagieren will, muss diese Funktion überschreiben. Traurig aber wahr...

    Es wird noch besser. Da ich nicht Zugriff auf alle Fenster habe, für die ich eigene Events brauche (weil sie von Plugins erstellt werden), habe ich teilweise überhaupt keine Möglichkeit die WindowProc zu überschreiben. Was dann dazu führt, dass ich die Fensterprozedur per WinAPI Subclassen muss um mich dort einklinken zu können.

    Das Event-System von WX ist einfach nur zum Kotzen.

    Äh, sorry, da bin ich wohl in's Schimpfen abgerutscht... Was ich damit sagen wollte... Natürlich sollte man in erster Linie die Möglichkeiten des Toolkits nutzen. Sonst könnte man gleich bei WinAPI bleiben. Da stimme dir vollkommen zu. Es ist nur leider so das das nicht immer möglich ist.



  • frenki schrieb:

    Ich weiss nicht worum es dem Original-Autoren ging. Mir geht es tatsächlich um Messages die WX nicht beherrscht.

    Das Problem ist in meinem Fall das beschissene Design von WX. Es sieht einfach keine Möglichkeit vor Messages abzufangen, die vom Toolkit-Entwickler nicht vorgesehen sind.

    Bei einem vernünftigen Toolkit würde ich einfach eine neue Event-Klasse erstellen, die diese Messages behandelt. [...]

    Gut, dass du trotzdem nicht erwähnst, welche Events dir eigentlich fehlen. Des weiteren solltest du eigentlich wissen, dass du natürlich eigene Events erstellen kannst, was auch in der Doku: http://docs.wxwidgets.org/stable/wx_eventhandlingoverview.html#customevents beschrieben ist.



  • Witzbold. Und wie soll ich meine eigenen Events feuern, ausser indem ich die WindowProc überschreibe?

    Das erstellen eigener Events ist zwar lächerlich umständlich, aber kein grosses Problem. Das Problem ist das Posten dieser Events, wenn WX die zugrunde liegende Message gar nicht kennt.



  • frenki schrieb:

    Witzbold. Und wie soll ich meine eigenen Events feuern, ausser indem ich die WindowProc überschreibe?

    Das erstellen eigener Events ist zwar lächerlich umständlich, aber kein grosses Problem. Das Problem ist das Posten dieser Events, wenn WX die zugrunde liegende Message gar nicht kennt.

    Uh, hast du überhauptmal in die Doku geschaut? In dem Link von vorhin stand auch drin, wie du ein Customevent abfeuerst:

    // user code sending the event
    
    void MyWindow::SendEvent()
    {
        wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
        event.SetEventObject( this );
        // Give it some contents
        event.SetText( wxT("Hallo") );
        // Send it
        GetEventHandler()->ProcessEvent( event );
    }
    


  • Ich glaube wir reden hier aneinander vorbei. Das weiss ich alles selbst.

    Zwei Probleme: 1. Stelle dir vor, du hast ein event dessen WM_-Message wx nicht kennt. Nehmen wir einfach mal (bin zu faul nachzusehen, was ich damals wirklich brauchte) WM_USER + X.

    Diese WM_USER willst du in deinem Frame abfangen, und ein ensprechendes Event feuern: Du musst die WindowProc überschreiben.

    2. Stell dir vor, du willst dieses Event auch für Frames abfangen, die von einem Plugin erstellt wurden, deren Quellcode du somit nicht hast: Du musst die WinAPI benutzen, um die WindowProc zu subclassen.

    In einem verünftigen Toolkit - z.B. den beiden die ich vorher verwendet habe, eines selbstgestrickt, eines Kommerziell, X-Plattform Win, OS/2, Unix - konnte ich das durch Überschreiben einer *dokumentierten* Funktion der Event-Basis-Klasse selbst erledigen. Somit sind in einem durchdachten Event-System beide Punkte kein Problem. Davon das man dort einfach sein neues Event von der Basis-klasse, bzw. einem vorhandenen Event, abgeleitet hat und fertig, anstatt sich noch mit diesen unsäglichen Makros abärgern zu müssen mal ganz abgesehen.

    Darum ist meine Meinung zum Event-System von wxWidgets: Ein undurchdachter Haufen Müll.


Anmelden zum Antworten