Click here to Skip to main content
Click here to Skip to main content

Introduction to wxWidgets

By , 25 Dec 2005
 

Introduction

wxWidgets formerly known as wxWindows is a framework for developing cross-platform GUI applications in C++. Julian Smart started the framework in 1992 at the Artificial Intelligence Applications Institute, University of Edinburgh. In 1995, a port to Xt was released by Markus Holzem. In May 1997, the Windows and the GTK+ ports were merged and put into a CVS repository.

What is wxWidgets

wxWidgets gives you a single, easy-to-use API for writing GUI applications on multiple platforms. Link it with the appropriate library for your platform (Windows/Unix/Mac) and compiler (almost any popular C++ compiler), and your application will adopt the look and feel appropriate to that platform. On top of the great GUI functionality, wxWindows gives you: online help, network programming, streams, clipboard and drag and drop, multithreading, image loading and saving in a variety of popular formats, database support, HTML viewing and printing, and much more.

Who should use wxWidgets

wxWidgets is a framework very much similar to MFC, except for a few negative points of its own. Those MFC programmers who are aware of the growing number of Linux users and who want to write cross platform GUI applications can use wxWidgets. With wxWidgets, it is very easy to use a framework based on C++ and it has a proven record of 13 years. In fact, wxWidgets is very stable and is supported on:

  • Windows 3.1, Windows 95/98, Windows NT, Windows 2000/XP, Windows ME, Windows CE.
  • Linux and other UNIX platforms with GTK+.
  • UNIX with Motif or the free Motif clone Lesstif.
  • Mac OS.
  • Embedded platforms are being investigated. See the wxUniversal project.
  • An OS/2 port is in progress, and you can also compile wxWidgets for GTK+ or Motif on OS/2.

Why use wxWidgets

There are a number of options available for writing cross platform GUI development, like: JAVA, Mono.NET, Qt, etc. Java has failed to prove itself as an efficient alternative. Qt is good but commercial and nobody knows its future. Mono.NET seems to be good but is largely driven by Microsoft, it seems like a copy of the work done by Microsoft and it has not yet proved itself as a successful alternative. Also, people would not like to use an extra burden of layer for highly efficient software. As wxWidgets does not use any middle layer and uses only the native controls available on the platform, it gives a nice look and feel to the application.

  • It is very complete. There are many utility classes like : wxRegEx, wxFTP, wxSplashScreen, wxZipInputStream, etc.
  • It is still heavily developed, and has a lot of support from the open source community.
  • Many compilers and platforms are supported : Windows, Linux, Mac, Unix.
  • There's a lot of documentation available on the internet, forums, wxBook.
  • It's free for personal and commercial use, and is more flexible than the LGPL license.
  • Whenever possible, wxWindows uses the platform SDK. This means that a program compiled on Windows will have the look and feel of a Windows program, and when compiled on a Linux machine, it will have the look and feel of a Linux program.
  • Ease of learning, it has the same Event tables and similar API and classes like that of WINAPI and MFC.
  • A lot of sample is provided in the samples directory of the installation, which contains how to use the basic controls, multi threading, MDI, drag and drop, sockets, printing and lots more.
  • A lot of ready to use classes are available, like: wxGenericDirCtrl, wxCalendarCtrl, wxDatePickerCtrl, wxTipWindow, wxStyledTextCtrl, wxStaticPicture, wxLEDNumberCtrl, wxEditableListBox, wxFoldPanelBar, wxGIFAnimationCtrl, wxSplashScreen, OGL (Object Graphics Library), FL (Frame Layout), etc. This is one of the main repository.
  • A lot of add on libraries are available to make the programming task more easier:

Main features

  • Multi threading.
  • Clipboard and drag and drop.
  • Network programming, like: wxSMTP, wxHTTP, wxFTP.
  • Image loading and saving in a variety of popular formats.
  • Streams (ZIP, Network, File, etc.), like: wxRarInputStream.
  • Database support, like: wxDao.
  • HTML viewing and printing, like: wxMozilla, wxIE.
  • XML based resource, multi language/Unicode support.
  • Default style themes available with the OS (e.g.: XP style themes).

Similarity to MFC

MFC and wxWidgets macros

MFC version wxWidgets version
BEGIN_MESSAGE_MAP BEGIN_EVENT_TABLE
END_MESSAGE_MAP END_EVENT_TABLE
DECLARE_DYNAMIC DECLARE_CLASS
DECLARE_DYNCREATE DECLARE_DYMAMIC_CLASS
IMPLEMENT_DYNAMIC IMPLEMENT_CLASS
IMPLEMENT_DYNCREATE IMPLEMENT_DYNAMIC_CLASS
IsKindOf(RUNTIME_CLASS(CWindow)) IsKindOf(CLASSINFO(wxWindow))

MFC and wxWidgets classes

