wxwidgets的消息映射宏探讨

来源:互联网 发布:中航工业贵飞集团知乎 编辑:程序博客网 时间:2024/05/30 22:53
 

看程序中如下宏语句:

enum

{

Minimal_Quit = wxID_EXIT,

Minimal_About = wxID_ABOUT

};

BEGIN_EVENT_TABLE(MyFrame, wxFrame)

EVT_MENU(Minimal_Quit, MyFrame::OnQuit)

EVT_MENU(Minimal_About, MyFrame::OnAbout)

END_EVENT_TABLE()

IMPLEMENT_APP(MyApp)

现在展开这些宏来分析内部的运行机制

1. 展开BEGIN_EVENT_TABLE(MyFrame, wxFrame)

2. 展开EVT_MENU(Minimal_Quit, MyFrame::OnQuit)

3. 展开END_EVENT_TABLE()

1. 在wxWidgets-2.6.2\include\wx\event.h文件中宏BEGIN_EVENT_TABLE被定义如下:

#define BEGIN_EVENT_TABLE(theClass, baseClass) \

const wxEventTable theClass::sm_eventTable = { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \

const wxEventTable *theClass::GetEventTable() const \

{ return &theClass::sm_eventTable; } \

wxEventHashTable theClass::sm_eventHashTable(theClass::sm_eventTable); \

wxEventHashTable &theClass::GetEventHashTable() const \

{ return theClass::sm_eventHashTable; } \

const wxEventTableEntry theClass::sm_eventTableEntries[] = { \

经过预编译处理后程序如下:

const wxEventTable MyFrame::sm_eventTable = { &wxFrame::sm_eventTable, &MyFrame::sm_eventTableEntries[0] };

const wxEventTable *MyFrame::GetEventTable() const { return &MyFrame::sm_eventTable; }

wxEventHashTable MyFrame::sm_eventHashTable(MyFrame::sm_eventTable);

wxEventHashTable &MyFrame::GetEventHashTable() const { return MyFrame::sm_eventHashTable; }

const wxEventTableEntry MyFrame::sm_eventTableEntries[] = {

2. 在wxWidgets-2.6.2\include\wx\event.h文件中宏EVT_MENU被定义如下:

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

#define wx__DECLARE_EVT1(evt, id, fn) wx__DECLARE_EVT2(evt, id, wxID_ANY, fn)

#define wx__DECLARE_EVT2(evt, id1, id2, fn) DECLARE_EVENT_TABLE_ENTRY(evt, id1, id2, fn, NULL),

#define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) wxEventTableEntry(type, winid, idLast, fn, obj)

当中wxCommandEventHandler(func)进行静态强制类型转化,把指定的函数(func)指针类型转化为事件处理函数类型

#define wxCommandEventHandler(func) \

(wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxCommandEventFunction, &func)

注: typedef void (wxObject::*wxObjectEventFunction)(wxEvent&);

typedef void (wxEvtHandler::*wxEventFunction)(wxEvent&);

typedef void (wxEvtHandler::*wxCommandEventFunction)(wxCommandEvent&);

#define wxStaticCastEvent(type, val) wx_static_cast(type, val)

#define wx_static_cast(t, x) ((t)(x)) //进行强制类型转化

EVT_MENU(Minimal_Quit, MyFrame::OnQuit)经过预编译处理后程序如下:

wxEventTableEntry(wxEVT_COMMAND_MENU_SELECTED, Minimal_Quit, wxID_ANY, MyFrame::OnQuit, NULL)

3. 在wxWidgets-2.6.2\include\wx\event.h文件中宏BEGIN_EVENT_TABLE被定义如下:

#define END_EVENT_TABLE() DECLARE_EVENT_TABLE_ENTRY( wxEVT_NULL, 0, 0, 0, 0 ) };

再展开DECLARE_EVENT_TABLE_ENTRY:

#define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \

wxEventTableEntry(type, winid, idLast, fn, obj)

经过预编译处理后程序如下:

wxEventTableEntry(wxEVT_NULL, 0, 0, 0, 0)};

综合上面所述,

BEGIN_EVENT_TABLE(MyFrame, wxFrame)

EVT_MENU(Minimal_Quit, MyFrame::OnQuit)

EVT_MENU(Minimal_About, MyFrame::OnAbout)

END_EVENT_TABLE()

最终展开的效果为:

const wxEventTable MyFrame::sm_eventTable = { &wxFrame::sm_eventTable, &MyFrame::sm_eventTableEntries[0] };

const wxEventTable *MyFrame::GetEventTable() const { return &MyFrame::sm_eventTable; }

wxEventHashTable MyFrame::sm_eventHashTable(MyFrame::sm_eventTable);

wxEventHashTable &MyFrame::GetEventHashTable() const { return MyFrame::sm_eventHashTable; }

const wxEventTableEntry MyFrame::sm_eventTableEntries[] = {

wxEventTableEntry(wxEVT_COMMAND_MENU_SELECTED, Minimal_Quit, wxID_ANY, MyFrame::OnQuit, NULL),

wxEventTableEntry(wxEVT_COMMAND_MENU_SELECTED, Minimal_About, wxID_ANY, MyFrame::OnAbout, NULL),

wxEventTableEntry(wxEVT_NULL, 0, 0, 0, 0)

};

wxWidgets通过宏的方式在预编译时静态设置好了事件映射表, 把指定的一个唯一的命令ID和MyFrame的指定函数静态绑定。实际上也可以进行动态绑定,这里先不描述。

IMPLEMENT_APP(MyApp)宏展开如下:

IMPLEMENT_APP(appname)

l IMPLEMENT_APP_NO_THEMES(appname)

n IMPLEMENT_APP_NO_MAIN(appname)

wxAppConsole *wxCreateApp() \

{ \

wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE, \

"your program"); \

return new appname; \

} \

wxAppInitializer \

wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp); \

appname& wxGetApp() { return *(appname *)wxTheApp; }

n IMPLEMENT_WXWIN_MAIN

extern "C" int WINAPI WinMain(HINSTANCE hInstance, \

HINSTANCE hPrevInstance, \

wxCmdLineArgType lpCmdLine, \

int nCmdShow) \

{ \

return wxEntry(hInstance, hPrevInstance, lpCmdLine, nCmdShow); \

}

l IMPLEMENT_WX_THEME_SUPPORT

最终的结果为:

wxAppConsole *wxCreateApp()

{

wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,

"your program");

return new MyApp;

}

wxAppInitializer

wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp);

MyApp& wxGetApp() { return *( MyApp*)wxTheApp; }

extern "C" int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

wxCmdLineArgType lpCmdLine,

int nCmdShow)

{ &nb