[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