Miscellaneous Classes
MFC version wxWidgets version
CWinApp wxApp
CObject wxObject
CCmdTarget wxEvtHandler
CCommandLineInfo wxCmdLineParser
CMenu wxMenu, wMenuBar, wxMenuItem
CWaitCursor wxBusyCursor
CDataExchange wxValidator
Window Classes
MFC version wxWidgets version
CFrameWnd wxFrame
CMDIFrameWnd wxMDIParentFrame
CMDIChildWnd wxMDIChildFrame
CSplitterWnd wxSplitterWindow
CToolBar wxToolBar
CStatusBar wxStatusBar
CReBar wxCoolBar, but see contrib/src/fl and wxAUI, wxDockIt
CPropertyPage wxPanel
CPropertySheet wxNotebook, wxPropertySheetDialog
Dialog Classes
MFC version wxWidgets version
CDialog wxDialog
CColorDialog wxColourDialog
CFileDialog wxFileDialog
CFindReplaceDialog wxFindReplaceDialog
CFontDialog wxFontDialog
CPageSetupDialog wxPageSetupDialog
CPrintDialog wxPrintDialog
Control Classes
MFC version wxWidgets version
CAnimateCtrl wxMediaCtrl, wxAnimationCtrl
CButton wxButton
CBitmapButton wxBitmapButton
CComboBox wxComboBox, wxChoice
CDateTimeCtrl wxDatePickerCtrl
CEdit wxTextCtrl
CHotKeyCtrl None, but see Keybinder
CListBox, CDragListBox wxListBox
CCheckListBox wxCheckListBox
CListCtrl wxListCtrl, wxListView
CMonthCalCtrl wxCalendarCtrl
CProgressCtrl wxGauge
CReBarCtrl None, but see contrib/src/fl and wxAUI, wxDockIt
CRichEditCtrl wxTextCtrl
CScrollBar wxScrollBar
CSliderCtrl wxSlider
CSpinButtonCtrl wxSpinButton, wxSpinCtrl
CStatic wxStaticText, wxStaticLine, wxStaticBox, wxStaticBitmap
CStatusBarCtrl wxStatusBar
CTabCtrl wxTabCtrl
CToolBarCtrl wxToolBar
CToolTipCtrl wxToolTip
CTreeCtrl wxTreeCtrl
Graphics Classes
MFC version wxWidgets version
CBitmap wxBitmap, wxImage, wxIcon, wxCursor
CBrush wxBrush
CPen wxPen
CFont wxFont
CImageList wxImageList, wxIconBundle
CPalette wxPalette
CRgn wxRegion
CClientDC wxClientDC
CMetaFileDC wxMetaFileDC
CPaintDC wxPaintDC
CWindowDC wxWindowDC
CDC wxDC, wxMemoryDC
Data Structure Classes
MFC version wxWidgets version
CArray, CObArray, CPtrArray wxArray
CStringArray wxArrayString
CDWordArray, CByteArray, CUIntArray wxArrayInt
CList, CPtrList, CObList wxList
CStringList wxArrayString, wxStringList
CMap wxHashMap
CString wxString
CPoint wxPoint
CRect wxRect
CSize wxSize
CTime wxDateTime
CTimeSpan wxTimeSpan, wxDateSpan
COleVariant wxVariant
Internet Classes
MFC version wxWidgets version
CSocket wxSocket
CFtpConnection wxFTP
CHttpConnection wxHTTP
Document/View Classes
MFC version wxWidgets version
CDocument wxDocument
CView wxView
CDocTemplate, CSingleDocTemplate, CMultiDocTemplate wxDocTemplate
Drag and Drop Classes
MFC version wxWidgets version
COleDataSource wxDataObject
COleDropSource wxDropSource
COleDropTarget wxDropTarget
File Classes
MFC version wxWidgets version
CFile wxFile, wxFFile, wxTextFile
CMemFile wxMemoryInputStream, wxMemoryOutputStream
CSocketFile wxSocketInputStream, wxSocketOutputStream
CRecentFileList wxFileHistory
Multithreading Classes
MFC version wxWidgets version
CWinThread wxThread
CCriticalSection wxCriticalSection
CMutex wxMutex
CSemaphore wxSemaphore

Class hierarchy

Getting started

Starting with wxWidgets is really very easy. Just follow these steps:

  • Download the wxMSW-2.6.2-Setup.exe from the sourceforge.net website.
  • Run the setup's EXE and install it in say "C:\wxWidgets\" folder.
  • Add an environment variable $(WXWIN) to your system. The value will be the path of the folder where you have installed wxWidgets.
    1. Right click on the My Computer icon on your desktop.
    2. Select Properties.
    3. A dialog appears. Select the "Advanced" tab in that dialog.
    4. Click "Environment Variables" button.
    5. Another dialog appears. Click on the "New" button in the "System variables" box.
    6. Add "WXWIN" in the "Variable name" text box and the folder path where you have installed wxWidgets in the "Variable value" text box.
    7. Click the OK button till all the dialogs disappear.

  • Open "src\wxWindows.dsw" and "build\msw\wx.dsw" files in Visual studio and build the projects (libraries) in the solution for all the project configurations namely: Debug, Release, Debug DLL, Release DLL, Unicode Debug, Unicode Release, Unicode Debug DLL, Unicode Release DLL. These solution files are in the wxWidgets installation folder. This step will create some libraries needed by our application for linking. These files will be created in the "lib", "lib\vc_lib\" and "lib\vc_dll\" folders under your wxWidgets installation directory.
  • Now everything is ready to feel the power of wxWidgets.

