I am a lazy man. So when I know wx-Widgets, I likes it rightly. That is a GUI APIs
cross platforms. The xMule is developed based on this packages.
There are not only GUI functions, classes, but also IO, enviromnets, database, OS sepcificed
functions. That is implemented in C++ languages.
I started to learn it. Its application structure is alike to MFC. There are macros to use
map events to handle functions.
Practically every app should define a new class derived from wxApp. By overriding wxApp's OnInit()
the program can be initialized, e.g. by creating a new main window.
class MyApp: public wxApp
{
virtual bool OnInit();
};
The main window is created by deriving a class from wxFrame and giving it a menu and a status bar
in its constructor. Also, any class that wishes to respond to any "event" (such as mouse clicks or
messages from the menu or a button) must declare an event table using the macro below. Finally,
the way to react to such events must be done in "handlers". These handlers should not be virtual.
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
private:
DECLARE_EVENT_TABLE()
};
In order to be able to react to a menu command, it must be given a unique identifier such as
a const or an enum.
enum
{
ID_Quit = 1,
ID_About,
};
We then proceed to actually implement an event table in which the events are routed to their
respective handler functions in the class MyFrame. There are predefined macros for routing all
common events, ranging from the selection of a list box entry to a resize event when a user
resizes a window on the screen. If -1 is given as the ID, the given handler will be invoked
for any event of the specified type, so that you could add just one entry in the event table
for all menu commands or all button commands etc.
The origin of the event can still be distinguished in the event handler as the (only) parameter
in an event handler is a reference to a wxEvent object, which holds various information about
the event (such as the ID of and a pointer to the class, which emitted the event).
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
As in all programs there must be a "main" function. Under wxWidgets main is implemented using
this macro, which creates an application instance and starts the program.
IMPLEMENT_APP(MyApp)
As mentioned above, wxApp::OnInit() is called upon startup and should be used to initialize
the program, maybe showing a "splash screen" and creating the main window (or several). The frame
should get a title bar text ("Hello World") and a position and start-up size. One frame can also
be declared to be the top window. Returning true indicates a successful initialization.
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( "Hello World", wxPoint(50,50), wxSize(450,340) );
frame->Show( true );
SetTopWindow( frame );
return true;
}
In the constructor of the main window (or later on) we create a menu with two menu items as well as
a status bar to be shown at the bottom of the main window. Both have to be "announced" to the frame
with respective calls.
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, "&About..." );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, "E&xit" );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( "Welcome to wxWidgets!" );
}
Here are the actual event handlers. MyFrame::OnQuit() closes the main window
by calling Close(). The parameter true indicates that other windows have no
veto power such as after asking "Do you really want to close?". If there is
no other main window left, the application will quit.
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close( true );
}
MyFrame::OnAbout() will display a small window with some text in it. In this
case a typical "About" window with information about the program.
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox( "This is a wxWidgets' Hello world sample",
"About Hello World", wxOK | wxICON_INFORMATION );
}
Each class that you wish to be known to the type system should have a macro
such as DECLARE_DYNAMIC_CLASS just inside the class declaration. The macro
IMPLEMENT_DYNAMIC_CLASS should be in the implementation file. Note that these
are entirely optional; use them if you wish to check object types, or create
instances of classes using the class name. However, it is good to get into
the habit of adding these macros for all classes.
Variations on these macros are used for multiple inheritance, and abstract
classes that cannot be instantiated dynamically or otherwise.
DECLARE_DYNAMIC_CLASS inserts a static wxClassInfo declaration into the class,
initialized by IMPLEMENT_DYNAMIC_CLASS. When initialized, the wxClassInfo object
inserts itself into a linked list (accessed through wxClassInfo::first and
wxClassInfo::next pointers). The linked list is fully created by the time all
global initialisation is done.
IMPLEMENT_DYNAMIC_CLASS is a macro that not only initialises the static
wxClassInfo member, but defines a global function capable of creating a dynamic
object of the class in question. A pointer to this function is stored in
wxClassInfo, and is used when an object should be created dynamically.
wxObject::IsKindOf uses the linked list of wxClassInfo. It takes a wxClassInfo
argument, so use CLASSINFO(className) to return an appropriate wxClassInfo pointer
to use in this function.
The function wxCreateDynamicObject can be used to construct a new object of
a given type, by supplying a string name. If you have a pointer to the wxClassInfo
object instead, then you can simply call wxClassInfo::CreateObject.
cross platforms. The xMule is developed based on this packages.
There are not only GUI functions, classes, but also IO, enviromnets, database, OS sepcificed
functions. That is implemented in C++ languages.
I started to learn it. Its application structure is alike to MFC. There are macros to use
map events to handle functions.
Practically every app should define a new class derived from wxApp. By overriding wxApp's OnInit()
the program can be initialized, e.g. by creating a new main window.
class MyApp: public wxApp
{
virtual bool OnInit();
};
The main window is created by deriving a class from wxFrame and giving it a menu and a status bar
in its constructor. Also, any class that wishes to respond to any "event" (such as mouse clicks or
messages from the menu or a button) must declare an event table using the macro below. Finally,
the way to react to such events must be done in "handlers". These handlers should not be virtual.
class MyFrame: public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
private:
DECLARE_EVENT_TABLE()
};
In order to be able to react to a menu command, it must be given a unique identifier such as
a const or an enum.
enum
{
ID_Quit = 1,
ID_About,
};
We then proceed to actually implement an event table in which the events are routed to their
respective handler functions in the class MyFrame. There are predefined macros for routing all
common events, ranging from the selection of a list box entry to a resize event when a user
resizes a window on the screen. If -1 is given as the ID, the given handler will be invoked
for any event of the specified type, so that you could add just one entry in the event table
for all menu commands or all button commands etc.
The origin of the event can still be distinguished in the event handler as the (only) parameter
in an event handler is a reference to a wxEvent object, which holds various information about
the event (such as the ID of and a pointer to the class, which emitted the event).
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Quit, MyFrame::OnQuit)
EVT_MENU(ID_About, MyFrame::OnAbout)
END_EVENT_TABLE()
As in all programs there must be a "main" function. Under wxWidgets main is implemented using
this macro, which creates an application instance and starts the program.
IMPLEMENT_APP(MyApp)
As mentioned above, wxApp::OnInit() is called upon startup and should be used to initialize
the program, maybe showing a "splash screen" and creating the main window (or several). The frame
should get a title bar text ("Hello World") and a position and start-up size. One frame can also
be declared to be the top window. Returning true indicates a successful initialization.
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame( "Hello World", wxPoint(50,50), wxSize(450,340) );
frame->Show( true );
SetTopWindow( frame );
return true;
}
In the constructor of the main window (or later on) we create a menu with two menu items as well as
a status bar to be shown at the bottom of the main window. Both have to be "announced" to the frame
with respective calls.
MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame((wxFrame *)NULL, -1, title, pos, size)
{
wxMenu *menuFile = new wxMenu;
menuFile->Append( ID_About, "&About..." );
menuFile->AppendSeparator();
menuFile->Append( ID_Quit, "E&xit" );
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append( menuFile, "&File" );
SetMenuBar( menuBar );
CreateStatusBar();
SetStatusText( "Welcome to wxWidgets!" );
}
Here are the actual event handlers. MyFrame::OnQuit() closes the main window
by calling Close(). The parameter true indicates that other windows have no
veto power such as after asking "Do you really want to close?". If there is
no other main window left, the application will quit.
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close( true );
}
MyFrame::OnAbout() will display a small window with some text in it. In this
case a typical "About" window with information about the program.
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox( "This is a wxWidgets' Hello world sample",
"About Hello World", wxOK | wxICON_INFORMATION );
}
Each class that you wish to be known to the type system should have a macro
such as DECLARE_DYNAMIC_CLASS just inside the class declaration. The macro
IMPLEMENT_DYNAMIC_CLASS should be in the implementation file. Note that these
are entirely optional; use them if you wish to check object types, or create
instances of classes using the class name. However, it is good to get into
the habit of adding these macros for all classes.
Variations on these macros are used for multiple inheritance, and abstract
classes that cannot be instantiated dynamically or otherwise.
DECLARE_DYNAMIC_CLASS inserts a static wxClassInfo declaration into the class,
initialized by IMPLEMENT_DYNAMIC_CLASS. When initialized, the wxClassInfo object
inserts itself into a linked list (accessed through wxClassInfo::first and
wxClassInfo::next pointers). The linked list is fully created by the time all
global initialisation is done.
IMPLEMENT_DYNAMIC_CLASS is a macro that not only initialises the static
wxClassInfo member, but defines a global function capable of creating a dynamic
object of the class in question. A pointer to this function is stored in
wxClassInfo, and is used when an object should be created dynamically.
wxObject::IsKindOf uses the linked list of wxClassInfo. It takes a wxClassInfo
argument, so use CLASSINFO(className) to return an appropriate wxClassInfo pointer
to use in this function.
The function wxCreateDynamicObject can be used to construct a new object of
a given type, by supplying a string name. If you have a pointer to the wxClassInfo
object instead, then you can simply call wxClassInfo::CreateObject.