wxWidgets事件处理(手机播放器连载系列2)
1、
绝大多数GUI程序都是事件驱动的,应用程序一直停留在一个消息循环中,等待这用户或者别的定时事件的发生,一旦收到某种事件,应用程序就将其扔给处理这个事件的函数。
不同的GUI编程架构用不同的方法将他内部的事件处理机制展现给程序开发者。对于wxWidgets来说,事件表机制是最主要的方法。
2、
每个wxEvtHandler的派生类,例如frame、按钮、菜单以及文档等,都会在其内部维护一个事件表,用来告诉wxWidgets事件和事件处理过程的对应关系。所以继承自wxWindow的窗口类,以及应用程序类都是wxEvtHandler的派生类。
下面来创建一个静态的事件表:
a、定义一个直接或者间接继承自wxEvtHandler的类
b、为每一个你想要处理的事件定义一个处理函数
c、在这个类中使用DECLARE_EVENT_TABLE来声明事件表
d、在.cpp文件中事件BEGIN_EVENT_TABLE和END_EVENT_TABLE实现一个事件表
e、在事件表的实现中增加事件宏,来实现从事件到事件处理过程的映射
wxEvent::Skip可以提示事件处理过程对于其中的事件应该继续寻找其父亲的事件表====一般来说在wxWidgets中,你应该通过调用事件Skip方法,而不是通过显示直接调用其父亲对应函数的方法来实现对特殊事件的过滤
继续来看一个例子:
client.h:
#include <wx/wx.h> class MyFrame : public wxFrame { public: MyFrame(const wxString& title); void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); void OnSize(wxSizeEvent& event); void OnButtonOK(wxCommandEvent& event); private: DECLARE_EVENT_TABLE(); // 告诉wxWidgets这个类想要自己处理某些事件,这是与EVENT_TABLE对应的 }; // 重载wxApp类的class要实现OnInit来定义自己的初始化函数,同样的还有OnExit等函数(app.h中) class MyApp: public wxApp { wxFrame* frame_; public: bool OnInit(); };
client.cpp
#include "stdafx.h" #include <wx/wx.h> #include "client.h" #include "mondrian.xpm" MyFrame::MyFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, wxT("Hello wxWidgets"), wxPoint(50,50), wxSize(800,600)) { // set icon for application SetIcon(wxIcon(mondrian_xpm)); wxButton *button = new wxButton(this, wxID_OK, wxT("OK"), wxPoint(200, 200), wxSize(50, 50)); wxButton *button2 = new wxButton(this, wxID_NO, wxT("NO"), wxPoint(300, 300), wxSize(50, 50)); // Create a menu bar wxMenu *fileMenu = new wxMenu; // The "About" item should be in the help menu wxMenu *helpMenu = new wxMenu; helpMenu->Append(wxID_ABOUT, wxT("&About...\tF1"), wxT("Show about dialog")); fileMenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"), wxT("Quit this program")); // Now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar(); menuBar->Append(fileMenu, wxT("&File")); menuBar->Append(helpMenu, wxT("&Help")); // ... and attach this menu bar to the frame SetMenuBar(menuBar); // Create a status bar just for fun CreateStatusBar(2); SetStatusText(wxT("Welcome to wxWidgets!")); } // Event table for MyFrame(事件表) BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(wxID_ABOUT, MyFrame::OnAbout) EVT_MENU(wxID_EXIT, MyFrame::OnQuit) EVT_SIZE( MyFrame::OnSize) EVT_BUTTON(wxID_OK, MyFrame::OnButtonOK) END_EVENT_TABLE() void MyFrame::OnAbout(wxCommandEvent& event) { wxString msg; msg.Printf(wxT("Hello and welcome to %s"), wxVERSION_STRING); wxMessageBox(msg, wxT("About Minimal"), wxOK | wxICON_INFORMATION, this); } void MyFrame::OnQuit(wxCommandEvent& event) { Close(); } void MyFrame::OnSize(wxSizeEvent& event) { // wxString msg; // msg.Printf(wxT("Hello and welcome to %s"), wxVERSION_STRING); // wxMessageBox(msg, wxT("About Minimal"), wxOK | // wxICON_INFORMATION, this); } void MyFrame::OnButtonOK(wxCommandEvent& event) { wxString msg; msg.Printf(wxT("Hello and welcome to %s"), wxVERSION_STRING); wxMessageBox(msg, wxT("About Minimal"), wxOK | wxICON_INFORMATION, this); } //////=======================MyApp============================ bool MyApp::OnInit() { frame_ = new MyFrame(wxT("Minimal wxWidgets App")); frame_->Show(); return true; }
useWxWidgets.cpp
// useWxWidgets.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <wx/wx.h> #include "wx/window.h" #include "client.h" #include "windows.h" #include "wx/frame.h" int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPTSTR lpCmdLine, _In_ int nCmdShow) { // 调用wxApp类来初始化wxWidgets MyApp* app=new MyApp(); wxApp::SetInstance(app); return wxEntry(hInstance,hPrevInstance); }