Hello world

Hello world is a classic example to start learning any new language. It gives an overview of the language without going deeper into it.

  • Just create a new project "HelloWorld" in your Visual Studio editor of "Win32 Project" type:

  • In the Application Settings, choose the application type as "Windows Application" and in the Additional options check the "Empty project" checkbox and click the "Finish" button:

  • Now create a new file, by pressing "Ctrl+N", and select the type as "C++ File" in the "Visual C++" categories. Click Open:

  • Now type the following code into the file:
    /*
     * hworld.cpp
     * Hello world sample by Robert Roebling
     */
     
    #include "wx/wx.h" 
     
    
    class MyApp: public wxApp
    {
        virtual bool OnInit();
    };
    
     
    class MyFrame: public wxFrame
    {
    public:
     
        MyFrame(const wxString& title, 
               const wxPoint& pos, const wxSize& size);
    
        void OnQuit(wxCommandEvent& event);
        void OnAbout(wxCommandEvent& event);
     
        DECLARE_EVENT_TABLE()
    };
    
    enum
    {
        ID_Quit = 1,
        ID_About,
    
    };
     
    BEGIN_EVENT_TABLE(MyFrame, wxFrame)
        EVT_MENU(ID_Quit, MyFrame::OnQuit)
        EVT_MENU(ID_About, MyFrame::OnAbout)
    END_EVENT_TABLE()
     
    IMPLEMENT_APP(MyApp)
    
    bool MyApp::OnInit()
    {
        MyFrame *frame = new MyFrame( "Hello World", 
             wxPoint(50,50), wxSize(450,340) );
        frame->Show(TRUE);
        SetTopWindow(frame);
        return TRUE;
    } 
     
    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 wxWindows!" );
    }
    
     
    void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
    {
        Close(TRUE);
    }
     
    void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
    {
    
        wxMessageBox("This is a wxWindows Hello world sample",
            "About Hello World", wxOK | wxICON_INFORMATION, this);
    }
  • Now save the file in the same project folder of "HelloWorld" as "Hello.cpp":

  • Now add the file to the project by right clicking on the "Source Files" >> "Add" >> "Add Existing Item…" in the Solution Explorer:

  • Select "Open":

  • Now, select the properties from the project menu:

  • Expand the "C/C++" node and select "General". In the "Additional Include Directories" add the following line for the "Debug" configuration:
    "$(WXWIN)\include";"$(WXWIN)\contrib\include";"$(WXWIN)\lib\mswd"

    And for the "Release" configuration add the following line:

    "$(WXWIN)\include";"$(WXWIN)\contrib\include";"$(WXWIN)\lib\msw"

  • In the Preprocessor tab, add the following line in the "Preprocessor Definitions" for the "Debug" configuration:
    WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;__WXDEBUG__;WXDEBUG=1;
    __WIN95__;__WIN32__;WINVER=0x0400;STRICT

    And for the "Release" configuration, add the following line:

    NDEBUG,WIN32,_WINDOWS,__WINDOWS__,__WXMSW__,__WIN95__,__WIN32__, 
    WINVER=0x0400,STRICT

  • In the "Code Generation" select the "Runtime Library" for "Debug" configuration as:
    Multi-threaded Debug DLL (/MDd)

    And for the "Releasse" configuration as:

    Multi-threaded DLL (/MD)

  • Expand the "Linker" node and select "General". In the "Additional Library Directories", add the following line for "Debug" configuration:
    "$(WXWIN)\lib";"$(WXWIN)\contrib\lib";"$(WXWIN)\lib\vc_lib"

    And for the "Release" configuration, add the following line:

    "$(WXWIN)\lib";"$(WXWIN)\contrib\lib";"$(WXWIN)\lib\vc_lib"

  • In the "Input" tab add the following line in the "Additional Dependencies" for the "Debug" configuration:
    wxmsw26d_core.lib wxbase26d.lib wxtiffd.lib wxjpegd.lib 
    wxpngd.lib wxzlibd.lib wxregexd.lib wxexpatd.lib
    winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib 
    kernel32.lib user32.lib gdi32.lib winspool.lib
    comdlg32.lib advapi32.lib shell32.lib ole32.lib 
    oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
  • And for the "Release" configuration, add the following line:
    wxmsw26_core.lib wxbase26.lib wxtiff.lib wxjpeg.lib 
    wxpng.lib wxzlib.lib wxregex.lib wxexpat.lib 
    winmm.lib comctl32.lib rpcrt4.lib wsock32.lib oleacc.lib 
    odbc32.lib kernel32.lib user32.lib gdi32.lib
    winspool.lib comdlg32.lib advapi32.lib shell32.lib 
    ole32.lib oleaut32.lib uuid.lib odbccp32.lib

  • Press the "OK" button to save these changes and build the solution from the build menu:

  • Select the "Start" or "Start Without Debugging" from the "Debug" menu to execute the program:

