[wx-dev] RFC improved event handling (more minor changes)

Brian Vanderburg II BrianVanderburg2 at aim.com
Wed Jul 30 07:44:18 PDT 2008


Brian Vanderburg II wrote:
> I've made some minor changes to your code to get a few cases working:
>
> 1.  Two different connects for members.  The first one expects the 
> handler object to be the same class as the handler function.  The 
> second allows the handler object to be derived from the class 
> containing the handler function.
>
> 2.  Type safety is only guaranteed if a handler object is passed.  If 
> you do window.Connect(wxEVT_BLUE, &MyEventHandler::onHandleColor ), 
> type casting is done converting 'this' to MyEventHandler but window is 
> only wxEvtHandler, so MyEventHandler::onHandleColor will get called 
> with a 'this' pointer only pointing to wxEvtHandler, not MyEventHandler.
>
> I've attached the changes to this file, with some comments where I've 
> made changes.
>
> Brian Vanderburg II
>
I've made a few more changes.

1.  A small problem that may crop up in some compilers.  Using the last 
version:

window.Connect(wxEVT_PAINT, &MyHandler::OnPaint) would only call the 
first member version since no handler object is passed.

window.Connect(wxEVT_PAINT, &MyHandler::OnPaint, &derived) would only 
call the second member version since the handler object is not of the 
same type but derived from the type the member function is in

window.Connect(wxEVT_PAINT, &MyHandler::OnPaint, &myHandler) would 
possibly match either the first or the second version, which may produce 
ambiguity errors on some compilers.

Change:

The first member version does not take any handler object.  This version 
is used as when no handler object is specified and uses 'this' as the 
handler.  The second member version is as is, taking Derived as a 
handler object.  This may be of the same class or of a derived class of 
the handler member function.  There would be no ambiguity for the the 
third situation above.

2.  Simulate wxWidgets connect - I've changed the Connect functions to 
have the same arguments that wxWidgets currently has.  For each of the 
three main connects I've also created the shortcut versions that take 
only one ID and no ID as well.


If this change is incorporated into wxWidgets, the static event tables 
could eventually be completely eliminated.  It would no longer be the 
easy way:

BEGIN_EVENT_TABLE(MyWindow, wxFrame)
    EVT_MENU(ID_MENU1, MyWindow::OnMenu1)
    EVT_MENU(ID_MENU2, MyWindow::OnMenu2)
    EVT_MENU(ID_MENU3, MyWindow::OnMenu3)
END_EVENT_TABLE()

vs:

Connect(ID_MENU1, wxEVT_MENU, &MyWindow::OnMenu1);
Connect(ID_MENU2, wxEVT_MENU, &MyWindow::OnMenu2);
Connect(ID_MENU3, wxEVT_MENU, &MyWindow::OnMenu3);

The second is fewer lines of code, and no longer need to use the 
conversion macros.  However it may still be needed for parent 
propogation of events to work:

If MyWindow uses only Connect and no BEGIN_EVENT_TABLE/etc exists any 
more, events not handled in MyWindow will not get processed by the event 
tables of wxFrame.

One solution:  since there is only one event table for each object, 
unlike the static class event tables, base classes could use dynamic 
connections as well.  When the base is created, it would Connect 
whatever it needed, then the derived class could Connect whatever it 
needed.  For this to work, the dynamic event table must be processed 
backwards, so event handlers set in MyWindow would handled first and if 
not found those set in wxFrame.  Also, the event handler for this window 
must be installed after creating the parent window (after calling 
Parent::Create()

// For single-step construction
class  MyFrame : public wxFrame
{
public
    MyFrame()
    {
       wxFrame::Create(...) // Could also do MyFrame() : wxFrame(...)
       // Connect event handlers after Parent::Create()
    }
}

// For two-step construction
class MyFrame : public wxFrame
{
public:
    MyFrame()
    {
       // no connections
    }

    MyFrame(...)
    {
       Create(...)
    }

    bool Create(...)
    {
       wxFrame::Create(...)
       // Connect here after Parent::Create
    }
}

Another issue would be how to handle Disconnect?

Brian Vanderburg II


More information about the wx-dev mailing list