Search code examples
c++eventsmenuwxwidgetsmenuitem

Creating a handler function with Bind to handle clicked menu item - wxWidgets 3.0


I would like to know how to use Bind function to create a simple event handler in wxWidgets 3.0 , C++.

To start off my experimenting I have created a very simple application - a main frame with a menu and a couple of items in the menu. No problems so far, all appears as expected. A part of the code I used was :

//create a menu bar
wxMenuBar* mbar = new wxMenuBar();

wxMenu* fileMenu = new wxMenu(_T(""));

fileMenu->Append(item1, _("&Item_1"), _("Select item 1"));
mbar->Append(fileMenu, _("&File"));


Now I would like to create a simple handler using Bind, that would pop out a message box in the event of selecting Item_1 from the menu, for example :

wxMessageBox( "You have selected Item 1", "Your selection", wxOK | wxICON_INFORMATION );


Please note that the popping up of a message box was just a simple example I have chosen to quickly grasp the concept and see the result. If possible, I would like the Bind event handler to be as general as possible, for arbitrary events and actions.


Solution

  • #include <wx/wx.h>
    #define item1 (wxID_HIGHEST + 1)
    
    class CApp : public wxApp
    {
    public:
        bool OnInit() {
            // Create the main frame.
            wxFrame * frame = new wxFrame(NULL, wxID_ANY, "demo");
            // Create a menu bar.
            wxMenuBar* mbar = new wxMenuBar();
            wxMenu* fileMenu = new wxMenu(_T(""));
            fileMenu->Append(item1, _("&Item_1"), _("Select item 1"));
            mbar->Append(fileMenu, _("&File"));
            frame->SetMenuBar(mbar);
            // Bind an event handling method.
    #if __cplusplus < 201103L
            frame->Bind(wxEVT_MENU, &CApp::item1_OnMenu, this, item1);
    #else
            frame->Bind(wxEVT_MENU, [](wxCommandEvent & evt)->void{
                wxMessageBox("You have selected Item 1", "Your selection", wxOK | wxICON_INFORMATION);
            }, item1);
    #endif
            // Enter the message loop.
            frame->Show(true);
            return this->wxApp::OnInit();
        }
    #if __cplusplus < 201103L
    protected:
        void item1_OnMenu(wxCommandEvent & evt) {
            wxMessageBox("You have selected Item 1", "Your selection", wxOK | wxICON_INFORMATION);
        }
    #endif
    };
    DECLARE_APP(CApp)
    IMPLEMENT_APP(CApp)
    

    The method wxEvtHandler::Bind has 3 overloads. The above only demonstrates 2 of them.

    For the available event types, which will be the 1st param of Bind, please refer to wx/event.h. The event.h also tells us which event class should be used. For example,

    #define EVT_MENU(winid, func) wx__DECLARE_EVT1(wxEVT_MENU, winid, wxCommandEventHandler(func))
    

    note the wxCommandEventHandler, remove the suffix Handler and the remaining will be the event class wxCommandEvent.