Congratulations!

You have successfully created your first "Hello World" program with wxWidgets:

Visual C++ 2005 Express

Install the Visual C++ 2005 Express by following the instructions given in Manual Installation Instructions for Express Editions and then configure the platform SDK by following steps given in Using Visual C++ 2005 Express Beta 2 with the Microsoft Platform SDK. After this, you need to change the following:

[Editor comment: Line breaks used to avoid scrolling.]

%program Files%\Microsoft Visual Studio 8\VC\VCProjectDefaults\
                                         corewin_express.vsprops

to set "_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" as PreprocessorDefinitions.

An example corewin_express.vsprops file:

<?xml version="1.0" ?>
<VisualStudioPropertySheet ProjectType="Visual C++" 
   Version="8.00" Name="Core Windows Libraries">
    <Tool Name="VCLinkerTool" AdditionalDependencies=
        "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib
        advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib" />
    <Tool Name="VCCLCompilerTool" PreprocessorDefinitions=
        "_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE" />
</VisualStudioPropertySheet>

Then open the file $(WXWIN)\src\msw\main.cpp, search for the function 'DllMain' and add the following lines:

#if _MSC_VER >= 1400 && _WINDLL
#undef _WINDLL
#endif

before the line:

#if defined(_WINDLL)

After you have configured your Visual Studio, the remaining steps are the same, simply follow the instructions given above for Visual Studio .NET, and open the wx.dsw file and compile the libraries for all the project configurations namely: Debug, Release, Debug DLL, Release DLL, Unicode Debug, Unicode Release, Unicode Debug DLL, Unicode Release DLL.

VC8 has also changed the way manifests are embedded in your executable. Your project will not be built if you include wx.manifest in your resource file. First, exclude the manifest from your resources by adding the define statement to your YourAppName.rc file:

#define wxUSE_NO_MANIFEST 1

Second, add these lines to your one of your source or header files to enable XP-Style common controls:

#if defined(__WXMSW__) && !defined(__WXWINCE__)
#pragma comment(linker, "\"/manifestdependency:type='win32' 
    name='Microsoft.Windows.Common-Controls' version='6.0.0.0'
    processorArchitecture='X86' publicKeyToken='6595b64144ccf1df'\"")
#endif

Linux

Due to the large number of pictures and high downloading time, this section has been moved to a new article. Working with wxWidgets on Linux, can be found here.

Understanding the program

You have to include wxWidgets' header files, of course. This can be done on a file by file basis (such as #include "wx/window.h") or using one global include (#include "wx/wx.h"). This is also useful on platforms that support precompiled headers such as all major compilers on the Windows platform:

// file name: hworld.cpp
//
// purpose: wxWidgets "Hello world"
//

// For compilers that support precompilation,
// includes "wx/wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
  #pragma hdrstop
#endif

#ifndef WX_PRECOMP
 #include "wx/wx.h"
#endif

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, a way to react to such events must be done in "handlers". In our sample, we react to two menu items, one for "Quit" and one for displaying an "About" window. 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 the 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 just add 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 information about the event (such as the ID of and a pointer to the class, which caused 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 for 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 as 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 the 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 i.e. a Message box 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's Hello world sample", 
    "About Hello World", wxOK | wxICON_INFORMATION );
}

How events are processed

An event table is placed in an implementation file to tell wxWindows how to map events to member functions. These member functions are not virtual functions, but they are all similar in form: they take a single wxEvent-derived argument, and have a void return type.

Here's an example of an event table:

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
  EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
  EVT_MENU    (DO_TEST,   MyFrame::DoTest)
  EVT_SIZE    (           MyFrame::OnSize)
  EVT_BUTTON  (BUTTON1,   MyFrame::OnButton1)
END_EVENT_TABLE()

