分享
 
 
 

wxWidget 小记(3) -- helloworld 宏展开

王朝other·作者佚名  2006-02-01
窄屏简体版  字體: |||超大  

看程序中如下宏语句:

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)

{

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

}

可以看出这个就是win32应用程序主程序了。它通过wxEntry函数实现整个主函数的功能,该函数与平台相关,可以自己调用本函数实现wxWidgets默认的入口函数(参考manual)。该函数的实现在wxWidgets-2.6.2\src\msw\main.cpp。

程序继续执行,在函数int wxEntryReal(int& argc, wxChar **argv)内部主要完成三个事情:

1: 调用wxApp::Initialize初始化应用程序,初始化时候调用wxApp::RegisterWindowClasses()注册一个窗口类,注册窗口类后, wxWidgets-2.6.2\src\msw\window.cpp文件下的LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)成为窗口事件处理主函数,负责窗口事件处理。后面创建MyFrame时候最终会调用CreateWindow创建函数主窗口。

2: 调用wxAppConsole::CallOnInit(),该函数最后调用bool MyApp::OnInit()虚拟函数初始化应用程序,因此经过wxWidgets封装后,呈现给用户的最终的主程序入口就是用户自己重载的OnInit()虚拟函数。在MyFrame构造函数调用wxTopLevelWindow::Create()完成窗口创建。

3: 最后调用wxAppBase::OnRun()进行消息循环接收发送, 把属于窗口的消息发送给wxWndProc进行处理。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有