The first two entries map menu commands to two different member functions. The EVT_SIZE macro doesn't need a window identifier, since normally you are only interested in the current window's size events. (In fact, you could intercept a particular window's size event by using EVT_CUSTOM(wxEVT_SIZE, ID, func).)

The EVT_BUTTON macro demonstrates that the originating event need not come from the window class implementing the event table - if the event source is a button within a panel within a frame, this will still work, because event tables are searched up through the hierarchy of Windows. In this case, the button's event table will be searched, then the parent panel's, and then the frame's.

As mentioned before, the member functions that handle events don't have to be virtual. Indeed, the member functions should not be virtual as the event handler ignores that the functions are virtual, i.e. overriding a virtual member function in a derived class will not have any effect. These member functions take an event argument, and the class of the event differs according to the type of the event and the class of the originating window. For the size events, wxSizeEvent is used. For menu commands and most control commands (such as button presses), wxCommandEvent is used. When controls get more complicated, then specific event classes are used, such as wxTreeEvent for events from wxTreeCtrl windows.

The event table in the implementation file must have a DECLARE_EVENT_TABLE macro in the class definition. For example:

class MyFrame: public wxFrame {

  DECLARE_DYNAMIC_CLASS(MyFrame)

public:
  ...
  void OnExit(wxCommandEvent& event);
  void OnSize(wxSizeEvent& event);
protected:
  int       m_count;
  ...
  DECLARE_EVENT_TABLE()
};

When an event is received from the windowing system, wxWindows calls wxEvtHandler::ProcessEvent on the first event handler object belonging to the window generating the event.

It may be noted that wxWindows' event processing system implements something very close to the virtual methods in normal C++, i.e. it is possible to alter the behavior of a class by overriding its event handling functions. In many cases, this works even for changing the behavior of native controls. For example, it is possible to filter out a number of key events sent by the system to a native text control by overriding wxTextCtrl and defining a handler for key events using EVT_KEY_DOWN. This would indeed prevent any key events from being sent to the native control - which might not be what is desired. In this case, the event handler function has to call Skip() so as to indicate that the search for the event handler should continue.

To summarize, instead of explicitly calling the base class version as you would do with C++ virtual functions (i.e. wxTextCtrl::OnChar()), you should instead call Skip.

In practice, this would look like the following if the derived text control only accepts 'a' to 'z' and 'A' to 'Z':

void MyTextCtrl::OnChar(wxKeyEvent& event)
{
    if ( isalpha( event.KeyCode() ) )
    {
       // key code is within legal range. we call event.Skip() so the
       // event can be processed either in the base wxWindows class
       // or the native control.

       event.Skip();
    }
    else
    {
       // illegal key hit. we don't call event.Skip() so the
       // event is not processed anywhere else.

       wxBell();
    }
}

The normal order of event table searching by ProcessEvent is as follows:

  1. If the object is disabled (via a call to wxEvtHandler::SetEvtHandlerEnabled) the function skips to step (6).
  2. If the object is a wxWindow, the ProcessEvent is recursively called on the window's wxValidator. If this returns TRUE, the function exits.
  3. SearchEventTable is called for this event handler. If this fails, the base class table is tried, and so on, until no more tables exist or an appropriate function is found, in which case the function exits.
  4. The search is applied down the entire chain of event handlers (usually the chain has a length of one). If this succeeds, the function exits.
  5. If the object is a wxWindow and the event is a wxCommandEvent, the ProcessEvent is recursively applied to the parent window's event handler. If this returns TRUE, the function exits.
  6. Finally, ProcessEvent is called on the wxApp object.

Pay close attention to step 5: People often overlook or get confused by this powerful feature of wxWindows event processing system. To put it a different way, events derived either directly or indirectly from wxCommandEvent will travel up the containment hierarchy from child to parent until an event handler is found that doesn't call event.Skip(). Events not derived from wxCommandEvent are sent to the window where they occurred and are then stopped.

Finally, there is another additional complication (which, in fact, simplifies the life of wxWindows programmers significantly): when propagating the command events upwards to the parent window, the event propagation stops when it reaches the parent dialog, if any. This means that you don't risk to get unexpected events from the dialog controls (which might be left unprocessed by the dialog itself because it doesn't care about them) when a modal dialog is popped up. The events do propagate beyond the frames, however. The rationale for this choice is that there are only a few frames in a typical application and their parent-child relation are well understood by the programmer, while it may be very difficult, if not impossible, to track down all the dialogs which may be popped up in a complex program (remember that some are created automatically by wxWindows). If you need to specify a different behavior for some reason, you can use SetExtraStyle(wxWS_EX_BLOCK_EVENTS) explicitly to prevent the events from being propagated beyond the given window or unset this flag for the dialogs which have it by default.

Typically events that deal with a window as a window (size, motion, paint, mouse, keyboard, etc.) are sent only to the window. Events that have a higher level of meaning and/or are generated by the window itself, (button click, menu select, tree expand, etc.) are command events and are sent up to the parent to see if it is interested in the event.

Note that your application may wish to override ProcessEvent to redirect the processing of events. This is done in the document/view framework, for example, to allow event handlers to be defined in the document or view. To test for command events (which are probably the only events you wish to redirect), you may use wxEvent::IsCommandEvent for efficiency, instead of using the slower run-time type system.

As mentioned above, only the command events are recursively applied to the parent's event handler. As this often causes confusion to the users, here is a list of the system events that are not sent to the parent's event handler:

wxEvent The event base class.
wxActivateEvent A window or application activation event.
wxCloseEvent A close window or end session event.
wxEraseEvent An erase background event.
wxFocusEvent A window focus event.
wxKeyEvent A keypress event.
wxIdleEvent An idle event.
wxInitDialogEvent A dialog initialization event.
wxJoystickEvent A joystick event.
wxMenuEvent A menu event.
wxMouseEvent A mouse event.
wxMoveEvent A move event.
wxPaintEvent A paint event.
wxQueryLayoutInfoEvent Used to query layout information.
wxSizeEvent A size event.
wxScrollWinEvent A scroll event sent by a scrolled window (not a scroll bar).
wxSysColourChangedEvent A system color change event.
wxUpdateUIEvent A user interface update event.

In some cases, it might be desired by the programmer to get a certain number of system events in a parent window, for example, all the key events sent to, but not used by, the native controls in a dialog. In this case, a special event handler will have to be written that will override ProcessEvent() in order to pass all the events (or any selection of them) to the parent window.

Additional points

  • You can create a "stdwx.h" file similar to the "stdafx.h" in MFC as a precompiled header. In the project settings in "C/C++" tab in the "Precompiled Headers" select "Automatically Generate (/YX)" for the "Create/Use Precompiled Header" and "stdwx.h" for the "Create/Use PCH Through File". The content of the "stdwx.h" file is as follows:
    #ifndef _stdwx_h_
    #define _stdwx_h_
    
    // SYSTEM INCLUDES
    #include <wx/wxprec.h>
    #ifdef __BORLANDC__
        #pragma hdrstop
    #endif
    #ifndef WX_PRECOMP
        #include "wx/wx.h"
    #endif
    
    // APPLICATION INCLUDES
    #endif
  • Also for the "Additional Include Directories" for the "Resources" tab in "General", for the Debug and Release configuration use:
    "$(WXWIN)\include";
  • The "setup.h" file in the wxWidgets installation has a number of switches. These switches can be used to enable/disable support for functionalities like ODBC, STL, etc. and will compile only those classes that will be used by you. They are simple define statements, whose value can be changed to 1 for enabling and 0 for disabling.

About EyeCare

Eye Care is basically inspired from Alok Gupta's application. It's a small utility program that reminds you, after a preset time interval, to give rest to your eyes and wash them, when you are lost in the matrix of programming. It sits in the taskbar, and monitors your eyes. Completely written in wxWidgets, it's another example of how easy it is to program in wxWidgets. It also shows how to put an application icon in the taskbar, save application configuration, work with images, process window specific messages, use the wxCode components like wxHyperlinkCtrl, and other concepts.

wxVisualIntergration and wxVCExpressIntegration

wxVisualIntergration and wxVCExpressIntegration written by Priyank Bolia, integrates wxWidgets support for Visual Studio .NET 2003 and Visual C++ 2005 Express by providing various wizards. The wxVisualIntergration can be downloaded from here and the wxVCExpressIntegration can be downloaded from here.

Features

  • Provides project wizard for Windows, console and DLL based applications.
  • All types of project settings, like enable Unicode, static/dynamic link, using a few mouse clicks.
  • Additional properties to choose from, like: single instance, WinXP theme, wxFormBuilder support.
  • Saves a lot of precious time, and reduces the error due to manual setting.
  • Projects have debug memory management, pre compiled headers, default menus, toolbar, statusbar, etc.

Useful sites

Some popular applications using wxWidgets

Conclusion

The wxWidgets license is essentially L-GPL (Library General Public Licence), with the exception that the derived works in binary form may be distributed on the user's own terms. This is a solution that satisfies those who wish to produce GPL'ed software using wxWidgets, and also those producing proprietary software. As you have seen, wxWidgets is the fastest to learn, easiest to use and the best possible solution (no royalties, no patents) for Windows programmers in the ever growing world of Linux and MAC.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

Priyank Bolia
Software Developer (Senior)
India India
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
AnswerRe: How to Add Group box that contain some control?memberPriyank Bolia21 Apr '08 - 1:53 
http://docs.wxwidgets.org/stable/wx_wxstaticbox.html#wxstaticbox
http://docs.wxwidgets.org/stable/wx_wxstaticboxsizer.html#wxstaticboxsizer
I told you this is not the right place to ask programming questions on wxWidgets, the best place is http://wxforum.shadonet.com/
 

QuestionHow to disable maximize button in Window?memberMember 459606618 Apr '08 - 0:12 
Hi am not sure that this can actually be done as such using a wxwidgets as you appear to be asking for. However, you can force a window not to
activate the maximize button simply :
 

It also not to be stretch by border drag using mouse.
Questionwindow That should be NON stectchable??????memberMember 459606617 Apr '08 - 21:40 
when we set prportion =0 , it create one more window inside . i just want a horizontal splitter window that is unstretchable . and we cant maximize it. i mean maximize tab should be disable. So please let me suggest the way .....
AnswerRe: window That should be NON stectchable??????memberPriyank Bolia17 Apr '08 - 21:57 
I am not able to understand what exactly you are looking for, anyway there are sample for sizers and spliter windows, where you can look at. Also you can post your problem at the http://wxforum.shadonet.com/.
 
Member 4596066 wrote:
i mean maximize tab should be disable

 
While creating the MainFrame window, don't use default style(wxDEFAULT_FRAME_STYLE), instead provide your own stlye without the wxMAXIMIZE_BOX flag.
 
Please check:
http://docs.wxwidgets.org/stable/wx_wxframe.html#wxframe
 

Generalunstrechable window i.e window with fixed size given by user.memberMember 459606616 Apr '08 - 23:25 
Hi all,
How can i fixed the size of window which should be non strechable...How can we make it nonstachable. i shall be thankful to you.
GeneralRe: unstrechable window i.e window with fixed size given by user.memberPriyank Bolia17 Apr '08 - 2:03 
When adding it to sizer, make the proportion value 0. Check the wxSizer parameters in the documentation.
 

QuestionCan we add controls like button ,listbox,combobox, etc in upper part of splitter window?????memberMember 459606615 Apr '08 - 1:40 
Hi i am using wxWidgets-2.8.3 for openphone . so in upper part of horizontal splitter window , can we add the controls like buttons etc. see log window that is the lower part of splitter window which shows the log messages. and i want some controls on upper part of splitter window . Can i add the controls over there. i shall be thankful to you.
AnswerRe: Can we add controls like button ,listbox,combobox, etc in upper part of splitter window?????memberPriyank Bolia15 Apr '08 - 1:51 
Yes, you can do anything the WinSDK allows. Check the splitter window sample in the sample directory. Also I don't actively use wxWidgets, so the best forum to ask question is http://wxforum.shadonet.com/
 

GeneralwxWidgets good introduction tutorialmembervirgil_trasca30 Mar '08 - 6:58 
wxWidgets is a great library. I did nice things with this library and I want to share to the community some of my leanings. Here is an introduction tutorial which I will update from time to time. In the near future I will publish a complete showcase of how to build a real application with wxWidgets.
GeneralwxArray questionmemberIlanTal16 Oct '07 - 5:29 
I've got the Hello World program to work, so I decided to dive into one of my existing MFC programs and try to convert it. You table describing the translations from CString to wxString etc. was very useful and a global replace worked.
 
CArray is another case. I replaced function templates and Class variables (in the *.h file) as follows:

int sortSlices(wxArray *flName, wxArray *posX,
wxArray *posY, wxArray *posZ);
int m_indx;
wxArray<imageEntry, imageEntry> m_aImage;
wxArray m_aSeries;
wxArray m_aStudy;
wxArray<imageEntry, imageEntry> m_bImage;
wxArray m_bSeries;
wxArray m_bStudy;

 
This of course doesn't work. I understood that I need an include on wx\dynarry, but still there is no such thing as wxArray. Now I see that I need
WX_DECLARE_OBJARRAY( imageEntry, ArrayOfImageEntries);
ArrayOfImageEntries m_aImage;
 
However I need to include wx/arrimpl.cpp, but this I can't put in the header file or I'll get linker errors. So where do I put it? ArrayOfImageEntries m_aImage will be used in multiple modules, so it needs to be known to all. Does it make sense to put it in StdAfx.cpp?
 
There is also the function template. There is a string array for the first variable, and the others are simple floats. Could I do something like
WX_DEFINE_ARRAY_FLOAT( float, MyArrayFloat);
int sortSlices( (stringArray) *flName, MyArrayFloat *posX, MyArrayFloat *posY, MyArrayFloat *posZ);
 
Thanks for your help.
I'm hopeful that this will be up and flying without too many problems.
 
Ilan
GeneralRe: wxArray questionmemberPriyank Bolia16 Oct '07 - 6:29 
First of all, the technical question should be asked at http://wxforum.shadonet.com/ and secondly you should use vector instead of wxArray. Using wxArray is an old fashion MFC way.
 

Generalcan't find setup.hmemberIlanTal8 Oct '07 - 3:48 
Hi,
This looks like very nice software but I am having a problem with the Hello World.
There is an include
#include "wx/wx.h"
which gives the error:

c:\Ilan\wxWidgets\include\wx\platform.h(190) : fatal error C1083: Cannot open include file: 'wx/setup.h': No such file or directory

I looked in platform.h and saw the call to include setup.h but in fact there is no setup.h.
There is setup_inc.h and setup_redirect.h.
There is: msvc\wx\setup.h which I tried to copy into the wx folder, but that didn't work.
 
Can you please tell me what I'm missing?
 
Thanks,
Ilan
GeneralRe: can't find setup.hmemberPriyank Bolia9 Oct '07 - 5:47 
http://www.wxwidgets.org/docs/faqmsw.htm#setuph
 

GeneralRe: can't find setup.hmemberIlanTal10 Oct '07 - 3:32 
Thanks for your answer. Sorry that I didn't see the FAQ entry.
Now that part works but I can't get it to link properly.

Linking...
wxmsw26d_core.lib(app.obj) : error LNK2019: unresolved external symbol __imp__InitCommonControls@0 referenced in function "public: virtual bool __thiscall wxApp::Initialize(int &,char * *)" (?Initialize@wxApp@@UAE_NAAHPAPAD@Z)
wxmsw26d_core.lib(window.obj) : error LNK2019: unresolved external symbol __imp___TrackMouseEvent@4 referenced in function "public: bool __thiscall wxWindow::HandleMouseMove(int,int,unsigned int)" (?HandleMouseMove@wxWindow@@QAE_NHHI@Z)
(clipped out most of the text to shorten message)
Debug/HelloWorld.exe : fatal error LNK1120: 20 unresolved externals

 
I don't know if the problem is in wxmsw26d_core.lib which exists and its size is 14317K, or if the missing entries are in another library. Should I try to regenerate it, or is the problem in a different library?
 
Thanks,
Ilan

GeneralRe: can't find setup.hmemberPriyank Bolia10 Oct '07 - 4:43 
comctl32.lib include this library in your program
 

QuestionEye Care link doesn't workmemberiyhernandezo16 Dec '06 - 9:55 
Hi, I was willing to probe your Eye Care software but saw that the link is broken. Can you fix this?. Thanks.
AnswerRe: Eye Care link doesn't workmemberPriyank Bolia16 Dec '06 - 19:18 
Which link broken? The html links are working perfectly.
 

QuestionwxVCExpressIntegrationmemberspidertp29 Oct '06 - 22:51 
Hello, I'd like to download your add-in to VS2005Express, but your site has always "Bandwidth Limit Exceeded" error.
Is there any other site I could download your add-in?
 
Thanks for this article!
 
Tomek
AnswerRe: wxVCExpressIntegrationmemberPriyank Bolia30 Oct '06 - 0:36 
You have to wait till next month for new bandwidth cycle, 2 days to go. Sorry can't help much.
 

GeneralRe: wxVCExpressIntegrationmemberspidertp30 Oct '06 - 1:30 
Could you send mi this add-in by e-mail?
QuestionRe: wxVCExpressIntegrationmemberJG3316 May '08 - 6:27 
Hello. The link given in the article to the site where wxVCExpressIntegration can be downloaded seems to be broken. Frown | :( Any chance this tool could be hosted on SourceForge, GoogleCode, or some other hosting site? It seems tools like this are hard to find. Thanks.
AnswerRe: wxVCExpressIntegrationmemberPriyank Bolia16 May '08 - 6:35 
You can download that wizard from:
http://priyank.co.in/infusions/pro_download_panel/download.php?catid=1
But its deprecated, and would support only Visual Express 2005 English edition.
In case if you are interested in commercial offering:
http://priyank.co.in/wxVS2008Integration.php
 

GeneralVC++ 2005 with wxWidgets UpdatememberMike Bluett17 Aug '06 - 14:50 
The instructions in this article for getting wxWidgets to work under Windows are out-of-date.
 
wxWidgets depends on the Microsoft Platform SDK to be usable. Microsoft has modified the latest PSDK 2003 SP1 so that the 32-bit libraries no longer contain certain functions that the current version of wxWidgets depends on. Even the latest CVS releases of wxWidgets (as of Aug 2006) do not work with PSDK 2003 SP1.
 
The library will compile without problem (assuming you use the right settings - details of which can be found doing a web search). However, when you try and link the library to your application you may receive link errors .
 
The PSDK that was distributed with VC++ 2003 works fine, but the new PSDK does not.
 
The best remedy is to try and get your hands on the older PSDK; otherwise, you are out of luck, unless you take it upon yourself to fix wxWidgets so that it works with PSDK 2003 SP1.
 
What is interesting is that Microsoft left these functions in the 64-bit library, but removed them from the 32-bit library. Also, there is no mention that these functions are deprecated in the MS online documentation.
 
A particular DLL (in the PSDK 2003 SP1) that is missing functions is shell32.dll. The shell32.dll that is distributed with Windows XP still contains these missing functions.
 
So, if you try using the PSDK 2003 SP1 and end up with link errors, you might want to compile wxWidgets with an older version of the PSDK.
 
An additional note: wxWidgets will not compile if you try and use the DLL version. I spent hours trying to get it to compile but without success. It does compile as static libraries.
GeneralRe: VC++ 2005 with wxWidgets UpdatememberPriyank Bolia17 Aug '06 - 17:43 
I guess for me it worked, though I exactly don't remember that I used PSDK 2003 SP1, but my guess is yes. Also the dll's worked definately for me.
There is no doubt that this article is little outdated, but anyone can anytime go to the http://wxforum.shadonet.com/ and post their problems.
 

GeneralRe: VC++ 2005 with wxWidgets Update [modified]memberMike Bluett18 Aug '06 - 16:29 
wxWidgets does not link using PSDK 2003 SP1.
 
Essentially what happens is that the linker complains of not being able to find certain functions.
 
If you then search for these functions in shell32.lib (in PSDK 2003 SP1) they do not show up. If you search the Windows XP shell32.dll or the VC++ 6.0 shell32.lib, you do find these functions.
 
If you subsequently, recompile wxWidgets using the old VC++ 6.0 libraries and then re-link the newly compiled wxWidgets with your application, everything compiles as expected.
 
Here is a few of the missing functions (which are part of wxWidgets
"base":
 
SHGetSpecialFolderLocation@12 should be in shell32.lib, but is not.
SHGetMalloc@4 should be in shell32.lib, but is not.
 
There are many more.
 
Both of these show up in the VC++ 6.0 version of shell32.lib.
 
If you do not see this problem, I suggest you download the latest PSDK 2003 SP1 and try it again. It will definitely fail to link all the files.
 
Incidentally, I already posted the problem to the wxWidgets site.
 

-- modified at 22:33 Friday 18th August, 2006

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 25 Dec 2005
Article Copyright 2005 by Priyank Bolia
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid