Wxtutorial PDF
Wxtutorial PDF
The author of this book makes no warranty of any kind, expressed or implied, with
regard to the programs or the documentation contained in this book.
wxWindows – Programming cross-platform GUI applications in C++ -2-
1 Contents
1 CONTENTS 2
2 INTRODUCTION 6
3 USING WXFRAME 13
4 EVENT HANDLING 20
4.1 INTRODUCTION 20
4.2 HOW IT WORKS 20
4.3 EVENT SKIPPING 21
4.4 VETOING AN EVENT 22
4.5 PLUG AN EVENT HANDLER 22
5 COMMON DIALOGS 24
5.1 INTRODUCTION 24
5.2 WXFILEDIALOG 24
5.3 WXCOLOURDIALOG 25
5.4 WXFONTDIALOG 26
5.5 WXPRINTDIALOG 27
5.6 WXDIRDIALOG 27
5.7 WXTEXTENTRYDIALOG 27
5.8 WXMESSAGEDIALOG 28
5.9 WXSINGLECHOICEDIALOG 28
-2-
wxWindows – Programming cross-platform GUI applications in C++ -3-
5.10 WXWIZARD 28
6 DIALOGS 29
7 STANDARD CONTROLS 39
7.1 WXBUTTON 39
7.1.1 METHODS 39
7.1.2 EVENT HANDLING 40
7.1.3 EXAMPLE 40
7.2 WXBITMAPBUTTON 41
7.2.1 METHODS 41
7.2.2 EVENT HANDLING 42
7.2.3 EXAMPLE 42
7.3 WXCALENDARCTRL 43
7.3.1 METHODS 43
7.3.2 WXCALENDARDATEATTR 44
7.3.3 EVENT HANDLING 46
7.3.4 EXAMPLE 46
7.4 WXCHECKBOX 47
7.4.1 METHODS 47
7.4.2 EVENT HANDLING 48
7.4.3 EXAMPLE 48
7.5 WXCHECKLISTBOX 49
7.5.1 METHODS 49
7.5.2 EVENT HANDLING 49
7.5.3 EXAMPLE 50
7.6 WXCHOICE 51
7.6.1 METHODS 51
7.6.2 EVENT HANDLING 52
7.6.3 EXAMPLE 52
7.7 WXCOMBOBOX 53
7.7.1 METHODS 53
7.7.2 EVENT HANDLING 54
7.7.3 EXAMPLE 54
7.8 WXGAUGE 55
7.8.1 METHODS 56
7.8.2 EVENT HANDLING 56
7.8.3 EXAMPLE 56
7.9 WXLISTBOX 57
7.9.1 METHODS 58
7.9.2 EVENT HANDLING 59
7.9.3 EXAMPLE 59
-3-
wxWindows – Programming cross-platform GUI applications in C++ -4-
7.10 WXRADIOBOX 60
7.10.1 METHODS 61
7.10.2 EVENT HANDLING 62
7.10.3 EXAMPLE 62
7.11 WXRADIOBUTTON 63
7.11.1 METHODS 63
7.11.2 EVENT HANDLING 63
7.11.3 EXAMPLE 64
7.12 WXSLIDER 65
7.12.1 METHODS 66
7.12.2 EVENT HANDLING 67
7.12.3 EXAMPLE 67
7.13 WXSPINCTRL 68
7.13.1 METHODS 69
7.13.2 EVENT HANDLING 69
7.13.3 EXAMPLE 69
7.14 WXSTATICBITMAP 70
7.14.1 METHODS 70
7.14.2 EXAMPLE 70
7.15 WXSTATICBOX 71
7.15.1 EXAMPLE 71
7.16 WXSTATICLINE 72
7.16.1 METHODS 72
7.16.2 EXAMPLE 72
7.17 WXSTATICTEXT 73
7.17.1 METHODS 74
7.17.2 EXAMPLE 74
7.18 WXTEXTCTRL 74
7.18.1 METHODS 75
7.18.2 EVENTS 77
7.18.3 EXAMPLE 77
8 VALIDATORS 79
9 SCROLLING 83
10 SPLITTING WINDOWS 84
11 COMMON CONTROLS 85
11.1 TOOLBAR 85
11.1.1 EVENTS 85
11.2 TREE CONTROL 85
11.2.1 ITEMS 86
-4-
wxWindows – Programming cross-platform GUI applications in C++ -5-
12 PROPERTY SHEETS 93
13 HTML 94
14 DOCUMENT/VIEW FRAMEWORK 95
15 THE CLIPBOARD 96
17 PRINTING 98
18 DRAWING 99
19 STRINGS 100
-5-
wxWindows – Programming cross-platform GUI applications in C++ -6-
24 LOGGING 106
25 DATABASES 107
26 MULTITHREADING 108
27 DEBUGGING 109
2 Introduction
wxWindows is the solution. wxWindows hides all the platform specific code for you. There
are many platform independent frameworks available. So why should you choose for
wxWindows?
-6-
wxWindows – Programming cross-platform GUI applications in C++ -7-
-7-
wxWindows – Programming cross-platform GUI applications in C++ -8-
2.3.5 Mac
When you’re going to use makefiles to build wxWindows, make sure you set the WXWIN
environment variable. It should point to the installation directory. An example:
SET WXWIN=c:\wx
Use the project file wxvc.dsp which you can find in the /src directory. Use Batch build
to build both a Debug and a Release version of wxWindows.
Previous versions of Visual C++ can use the makefile makefile.vc. For more
information about how to do this read the install.txt file which you can find in the
/doc/msw directory.
! Mingw32
MinGW is a collection of header files and import libraries that allow you to use GCC
and produce native Windows32 programs that do not rely on any 3rd-party DLLs. The
current set of tools includes GNU Compiler Collection (GCC), GNU Debugger (GDB),
GNU make, and other utilities.
First, don’t forget to set the WXWIN environment variable. Before you can compile
wxWindows you have to perform the following tasks:
• Download extra.zip from the remstar ftp site: ftp://www.remstar.com/pub/. (see
folder \wxwin\ports\mingw32)
• Extract cp.exe and rm.exe from extra.zip and put them in the bin-directory of
your Mingw compiler.
• When the PATH environment variable doesn’t include the bin directory of the
Mingw compiler, then you have to update mingw32.bat (in the src directory) to
make sure the compiler can be found.
• Run mingw32.bat
• When necessary, update the makeg95.env file (see below). This file contains all
the common settings for wxWindow programs.
• Only for version lower then 2.2.9: The INT32 problem: Mingw32 already defines
INT32. The problem is that it is defined as int, which is not the same as defined in
wxWindows. Add the –DINT32_DEFINED compiler option in makeg95.env. Change
the jinclude.h header file, which you can find in the jpeg directory, and add the
following line at the top of the source code.
typedef int INT32;
• Change the working directory to src/msw and run “make –f makefile.g95”.
-8-
wxWindows – Programming cross-platform GUI applications in C++ -9-
• When you want to debug your applications with GDB then add –g to the
debugflags. Your executables will be enormous, because debug information is
created in each object file.
When the make program complains about some include files it cannot find, you can
change the makeg95.env file as follows:
#ifeq ($(MINGW32),1)
#INC = -I$(WXINC) -I$(WXDIR)/contrib/include -I$(WXDIR)/src/png -I$(WXDIR)/src/jpeg -
I$(WXDIR)/src/zlib -I$(WXDIR)/src/xpm -I$(WXDIR)/src/tiff $(EXTRAINC) $(COMPPATHS)
#else
INC = -I$(WXINC) -I$(WXDIR)/contrib/include -I$(WXDIR)/src/png -I$(WXDIR)/src/jpeg -
I$(WXDIR)/src/zlib -I$(WXDIR)/src/xpm -I$(WXDIR)/src/tiff $(EXTRAINC) $(COMPPATHS) -
I$(WXDIR)/include/wx/msw/gnuwin32
#endif
Change it into:
#ifeq ($(MINGW32),1)
#WINC = -I$(WXINC) -I$(WXDIR)/contrib/include -I$(WXDIR)/src/png -I$(WXDIR)/src/jpeg -
I$(WXDIR)/src/zlib -I$(WXDIR)/src/xpm -I$(WXDIR)/src/tiff $(EXTRAINC) $(COMPPATHS)
#else
WINC = -I$(WXINC) -I$(WXDIR)/contrib/include -I$(WXDIR)/src/png -I$(WXDIR)/src/jpeg -
I$(WXDIR)/src/zlib -I$(WXDIR)/src/xpm -I$(WXDIR)/src/tiff $(EXTRAINC) $(COMPPATHS) -
I$(WXDIR)/include/wx/msw/gnuwin32
#endif
You probably have to do this when you use the Dev-C++ IDE that contains the
Mingw32 compiler.
! Debug configuration
C/C++ Tab
Link Tab
-9-
wxWindows – Programming cross-platform GUI applications in C++ - 10 -
! Release configuration
C/C++ Tab
Link Tab
! All configurations
C/C++ Tab
c:\<wx-path>\include;c:\<wx-path>\contrib\include
Of course you can add other directories you wish to use in your project. You can
skip this setting when you add those directories to the options ‘Directories’.
Link Tab
c:\<wx-path>\lib, c:\<wx-path>\contrib\lib
Replace the <wx-path> with the path where wxWindows is installed. You can skip
this setting when you add those directories to the options ‘Directories’.
2.5.2 Mingw32
You have to create a resource file when you run your application on Windows. The only
requirement is that you include wx.rc.
#include “wx/msw/wx.rc”
- 10 -
wxWindows – Programming cross-platform GUI applications in C++ - 11 -
The name of the resource file should be the same as the target in your makefile. Create a
makefile as shown in Example 1.
Example 1. A makefile for MingW.
WXDIR = $(WXWIN)
EXTRAINC=
EXTRACPPFLAGS=
EXTRALIBS=
EXTRALDFLAGS=
TARGET=YourApplicationName
OBJECTS=YourApplication.o YourFrame.o
include $(WXDIR)/src/makeprog.g95
Use the EXTRAINC to specify additional directories for header files. EXTRALIBS can be
used to specify some extra libraries to link with and use EXTRACPPFLAGS to define
additional preprocessor definitions. EXTRALDFLAGS is used to specify additional link flags
and directories for searching libraries. OBJECTS is a list of the object files which are
related to your source files.
Example 2 shows you how a makefile is created to use expat, the XML parser.
Because the linker of MingW (ld) searches for libraries with a “.a” suffix, you probably
have to rename some libraries, or you have to specify the full path when using the –l
option flag.
Each wxWindow application needs an object derived from wxApp. Each application
overrides the OnInit() method for initializing the application. You can, for example, create
your main window here. Example 3 shows the definition of HelloWorldApp.
Example 3. HelloWorldApp.h - The HelloWorldApp definition
#ifndef _HELLOWORLDAPP_H
#define _HELLOWORLDAPP_H
/**
* The HelloWorldApp class
* This class shows a window containing a statusbar with the text ‘Hello World’
*/
class HelloWorldApp : public wxApp
{
public:
virtual bool OnInit();
};
DECLARE_APP(HelloWorldApp)
#endif _HELLOWORLDAPP_H
For the main window, you use the wxFrame class. This class provides a window whose
size and position can be changed by the user. It has thick borders and a title bar. In
addition, you can provide it a menu bar, a statusbar and a toolbar. Example 4 shows the
implementation of HelloWorldApp.
- 11 -
wxWindows – Programming cross-platform GUI applications in C++ - 12 -
#ifndef WX_PRECOMP
#include “wx/wx.h”
#endif
#include “HelloWorldApp.h”
IMPLEMENT_APP(HelloWorldApp)
bool HelloWorldApp::OnInit()
{
wxFrame *frame = new wxFrame((wxFrame*) NULL, -1, “Hello World”);
frame->CreateStatusBar();
frame->SetStatusText(“Hello World”);
frame->Show(TRUE);
SetTopWindow(frame);
return true;
}
When you’re compiler supports precompiled headers, you can use the wxprec header file.
When it doesn’t, you should include wx.h, which includes all necessary header files for
wxWindow. You can also include each header file separately for each control.
The macros DECLARE_APP and IMPLEMENT_APP does the following for us:
# When the platform needs one, it creates a main() or WinMain() method.
# It creates the global method wxGetApp(). You can use this function to retrieve a
reference to the one and only application object.
Example:
HelloWorldApp &app = (HelloWorldApp&) wxGetApp();
You could be wondering why the frame variable isn’t deleted somewhere. By setting the
frame as the top window of the application, the application will delete the frame for us.
The cast of NULL to wxFrame* is done because some compilers define NULL as 0L so that
no conversion to pointers is allowed. This cast makes the code a little bit more portable.
After the frame is constructed, a statusbar is created with the CreateStatusBar method.
The text of the statusbar is set to “Hello World”. Calling the Show method shows the
frame. Show is a method of the wxWindow class which wxFrame derives from.
When the OnInit()-method returns false the application immediately stops. This way you
can stop the application when something went wrong during the initialization phase.
- 12 -
wxWindows – Programming cross-platform GUI applications in C++ - 13 -
3 Using wxFrame
The wxFrame class provides us a frame window. A frame window is a window whose size
can be changed. It has a thick border, a title bar. Optionally it can have a menubar, a
toolbar or a statusbar. A frame can act as a container for other controls except for
another frame or a dialog. wxFrame is derived from wxWindow.
/**
* Destructor
*/
~TextFrame();
};
#endif _TEXTFRAME_H
The constructor of wxFrame is called from the TextFrame constructor. The constructor of
wxFrame is defined as follows:
! parent is a pointer to the parent window. In this example, the frame doesn’t have
any parent, so NULL is passed.
! id is the window identifier. –1 indicates the default.
! title is the name of the window. This will be shown in the frame’s title bar.
! pos is the window position. A value of (-1, -1) indicates the default (=
wxDefaultPosition). Depending on the platform this default is chosen by the
windowing system or wxWindow.
! size is the window size. A value of (-1, -1) indicates the default (= wxDefaultSize).
Depending on the platform this default is chosen by the windowing system or
wxWindow.
! style is the window style. wxFrame defines the following additional styles:
- 13 -
wxWindows – Programming cross-platform GUI applications in C++ - 14 -
! name is the name of the window. This parameter is used to associate a name with an
item. This allows the application user to set Motif resource values for individual
windows.
Example 6. TextFrame.cpp – The TextFrame implementation
// For compilers that supports precompilation , includes “wx/wx.h”
#include “wx/wxprec.h”
#ifndef WX_PRECOMP
#include “wx/wx.h”
#endif
#include “TextFrame.h”
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
}
TextFrame::~TextFrame()
{
}
DECLARE_APP(TextEditorApp)
#endif // TEXTEDITORAPP_H
#ifndef WX_PRECOMP
#include “wx/wx.h”
#endif
#include “TextEditorApp.h”
#include “TextFrame.h”
IMPLEMENT_APP(TextEditorApp)
bool TextEditorApp::OnInit()
{
TextFrame *frame = new TextFrame(“Simple Text Editor”, 100, 100, 400, 300);
frame->Show(TRUE);
- 14 -
wxWindows – Programming cross-platform GUI applications in C++ - 15 -
SetTopWindow(frame);
return true;
}
Example 9 shows the new definition of the TextFrame class. The only thing that’s
changed is that you add a member of the type wxTextCtrl. This member is initialized in
the constructor.
Example 9. TextFrame.h – The TextFrame definition with wxTextCtrl
#ifndef _TEXTFRAME_H
#define _TEXTFRAME_H
/**
* Destructor
*/
~TextFrame();
private:
wxTextCtrl *m_pTextCtrl;
};
#endif _TEXTFRAME_H
Example 10 shows the new constructor of the TextFrame class. The parent of the
wxTextCtrl member is the TextFrame, so we pass the this pointer. The text ‘Type some
text…’ will be shown as the default text. Notice that the wxTextCtrl’s constructor looks
similar to the wxFrame’s constructor. Each class derived from wxWindow follows the
same constructor pattern.
Again, you don’t see code for deleting the pointer of wxTextCtrl. You don’t need to,
because TextFrame is the parent that will delete all it’s children when it is destroyed.
wxTE_MULTILINE is a specific window-style for a text control. This style indicates that
wxTextCtrl allows multiple lines. See chapter 7.10 for more information about different
styles.
#ifndef WX_PRECOMP
#include “wx/wx.h”
#endif
#include “TextFrame.h”
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
m_pTextCtrl = new wxTextCtrl(this, -1, wxString(“Type some text...”),
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
}
- 15 -
wxWindows – Programming cross-platform GUI applications in C++ - 16 -
TextFrame::~TextFrame()
{
}
When you build this project, you’ll have an application that shows a window where you
can enter some text. Try cut, paste, and you’ll see that this small piece of code does a lot
for you.
Each menu needs a unique ID. In Example 11 you see this is done by using an enum.
#define for defining constants (e.g. #define MENU_FILE_MENU 1) isn’t used because this
can’t guarantee you that you have unique ID’s. It’s quit easily to overlook some values
and it’s difficult to maintain when you have to insert new ID’s.
Example 11. TextFrame.h - The TextFrame definition with menus
#ifndef _TEXTFRAME_H
#define _TEXTFRAME_H
/**
* Destructor
*/
~TextFrame();
private:
wxTextCtrl *m_pTextCtrl;
wxMenuBar *m_pMenuBar;
wxMenu *m_pFileMenu;
wxMenu *m_pInfoMenu;
enum
{
MENU_FILE_OPEN,
MENU_FILE_SAVE,
MENU_FILE_QUIT,
MENU_INFO_ABOUT
};
};
#endif _TEXTFRAME_H
In the implementation of TextFrame in Example 12 you see how the menubar is created
in the constructor of TextFrame. A menu-item is added to the menu using the Append
method of wxMenu. Note how the ampersand is used to indicate which character is used
as the hotkey. When the menu is created you use Append method from wxMenuBar to
append it to the menubar.
Example 12. TextFrame.cpp – The TextFrame implementation with menus
// For compilers that supports precompilation , includes “wx/wx.h”
#include “wx/wxprec.h”
#ifndef WX_PRECOMP
#include “wx/wx.h”
#endif
#include “TextFrame.h”
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
m_pTextCtrl = new wxTextCtrl(this, -1, wxString(“Type some text...”),
- 16 -
wxWindows – Programming cross-platform GUI applications in C++ - 17 -
SetMenuBar(m_pMenuBar);
}
TextFrame::~TextFrame()
{
}
Example 13 creates a statusbar that contains 3 fields. The text “Ready” is displayed in
the first field.
The statusbar can also be used to display a description of the selected menu. Example 14
shows you how to change Example 12. When you select a menu, the description is
displayed in the first field of the statusbar.
Example 14. Menus with a description-text.
// File menu
m_pFileMenu = new wxMenu();
m_pFileMenu->Append(MENU_FILE_OPEN, “&Open”, “Opens an existing file”);
m_pFileMenu->Append(MENU_FILE_SAVE, “&Save”, “Save the content”);
m_pFileMenu->AppendSeparator();
m_pFileMenu->Append(MENU_FILE_QUIT, “&Quit”, “Quit the application”);
m_pMenuBar->Append(m_pFileMenu, “&File”);
// About menu
m_pInfoMenu = new wxMenu();
m_pInfoMenu->Append(MENU_INFO_ABOUT, “&About”, “Shows information about the application”);
m_pMenuBar->Append(m_pInfoMenu, “&Info”);
Each window that processes events needs to declare an event table. The
DECLARE_EVENT_TABLE macro is used for this. You also need to define the methods for
your actions. An event received from a menu is a wxCommandEvent. This is the type of
- 17 -
wxWindows – Programming cross-platform GUI applications in C++ - 18 -
the parameter of your methods. Example 15 contains the full definition of the TextFrame
class.
Example 15. TextFrame.h – The TextFrame definition with an event table
#ifndef _TEXTFRAME_H
#define _TEXTFRAME_H
/**
* Destructor
*/
~TextFrame();
/**
* Processes menu File|Open
*/
void OnMenuFileOpen(wxCommandEvent &event);
/**
* Processes menu File|Save
*/
void OnMenuFileSave(wxCommandEvent &event);
/**
* Processes menu File|Quit
*/
void OnMenuFileQuit(wxCommandEvent &event);
/**
* Processes menu About|Info
*/
void OnMenuInfoAbout(wxCommandEvent &event);
protected:
DECLARE_EVENT_TABLE()
private:
wxTextCtrl *m_pTextCtrl;
wxMenuBar *m_pMenuBar;
wxMenu *m_pFileMenu;
wxMenu *m_pInfoMenu;
enum
{
MENU_FILE_OPEN,
MENU_FILE_SAVE,
MENU_FILE_QUIT,
MENU_INFO_ABOUT
};
};
#endif _TEXTFRAME_H
The event table is placed in the implementation file. wxWindows helps you with a bunch
of macros. The BEGIN_EVENT_TABLE macro is used to declare the beginning of the event
table. Because you can have many event tables in your program you pass the name of
the class that processes the events in the macro. To attach your method to the event,
you use the EVT_MENU macro. The end of the event table is marked with the
END_EVENT_TABLE macro.
Example 16 is the full implementation of the TextFrame class.
Example 16. TextFrame.cpp – The TextFrame implementation that processes menu events
// For compilers that supports precompilation , includes “wx/wx.h”
#include “wx/wxprec.h”
#ifndef WX_PRECOMP
#include “wx/wx.h”
#endif
- 18 -
wxWindows – Programming cross-platform GUI applications in C++ - 19 -
#include “TextFrame.h”
TextFrame::TextFrame(const wxChar *title, int xpos, int ypos, int width, int height)
: wxFrame((wxFrame *) NULL, -1, title, wxPoint(xpos, ypos), wxSize(width, height))
{
m_pTextCtrl = new wxTextCtrl(this, -1, wxString(“Type some text…”),
wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
CreateStatusBar();
m_pMenuBar = new wxMenuBar();
// File Menu
m_pFileMenu = new wxMenu();
m_pFileMenu->Append(MENU_FILE_OPEN, “&Open”, “Opens an existing file”);
m_pFileMenu->Append(MENU_FILE_SAVE, “&Save”, “Saves the file”);
m_pFileMenu->AppendSeparator();
m_pFileMenu->Append(MENU_FILE_QUIT, “&Quit, “Close the application”);
m_pMenuBar->Append(m_pFileMenu, “&File”);
// About menu
m_pInfoMenu = new wxMenu();
m_pInfoMenu->Append(MENU_INFO_ABOUT, “&About”, “Shows info about the application”);
m_pMenuBar->Append(m_pInfoMenu, “&Info”);
SetMenuBar(m_pMenuBar);
}
TextFrame::~TextFrame()
{
}
BEGIN_EVENT_TABLE(TextFrame, wxFrame)
EVT_MENU(MENU_FILE_OPEN, TextFrame::OnMenuFileOpen)
EVT_MENU(MENU_FILE_SAVE, TextFrame::OnMenuFileSave)
EVT_MENU(MENU_FILE_QUIT, TextFrame::OnMenuFileQuit)
EVT_MENU(MENU_INFO_ABOUT, TextFrame::OnMenuInfoAbout)
END_EVENT_TABLE
Try this program and see what the results are. The Open and Save menu items of the
File menu are not yet implemented. How you can open, read and save a file is explained
in chapter 24 and how you can use common dialogs for opening and saving files is
explained in chapter 5.
- 19 -
wxWindows – Programming cross-platform GUI applications in C++ - 20 -
4 Event Handling
In chapter 3.5 on page 17 you’ve already learned how to do the event handling for
menus. In this chapter, you’ll learn how event handling works and how to handle other
events.
4.1 Introduction
An event is something that occurred in your application or outside your application. An
event might be initiated by the user, another application, the operating system… You
need a mechanism to react on the events you’re interested in.
The above event-table tells wxWindows when it receives a WM_SIZE event for your
frame to call the OnSize member function of the MyFrame class. The
BEGIN_EVENT_TABLE macro declares that MyFrame, which is derived from wxFrame,
owns this event table.
The member function that handles an event does not have to be virtual. Actually the
event handler ignores the virtual declaration. These functions have a similar form: the
return type is void and they receive an event parameter. The type of this parameter
depends on the event. For size events, wxSizeEvent is used. For menu commands and
most control commands (e.g. a button), wxCommandEvent is used. When controls get
more complicated, they use their own event class.
All these macros are used to hide the complexity of the event-handling system. For a
complete list of these event-macros, look at Appendix A: Event Macros on page 115.
- 20 -
wxWindows – Programming cross-platform GUI applications in C++ - 21 -
4. The search is applied down the entire chain of event handlers. When this succeeds
(meaning the event is processed) the function exits.
5. When the object is a wxWindow and the event is a wxCommandEvent, ProcessEvent
is recursively applied to the parent window’s event handler. When this returns true,
the function exits. This way a button click will be processed by the parent of the
button and not by the button itself.
6. Finally, ProcessEvent is called on the wxApp object.
#ifndef WX_PRECOMP
#include “wx/wx.h”
#endif
#include “NumTextCtrl.h”
#include <ctype.h>
BEGIN_EVENT_TABLE(NumTextCtrl, wxTextCtrl)
EVT_CHAR(NumTextCtrl::OnChar)
END_EVENT_TABLE()
When NumericTextCtrl receives a key event, the keycode is checked. When the entered
key is numeric, the base class wxTextCtrl may process the event. That’s why the Skip
method is called on the event. You must call the Skip method here, because otherwise no
key would be processed.
- 21 -
wxWindows – Programming cross-platform GUI applications in C++ - 22 -
if ( event.CanVeto() )
{
if ( m_pTextCtrl->IsModified() )
{
wxMessageDialog *dlg =
new wxMessageDialog(this, "Text is changed!\nAre you sure you want to exit?",
"Text changed!!!", wxYES_NO | wxNO_DEFAULT);
int result = dlg->ShowModal();
if ( result == wxID_NO )
{
event.Veto();
destroy = false;
}
}
}
if ( destroy )
{
Destroy();
}
When does CanVeto return false? You can’t veto an event when the task manager ends
your program, when the user logs off, …
The solution for this problem is to create a new event handler and plug it into a
wxWindow class. To do this, you create a new class derived from wxEvtHandler. Within
this new class, you do the same as you would when you do event handling for a normal
window. The code is shown in Example 21 and Example 22.
private:
};
#endif // _LogEventHandler_H
- 22 -
wxWindows – Programming cross-platform GUI applications in C++ - 23 -
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "LogEventHandler.h"
BEGIN_EVENT_TABLE(LogEventHandler, wxEvtHandler)
EVT_MENU_RANGE(-1, -1, LogEventHandler::OnMenu)
END_EVENT_TABLE()
With the EVT_MENU_RANGE macro, you can handle a range of menus. The first two
parameters specify the range of id’s you want to handle. –1 means that you want to
handle all the menu items.
The next step is to push the new event handler in the stack of handlers. This is done
using the PushEventHandler method of the wxWindow class. Removing the event handler
is done PopEventHandler method.
PushEventHandler(new LogEventHandler());
The PopEventHandler method has a boolean parameter. When this parameter is true,
wxWindows will delete the event handler. Note that when you don’t pop the event
handler, wxWindows will try to delete the event handler when the window is destroyed.
This can generate access violation errors when you didn’t create the event handler on the
heap. Avoid these errors by calling PopEventHandler with parameter false in the
destructor of your class.
- 23 -
wxWindows – Programming cross-platform GUI applications in C++ - 24 -
5 Common Dialogs
5.1 Introduction
In chapter 3.5 on page 17 you provided menu commands for opening and saving a text-
file. To allow the user to select or enter a filename you can use a common dialog:
wxFileDialog. When common dialogs are used, you give the user a consistent interface.
No matter which application the user uses, they can expect to see a dialog that looks
familiar.
You’ll see in the following examples that for every dialog the Destroy method is called
instead of deleting the pointer. This is done for consistency purposes. wxWindows
controls should always be created on the heap and they are safely removed when you
call the Destroy method. This is because wxWindows sometimes delays deletion until all
events are processed. This way wxWindows avoids that events are sent to non-existing
windows.
5.2 wxFileDialog
wxFileDialog is used to present the user a dialog where he can select or enter a filename
when he wants to open or save a file. The constructor of wxFileDialog looks like this:
- 24 -
wxWindows – Programming cross-platform GUI applications in C++ - 25 -
dialog’s “files of type” combo-box. Use the following syntax for this:
description|extension. The following example gives the user the possibility to view all
files, all text-files and all bitmap files: “All files(*.*)|*.*|Text files(*.txt)|*.txt|Bitmap
files(*.bmp)|*.bmp”
! style is the type of the dialog.
Example 23 completes the text editor you’ve written in chapter 3. The ShowModal
method displays the dialog. “Modal” means that no other window of the application can
get the focus until the dialog is closed. ShowModal returns wxID_OK when the user
presses OK and wxID_CANCEL otherwise. GetFilename is used to retrieve the name of
the file that is selected. GetPath will return the full path (directory and filename) of the
selected file. Loading and saving text is very simple when the wxTextCtrl class is used.
You can use the methods LoadFile and SaveFile.
Example 23. Implementation of the File Open and File Save menu actions.
void TextFrame::OnMenuFileOpen(wxCommandEvent &event)
{
wxFileDialog *dlg = new wxFileDialog(this, "Open a text file",
"", "", "All files(*.*)|*.*|Text Files(*.txt)|*.txt",
wxOPEN, wxDefaultPosition);
if ( dlg->ShowModal() == wxID_OK )
{
m_pTextCtrl->LoadFile(dlg->GetFilename());
SetStatusText(dlg->GetFilename(), 0);
}
dlg->Destroy();
}
5.3 wxColourDialog
wxColourDialog implements a dialog where the user can select a color. wxColourDialog is
used together with wxColourData. wxColourData is used to set the current color in the
dialog and to get the selected color. The constructor of wxColourDialog looks like this:
- 25 -
wxWindows – Programming cross-platform GUI applications in C++ - 26 -
Example 24 adds a menu-item to the application to allow the user to select another
background color. The current background-color is assigned to colourData. When the
application runs on a Windows-system the full dialog is displayed.
Example 24. Selecting a color with wxColourDialog
void TextFrame::OnMenuOptionBackgroundColor(wxCommandEvent &event)
{
wxColourData colourData;
wxColour colour = m_pTextCtrl->GetBackgroundColour();
colourData.SetColour(colour);
colourData.SetChooseFull(true);
wxColourDialog *dlg = new wxColourDialog(this, &colourData);
if ( dlg->ShowModal() == wxID_OK )
{
colourData = dlg->GetColourData();
m_pTextCtrl->SetBackgroundColour(colourData.GetColour());
m_pTextCtrl->Refresh();
}
dlg->Destroy();
}
5.4 wxFontDialog
wxFontDialog is used to show the user a dialog where he can select a font. This dialog is
used together with wxFontData, wxFont and wxColour. wxFontData is used to set the
current font in the dialog and to get the selected font. The constructor of the
wxFontDialog looks like this:
Example 25 implements a new menu item for changing the font in the editor. First of all
fontData is filled with the current font and color. When the application runs on a
Windows-system, the user will see a help-button. When the user selects the font,
fontData is used to set the new font and foregroundcolor.
Example 25.Selecting a font with wxFontDialog
void TextFrame::OnMenuOptionFont(wxCommandEvent& event)
{
wxFontData fontData;
wxFont font;
wxColour colour;
font = m_pTextCtrl->GetFont();
fontData.SetInitialFont(font);
colour = m_pTextCtrl->GetForegroundColour();
fontData.SetColour(colour);
fontData.SetShowHelp(true);
- 26 -
wxWindows – Programming cross-platform GUI applications in C++ - 27 -
5.5 wxPrintDialog
wxPrintDialog is used to print a document and to set the printer options. It’s used
together with wxPrinterData and wxPrinterDC
5.6 wxDirDialog
wxDirDialog is used to select a directory. The constructor looks like this:
The following example shows an implementation of a menu item to set a new working
directory. wxGetCwd is used to retrieve the current working directory. When the user
selected a directory you can retrieve the name of the directory with the GetPath method.
wxSetWorkingDirectory is used to set the new working directory.
5.7 wxTextEntryDialog
wxTextEntryDialog is a dialog that requests a one-line text from the user. The
constructor looks like this:
As you can see in the following example wxTextEntryDialog is ideal to prompt the user
for a password.
- 27 -
wxWindows – Programming cross-platform GUI applications in C++ - 28 -
5.8 wxMessageDialog
wxMessageDialog can be used to show a single or multi-line message, with a choice of
OK, Yes, No or Cancel. The constructor looks like this:
On page 22 you see Example 20 that uses wxMessageDialog to ask the user if he is sure
to exit the application.
5.9 wxSingleChoiceDialog
To Do
5.10 wxWizard
To Do
- 28 -
wxWindows – Programming cross-platform GUI applications in C++ - 29 -
6 Dialogs
A dialog box is a window with a title bar. The window can be moved and it can contain
controls and other windows. A dialog can be modal or modeless. A modal dialog blocks
the flow of the program until the dialog is closed.
When you use dialogs in your program, wxWindows needs a resource file. When you
don’t need extra icons, it can be as simple as you can see in Example 26.
Example 27 shows you the definition of a dialog that shows the about-information of the
simple text editor you have developed in the previous chapters. Example 28 shows the
implementation.
Example 27. AboutDialog.h – The AboutDialog definition
#ifndef _ABOUTDIALOG_H
#define _ABOUTDIALOG_H
/**
- 29 -
wxWindows – Programming cross-platform GUI applications in C++ - 30 -
* Destructor
*/
virtual ~AboutDialog() { }
/**
* Sets the text on the dialog
*/
void SetText(const wxString& text);
private:
wxStaticText *m_pInfoText;
wxButton *m_pOkButton;
};
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "AboutDialog.h"
You can see in the examples that there’s no event handling. You don’t need to provide it
because you can use the default event handling of wxWindows. A dialog is automatically
closed when the user clicks on a button that has the wxID_OK or wxID_CANCEL
identifier. Example 29 shows you how you can show the dialog when the user clicks on
the about menu item.
When you don’t use the default handling, you don’t use an Ok button for example, then
you need to destroy the dialog yourself (by calling Destroy()) in the EVT_CLOSE event!
Your application keeps running when you don’t destroy the dialog.
When you execute the text editor and select the Info/About menu, you must see a dialog
as shown in Figure 1.
- 30 -
wxWindows – Programming cross-platform GUI applications in C++ - 31 -
6.2.1 wxLayoutConstraints
Instead of calculating the positions of the controls when you get an EVT_SIZE event,
wxWindows helps you with the wxLayoutConstraints class to layout the controls on a
parent window. Each window can be associated with a wxLayoutConstraints object to
define the way it is laid out, with respect to its sibling or the parent.
The constraints are initially set to wxUnconstrained, which means that their values should
be calculated by looking at known constraints. The layout algorithm needs to know
exactly 4 constraints, to calculate the position and size of the control.
Therefore, you should always set exactly 4 constraints of the above table.
The algorithm is executed when the Layout method of wxWindow is called. You can use
the SetAutoLayout method to automatically call Layout when the window, frame, dialog
or panel is resized. Alternatively, you can call Layout yourself.
Absolute(int value)
Constrains the edge to be the given absolute value.
- 31 -
wxWindows – Programming cross-platform GUI applications in C++ - 32 -
AsIs()
Sets the edge or constraint to the current value of the window’s value. If either the width
or the height constraints are as is, the window is not resized but moved. This is often
used when the size of a control is not allowed to change (e.g. a button)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "AboutDialog.h"
Layout();
}
- 32 -
wxWindows – Programming cross-platform GUI applications in C++ - 33 -
layout->top.Below(m_pInfoText, 10);
The top of the button is below m_pInfoText with a margin of 10.
layout->centreX.SameAs(this, wxCentreX);
The horizontal center of the button is the same as the center of its parent.
layout->width.PercentOf(this, wxWidth, 80);
The width is 80% of the width of its parent.
layout->height.AsIs();
The height is kept unchanged.
As you can see in Figure 2 the layout of the dialog is much better now.
6.2.2 wxSizer
The preferred way of wxWindows to layout controls on your dialogs are sizers. Sizers are
classes derived from wxSizer. The most important method of wxSizer is Add. With this
method, you add controls, other sizers or spacers as items to a sizer.
Adding controls
- 33 -
wxWindows – Programming cross-platform GUI applications in C++ - 34 -
Border flags:
Behavior flags:
Adding sizers
Sizers can be nested. See adding controls for a detailed explanation of all the
parameters.
Adding spacers
void Add(int width, int height, int option = 0, int flag = 0, int border = 0,
wxObject* userData = NULL)
A spacer can be used to keep space between controls. You could for example add a
spacer between two buttons on a dialog. When the spacer is allowed to grow, the result
will be that the first button is kept left aligned and the other one is kept right aligned.
! wxBoxSizer
A box sizer is used to layout your controls in a row/column hierarchy. A box sizer can
grow in both directions. Depending on the flags you specify, a box sizer will grow
vertically and/or horizontally. When you create a box sizer, you have to give it a main
orientation.
First, a sizer is created for the full dialog. Its main orientation is vertical. All the other
sizers, who are children of the dialog sizer, will have a horizontal main orientation.
They are allowed to grow horizontally, but not vertically. The second sizer is used to
layout the Ok button. This is done to keep a fixed margin between the button and the
edge of the dialog. When the button is added, a border of size 20 is specified.
Example 31. Using the wxBoxSizer
AboutDialog:: AboutDialog(wxWindow *parent)
: wxDialog(parent, -1, "About Simple Text Editor", wxDefaultPosition,
- 34 -
wxWindows – Programming cross-platform GUI applications in C++ - 35 -
// The sizers can't change their vertical size. They can only grow horizontally.
dialogSizer->Add(textSizer, 0, wxGROW);
dialogSizer->Add(buttonSizer, 0, wxGROW);
SetSizer(dialogSizer);
SetAutoLayout(TRUE);
Layout();
}
! wxGridSizer
A grid sizer is a sizer which layouts the controls in a two-dimensional table that
contains cells of the same size. The width of each cell is the width of the widest
control and the height of each cell is the height of the tallest control. When you create
a grid sizer you have to specify how many rows you want and how many columns. If
one of these are zero the value is calculated by the grid sizer. You can also specify
how much space there must be between columns and rows.
In Example 32 a grid sizer is created with two rows and one column. The space
between columns and rows is 10.
SetSizer(dialogSizer);
SetAutoLayout(TRUE);
Layout();
}
- 35 -
wxWindows – Programming cross-platform GUI applications in C++ - 36 -
! wxFlexGridSizer
A flex grid sizer is a sizer which layouts the controls in a two-dimensional table with
all cells in one row with the same width and all cells in one column with the same
height.
A grid sizer is very useful for dialogs where you need to attach labels to controls.
Figure 4 shows an example of the use of wxFlexGridSizer. The width of the first
column, containing the labels, is the maximum width of one of the labels. The code
for creating such a dialog is shown in Example 33. You can see that 2 rows and 2
columns are created. When adding controls to the sizer, they are placed from left to
right and from top to bottom.
Figure 4. An example of wxFlexGrid
SetSizer(dialogSizer);
SetAutoLayout(TRUE);
Layout();
! wxStaticBoxSizer
wxStaticBoxSizer is a sizer derived from wxBoxSizer. It adds a static box around the
sizer.
! wxNotebookSizer
This sizer is a specialized sizer to make sizers work on wxNotebook controls.
- 36 -
wxWindows – Programming cross-platform GUI applications in C++ - 37 -
Sizers can be nested. You can use a box sizer together with a grid sizer. Example 34
shows you how a wxBoxsizer is combined with a wxFlexGridSizer.
dialogSizer->Add(controlSizer);
dialogSizer->Add(20, 20);
dialogSizer->Add(buttonSizer, 0, wxALIGN_CENTRE);
SetSizer(dialogSizer);
SetAutoLayout(TRUE);
Layout();
6.3 wxPanel
A panel is a window that can contain controls. Its main purpose is to be similar as a
dialog, with the exception that it can have any window as a parent. This way you can
create a frame that contains several controls.
- 37 -
wxWindows – Programming cross-platform GUI applications in C++ - 38 -
6.3.1 Methods
6.3.3 Example
! The resource file format is a recent addition and subject to change. In later versions,
the format will be replaced by XML.
! Not all controls are available.
- 38 -
wxWindows – Programming cross-platform GUI applications in C++ - 39 -
7 Standard Controls
In the previous chapters, you already saw some standard controls. This chapter will show
you how to use the standard controls and what you can do with them. A standard control
always needs a parent window: a wxFrame, wxPanel or wxDialog.
A standard control should be created on the heap (using new) and added as a child to
another window. The parent window will delete your control. So, don’t delete it yourself,
because this will result in access violations errors.
When using an identifier for a window you have to be sure that you use a valid number.
Don’t use zero because this can cause segmentation faults. The easiest way is to use an
enumeration with the first element starting at 1000. When you don’t need an identifier
use -1.
Validators are not discussed in this chapter. Read chapter 8 to know how to use them.
7.1 wxButton
By clicking on a button, the user initiates a command.
7.1.1 Methods
wxString GetLabel() const
Returns the string label of the button.
wxSize GetDefaultSize()
Returns the default size for a button.
void SetDefault()
This sets the button as the default button for the panel or dialog.
- 39 -
wxWindows – Programming cross-platform GUI applications in C++ - 40 -
7.1.3 Example
The following example shows a simple dialog with a centered button. When you click the
button, a message box pops up with the message “You clicked my button”.
Example 35. ButtonDlg.h - The definition of the wxButton example.
#ifndef _ButtonDlg_H
#define _ButtonDlg_H
protected:
private:
DECLARE_EVENT_TABLE()
// ID's
enum
{
BUTTON_SELECT = 1000
};
};
#endif
#include "ButtonDlg.h"
BEGIN_EVENT_TABLE(ButtonDlg, wxDialog)
- 40 -
wxWindows – Programming cross-platform GUI applications in C++ - 41 -
EVT_BUTTON(BUTTON_SELECT, ButtonDlg::OnButtonSelect)
END_EVENT_TABLE()
7.2 wxBitmapButton
A wxBitmapButton is a button that contains a bitmap. You can use it on a dialog, panel or
almost any window.
The constructor:
7.2.1 Methods
wxBitmap& GetBitmapDisabled() const;
Returns the bitmap for the disabled button.
- 41 -
wxWindows – Programming cross-platform GUI applications in C++ - 42 -
7.2.3 Example
The example will show you how to create a wxBitmapButton. When you want more
details on how to use bitmaps, you should read chapter 18.
protected:
private:
// ID's
enum
{
ID_BUTTON_SELECT = 1000
};
wxBitmapButton *m_pButton;
};
#endif
#include "ButtonDlg.h"
- 42 -
wxWindows – Programming cross-platform GUI applications in C++ - 43 -
BEGIN_EVENT_TABLE(ButtonDlg, wxDialog)
EVT_BUTTON(ID_BUTTON_SELECT, ButtonDlg::OnButtonSelect)
EVT_CLOSE(ButtonDlg::OnClose)
END_EVENT_TABLE()
In this example, you have to add the bitmap definition in the resource file. Example 39
shows you how to do that.
#include "wx/msw/wx.rc"
7.3 wxCalendarCtrl
The calendar control allows the user to select a date. You can customize the display of
the control in several ways: colors and fonts can be globally changed and each day can
have another display style. Read chapter 20 Date & Time on page101 when you need
more information about handling dates in wxWindows.
You have to explicitly include “wx/calctrl.h” before you can use the calendar control.
! parent is the parent window of the calendar control. This can’t be NULL!
! id is the unique identifier for this control. You can use –1 when you don’t need one.
! date is the default date.
! pos is the position of the control.
! size is the size of the control.
! style is the style of the control.
The display of each day can be changed using the wxCalendarDateAttr class.
7.3.1 Methods
void EnableHolidayDisplay(bool display = TRUE)
When enabled the special highlighting of holidays is used. Use this instead of changing
the wxCAL_SHOW_HOLIDAYS style bit. The style can only be set on creation.
- 43 -
wxWindows – Programming cross-platform GUI applications in C++ - 44 -
7.3.2 wxCalendarDateAttr
wxCalendarDateAttr is used for setting attributes for a specific day.
Constructors:
wxCalendarDateAttr()
- 44 -
wxWindows – Programming cross-platform GUI applications in C++ - 45 -
wxCAL_BORDER_NONE No border.
wxCAL_BORDER_SQUARE A square border.
wxCAL_BORDER_ROUND A round border.
Methods:
- 45 -
wxWindows – Programming cross-platform GUI applications in C++ - 46 -
7.3.4 Example
The example shows a dialog with a calendar control. When you double click or press the
enter key on a day, the day is marked with a red background color.
Example 40. CalendarDlg.h - The definition of the Calendar example.
#ifndef _CalendarDlg_H
#define _CalendarDlg_H
#include <wx/calctrl.h>
protected:
void OnClose(wxCloseEvent &event);
void OnCalendar(wxCalendarEvent &event);
DECLARE_EVENT_TABLE()
private:
enum
{
ID_CALENDAR = 1000
};
wxCalendarCtrl *m_pCalendar;
};
#endif // _CalendarDlg_H
#include "CalendarDlg.h"
- 46 -
wxWindows – Programming cross-platform GUI applications in C++ - 47 -
BEGIN_EVENT_TABLE(CalendarDlg, wxDialog)
EVT_CALENDAR(ID_CALENDAR, CalendarDlg::OnCalendar)
EVT_CLOSE(CalendarDlg::OnClose)
END_EVENT_TABLE()
7.4 wxCheckBox
A checkbox is a labeled box which can be checked or unchecked.
The constructor:
7.4.1 Methods
bool GetValue() const
Returns true when the checkbox is checked, false otherwise.
- 47 -
wxWindows – Programming cross-platform GUI applications in C++ - 48 -
EVT_CHECKBOX(id, func)
7.4.3 Example
Example 42 and Example 43 shows you how to create a checkbox and how to use the
EVT_CHECKBOX handler. With the IsChecked method, you can see whether the checkbox
is checked or not. You can also use GetValue of wxCheckBox for this.
Example 42. CheckBoxDlg.h - The definition of the Checkbox example.
#ifndef _CheckBoxDlg_H
#define _CheckBoxDlg_H
protected:
void OnCheck(wxCommandEvent &event);
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
enum
{
ID_CHECKBOX = 1000
};
wxCheckBox *m_pCheckBox;
};
#endif // _CheckBoxDlg_H
#include "CheckBoxDlg.h"
- 48 -
wxWindows – Programming cross-platform GUI applications in C++ - 49 -
BEGIN_EVENT_TABLE(CheckBoxDlg, wxDialog)
EVT_CHECKBOX(ID_CHECKBOX, CheckBoxDlg::OnCheck)
EVT_CLOSE(CheckBoxDlg::OnClose)
END_EVENT_TABLE()
7.5 wxCheckListBox
wxCheckListBox is like a listbox, except the items can be checked or unchecked. This
control is only available on the GTK and Windows port. When you want to use it on a
Windows platform, wxWindows should be compiled with the USE_OWNER_DRAWN set to
1. When you didn’t change any definitions, this should be ok.
The header file for wxCheckListBox is not automatically included with wx.h. You have to
include “wx/checklst.h” yourself.
wxCheckListBox is derived from wxListBox. See 7.9 for more information on using
wxListBox.
7.5.1 Methods
void Check(int item, bool check = true)
Use this method to check or uncheck an item.
EVT_CHECKLISTBOX(id, func)
The argument for the handler function is a wxCommandEvent. You can use GetSelection
to retrieve which item is checked or unchecked.
- 49 -
wxWindows – Programming cross-platform GUI applications in C++ - 50 -
7.5.3 Example
The following example shows a checklistbox that contains three items. When an item is
checked or unchecked a message shows which item is selected and whether it is checked
or unchecked.
Example 44. CheckListBoxDlg.h - The definition of a checklistbox example.
#ifndef _CheckListBoxDlg_H
#define _CheckListBoxDlg_H
protected:
void OnCheck(wxCommandEvent &event);
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
enum
{
ID_CHECKLISTBOX = 1000
};
wxCheckListBox *m_pCheckListBox;
};
#endif // _CheckListBoxDlg_H
#include "CheckListBoxDlg.h"
BEGIN_EVENT_TABLE(CheckListBoxDlg, wxDialog)
EVT_CHECKLISTBOX(ID_CHECKLISTBOX, CheckListBoxDlg::OnCheck)
EVT_CLOSE(CheckListBoxDlg::OnClose)
END_EVENT_TABLE()
- 50 -
wxWindows – Programming cross-platform GUI applications in C++ - 51 -
To see if the item is checked or not, you have to use the IsChecked method from
wxCheckListBox. The IsChecked method from wxCommandEvent can only be used for
checkboxes and menus.
7.6 wxChoice
wxChoice is used to select one of a list of strings. The user sees the list when he clicks on
the control. The index of the list is zero-based.
wxChoice(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
int n, const wxString choices[], long style = 0,
const wxValidator& validator = wxDefaultValidator,
const wxString& name = "choice")
7.6.1 Methods
void Append(const wxString& item)
void Append(const wxString& item, void *clientData)
Item is appended to the list. clientData can be used to associate other data with the
item. This can be useful to associate an item with an index in an array.
void Clear()
The list is cleared. All items are removed.
void Delete(int n)
Deletes the item from the list. The index of the list is zero-based.
- 51 -
wxWindows – Programming cross-platform GUI applications in C++ - 52 -
void SetSelection(int n)
Sets the text field with the string at the given position. This does not generate an
EVT_CHOICE event.
EVT_CHOICE(id, func)
The handler function will be called when an item is selected. The argument of the handler
is a wxCommandEvent.
7.6.3 Example
The example shows a dialog with a wxChoice control. When the user selects an item, the
item will be shown immediately in the text field. This is done with the SetSelection
method. When you don’t do this the selected item will only be shown when the user
clicks on the arrow or when the control looses the focus.
Example 46. ChoiceDlg.h - The definition of the wxChoice example.
#ifndef _ChoiceDlg_H
#define _ChoiceDlg_H
protected:
void OnClose(wxCloseEvent &event);
void OnChoice(wxCommandEvent &event);
DECLARE_EVENT_TABLE()
private:
enum
{
ID_CHOICE = 1000
};
wxChoice *m_pChoice;
};
#endif // _ChoiceDlg_H
#include "ChoiceDlg.h"
- 52 -
wxWindows – Programming cross-platform GUI applications in C++ - 53 -
m_pChoice->Append("Automatic gear");
BEGIN_EVENT_TABLE(ChoiceDlg, wxDialog)
EVT_CHOICE(ID_CHOICE, ChoiceDlg::OnChoice)
EVT_CLOSE(ChoiceDlg::OnClose)
END_EVENT_TABLE()
7.7 wxComboBox
A combobox is a combination of an edit control and a listbox. The user can select a string
from a list or can enter a value when the text field is not read-only. The control can be
displayed as a drop-down list with or without a text field. The index of the list is zero-
based.
7.7.1 Methods
wxComboBox is derived from wxChoice. Therefore, all public methods of wxChoice are
also available for wxComboBox.
- 53 -
wxWindows – Programming cross-platform GUI applications in C++ - 54 -
void Copy()
Copies the selected text to the clipboard.
void Cut()
Copies the selected text to the clipboard and removes the selection.
void SetInsertionPointEnd();
Sets the insertion point of the text field at the end.
EVT_COMBOBOX(id, func)
EVT_TEXT(id, func)
7.7.3 Example
The example will show a combobox where the user can select an item from the list, or
can enter a new value.
Example 48. ComboboxDlg.h - The definition of the wxComboBox example.
#ifndef _ComboboxDlg_H
#define _ComboboxDlg_H
protected:
void OnClose(wxCloseEvent &event);
- 54 -
wxWindows – Programming cross-platform GUI applications in C++ - 55 -
DECLARE_EVENT_TABLE()
private:
enum
{
ID_COMBOBOX = 1000
};
wxComboBox *m_pCombobox;
};
#endif // _ComboboxDlg_H
#include "ComboboxDlg.h"
BEGIN_EVENT_TABLE(ComboboxDlg, wxDialog)
EVT_COMBOBOX(ID_COMBOBOX, ComboboxDlg::OnCombobox)
EVT_CLOSE(ComboboxDlg::OnClose)
END_EVENT_TABLE()
7.8 wxGauge
A gauge is a horizontal or vertical bar that shows a quantity. You can use a gauge to
show the user the progress of a lengthy process. In the MSW distribution wxGauge is
defined as a macro. When __WIN95__ is defined, the actual class that implements the
gauge is called wxGauge95. When __WIN95__ is not defined, wxGaugeMSW is used. The
difference is that wxGauge95 uses the gauge control of the common controls library from
Microsoft. Don’t use these classes directly and use wxGauge instead. Otherwise, you
break the portability of your code.
wxGauge(wxWindow *parent, wxWindowID id, int range, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, long style = wxGA_HORIZONTAL,
const wxValidator& validator = wxDefaultValidator, const wxString& name = “gauge”)
- 55 -
wxWindows – Programming cross-platform GUI applications in C++ - 56 -
! id is the unique identifier of the gauge. Use –1 when you don’t need it.
! range is the maximum value of the gauge.
! pos is the position of the gauge.
! size is the size of the gauge.
! style is the window style of the gauge.
7.8.1 Methods
int GetBezelFace(void) const
Returns the width of the 3D bezel face. This method can only be used when __WIN95__
is not defined. It returns 0 when __WIN95__ is defined.
void SetBezelFace(int w)
Sets the width of the 3D bezel face. This method can only be used when __WIN95__ is
not defined. It doesn’t do anything when __WIN95__ is defined.
void SetRange(int r)
Sets a new maximum range of the gauge.
void SetShadowWidth(int w)
Sets the width of the 3D shadow margin width. This method can only be used when
__WIN95__ is not defined. It doesn’t do anything when __WIN95__ is defined.
7.8.3 Example
The example shows a gauge with a maximum range of 100. To show the progress in the
gauge a timer is used. After each 100 milliseconds, the value of the gauge will be added
by one.
Example 50. GaugeDlg.h - The definition of the gauge example.
#ifndef _GaugeDlg_H
#define _GaugeDlg_H
- 56 -
wxWindows – Programming cross-platform GUI applications in C++ - 57 -
GaugeDlg();
protected:
void OnTimer(wxTimerEvent &event);
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
wxGauge *m_pGauge;
wxTimer *m_pTimer;
enum
{
ID_TIMER = 1000
};
};
#endif // _GaugeDlg_H
BEGIN_EVENT_TABLE(GaugeDlg, wxDialog)
EVT_TIMER(ID_TIMER, GaugeDlg::OnTimer)
EVT_CLOSE(GaugeDlg::OnClose)
END_EVENT_TABLE()
7.9 wxListBox
A listbox is used to show the user a list where he can select one or more items. The
index of an item is zero-based. The constructor looks like this:
- 57 -
wxWindows – Programming cross-platform GUI applications in C++ - 58 -
7.9.1 Methods
void Clear()
Removes all the items from the list.
void Delete(int n)
Deletes the item at the given position.
void Deselect(int n)
Deselectes the item at the given position.
- 58 -
wxWindows – Programming cross-platform GUI applications in C++ - 59 -
void SetFirstItem(int n)
void SetFirstItem(const wxString& s)
The item at the given position or with the given string will be the first visible item in the
list. (Windows only)
EVT_LISTBOX(id, func)
EVT_LISTBOX_DCLICK(id, func)
7.9.3 Example
The example shows a listbox and will show a message box when the user double clicks
on the listbox.
Example 52. ListboxDlg.h - The definition of the wxListBox example.
#ifndef _ListboxDlg_H
#define _ListboxDlg_H
protected:
void OnClose(wxCloseEvent &event);
void OnListboxDClick(wxCommandEvent &event);
DECLARE_EVENT_TABLE()
private:
- 59 -
wxWindows – Programming cross-platform GUI applications in C++ - 60 -
enum
{
ID_LISTBOX = 1000
};
wxListBox *m_pListbox;
};
#endif // _ListboxDlg_H
#include "ListboxDlg.h"
BEGIN_EVENT_TABLE(ListboxDlg, wxDialog)
EVT_LISTBOX_DCLICK(ID_LISTBOX, ListboxDlg::OnListboxDClick)
EVT_CLOSE(ListboxDlg::OnClose)
END_EVENT_TABLE()
In the OnListboxDClick function, you see that the content of the selected item is retrieved
using the GetStringSelection method of the wxListBox class. The GetString method of
wxCommandEvent doesn’t work here.
7.10 wxRadioBox
A radiobox is a control that shows a list of mutually exclusive choices. The radio buttons
can be displayed in a vertical or horizontal column.
The constructor:
- 60 -
wxWindows – Programming cross-platform GUI applications in C++ - 61 -
7.10.1 Methods
bool Enable(bool enable)
void Enable(int item, bool enable)
All items or the given item are enabled or disabled.
void SetSelection(int N)
The item at the given index is selected. An EVT_COMMAND_RADIOBOX_SELECTED event
is not fired.
- 61 -
wxWindows – Programming cross-platform GUI applications in C++ - 62 -
EVT_RADIOBOX(id, func)
7.10.3 Example
The example shows a dialog that contains a radiobox with three items. The items are
placed in one column. When the user selects an item, a message box is shown with the
name of the selected item.
Example 54. RadioboxDlg.h - The definition of the wxRadioBox example.
#ifndef _RadioboxDlg_H
#define _RadioboxDlg_H
protected:
void OnClose(wxCloseEvent &event);
void OnRadiobox(wxCommandEvent &event);
DECLARE_EVENT_TABLE()
private:
enum
{
ID_RADIOBOX = 1000
};
wxRadioBox *m_pRadiobox;
};
#endif // _RadioboxDlg_H
In Example 55 you see that wxRA_SPECIFY_COLS is used to place the items in a column.
Because all the items must be placed in one column, the maximum dimension parameter
is set to 1.
#include "RadioboxDlg.h"
- 62 -
wxWindows – Programming cross-platform GUI applications in C++ - 63 -
BEGIN_EVENT_TABLE(RadioboxDlg, wxDialog)
EVT_RADIOBOX(ID_RADIOBOX, RadioboxDlg::OnRadiobox)
EVT_CLOSE(RadioboxDlg::OnClose)
END_EVENT_TABLE()
7.11 wxRadioButton
A radio button is a button that is used to show a mutually exclusive selection.
The constructor:
! parent is the parent window of the radio button. This can’t be NULL!
! id is the unique identifier for this window. Use –1, when you don’t need it.
! label is the text displayed with the radio button.
! pos is the position of the radio button.
! size is the size of the radio button.
! style is the window style of the radio button. wxRadioButton defines one additional
style.
7.11.1 Methods
bool GetValue(void) const
When the radio button is selected true is returned. Otherwise false is returned.
EVT_RADIOBOX(id, func)
- 63 -
wxWindows – Programming cross-platform GUI applications in C++ - 64 -
show a message box for example, the button will not be refreshed correctly. This bug will
be solved in version 2.3.3.
7.11.3 Example
The example will try to implement the same functionality as in wxRadioBox. You’ll see
that the use of wxRadioBox is much easier.
Example 56. RadioButtonDlg.h - The definition of the wxRadioButton example.
#ifndef _RadiobuttonDlg_H
#define _RadiobuttonDlg_H
protected:
void OnClose(wxCloseEvent &event);
void OnRadioButton(wxCommandEvent &event);
DECLARE_EVENT_TABLE()
private:
enum
{
ID_RADIOBUTTON_1 = 1000,
ID_RADIOBUTTON_2,
ID_RADIOBUTTON_3
};
wxRadioButton *m_pRadiobutton1;
wxRadioButton *m_pRadiobutton2;
wxRadioButton *m_pRadiobutton3;
};
#endif // _RadiobuttonDlg_H
In the constructor of the dialog, you’ll see that the first radio button has the
wxRB_GROUP style. This style indicates the start of a new group of radio buttons.
- 64 -
wxWindows – Programming cross-platform GUI applications in C++ - 65 -
#include "RadiobuttonDlg.h"
BEGIN_EVENT_TABLE(RadiobuttonDlg, wxDialog)
EVT_RADIOBUTTON(ID_RADIOBUTTON_1, RadiobuttonDlg::OnRadioButton)
EVT_RADIOBUTTON(ID_RADIOBUTTON_2, RadiobuttonDlg::OnRadioButton)
EVT_RADIOBUTTON(ID_RADIOBUTTON_3, RadiobuttonDlg::OnRadioButton)
EVT_CLOSE(RadiobuttonDlg::OnClose)
END_EVENT_TABLE()
7.12 wxSlider
A slider is a control with a handle that the user can slide to change its value. Before
Win95, a scrollbar is used to simulate a slider. In Win95 the track bar control is used.
The correct implementation is chosen by wxWindows depending on the definition of
__WIN95__. wxSlider is translated into wxSlider95 when __WIN95__ is defined,
wxSliderMSW is used when it is not defined. You should always use wxSlider, instead of
the concrete classes. Otherwise, you break the portability of your code.
The constructor:
- 65 -
wxWindows – Programming cross-platform GUI applications in C++ - 66 -
wxSlider(wxWindow *parent, wxWindowID id, int value, int minValue, int maxValue,
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxSL_HORIZONTAL, const wxValidator& validator = wxDefaultValidator,
const wxString& name = wxSliderNameStr)
! parent is the parent window of the slider control. This can’t be NULL!
! id is the unique identifier for the slider control. Use –1 when you don’t need it.
! value is the initial value of the slider control.
! minValue is the minimum value of the slider control.
! maxValue is the maximum value of the slider control.
! pos is the position of the slider control.
! size is the size of the slider control.
! style is the style of the slider control. wxSlider provides the following additional
styles:
7.12.1 Methods
void ClearSel() __WIN95__ Only
Clears a selection. This is only useful when wxSL_SELRANGE is used.
- 66 -
wxWindows – Programming cross-platform GUI applications in C++ - 67 -
void SetValue(int)
Sets a new value.
7.12.3 Example
The example shows a dialog with a slider that shows its ticks, minimum value, maximum
value and the current value. Note that you have to set the line and page size, otherwise
clicking on the slider won’t work.
Example 58. SliderDlg.h - The definition of the wxSlider example.
#ifndef _SliderDlg_H
#define _SliderDlg_H
protected:
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
};
- 67 -
wxWindows – Programming cross-platform GUI applications in C++ - 68 -
#endif
#include "SliderDlg.h"
slider->SetLineSize(1);
slider->SetPageSize(2);
BEGIN_EVENT_TABLE(SliderDlg, wxDialog)
EVT_CLOSE(SliderDlg::OnClose)
END_EVENT_TABLE()
7.13 wxSpinCtrl
wxSpinCtrl combines a text control with a spin button. wxWindows also provides a
wxSpinButton, but this is only implemented on Windows and GTK platforms. Therefore,
portable programs should use wxSpinCtrl.
wxSpinCtrl is not automatically included when you use <wx.h>. You have to include
<wx/spinctrl.h> yourself.
- 68 -
wxWindows – Programming cross-platform GUI applications in C++ - 69 -
7.13.1 Methods
int GetMax() const;
Returns the maximum value.
7.13.3 Example
The example shows a spin control in the middle of a dialog. You can select values from 0
to 10. When the maximum value is reached, the value will be reset to the beginning of
the range.
Example 60. SpinDlg.h - The definition of the wxSpinCtrl example.
#ifndef _SpinDlg_H
#define _SpinDlg_H
protected:
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
enum
{
ID_SPIN = 1000
};
};
#include "SpinDlg.h"
- 69 -
wxWindows – Programming cross-platform GUI applications in C++ - 70 -
SetAutoLayout(TRUE);
Layout();
}
BEGIN_EVENT_TABLE(SpinDlg, wxDialog)
EVT_CLOSE(SpinDlg::OnClose)
END_EVENT_TABLE()
7.14 wxStaticBitmap
wxStaticBitmap displays a bitmap.
7.14.1 Methods
const wxBitmap& GetBitmap() const;
Returns the bitmap. This method will assert when you’ve used an icon instead of a
bitmap.
7.14.2 Example
The example will show a bitmap in the middle of a dialog.
Example 62. StaticBitmapDlg.h - The definition of the wxStaticBitmap example.
#ifndef _StaticBitmapDlg_H
#define _StaticBitmapDlg_H
protected:
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
};
#endif
- 70 -
wxWindows – Programming cross-platform GUI applications in C++ - 71 -
BEGIN_EVENT_TABLE(StaticBitmapDlg, wxDialog)
EVT_CLOSE(StaticBitmapDlg::OnClose)
END_EVENT_TABLE()
7.15 wxStaticBox
A static box is a rectangle drawn around other controls to denote a logical grouping of
items.
What’s the easiest way to put controls in the static box? Moreover, how can you make
sure that the size of the static box is big enough to show all the controls? The solution is
wxStaticBoxSizer. It works like a box sizer and draws a static box around its current size.
Read chapter 6.2.2 when you don’t know how use sizers.
7.15.1 Example
The example creates two controls. wxStaticBoxSizer is used two make sure that the
controls are laid out fine: the first control encloses the second one.
- 71 -
wxWindows – Programming cross-platform GUI applications in C++ - 72 -
protected:
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
};
#endif
BEGIN_EVENT_TABLE(StaticBoxDlg, wxDialog)
EVT_CLOSE(StaticBoxDlg::OnClose)
END_EVENT_TABLE()
7.16 wxStaticLine
wxStaticLine can be used to draw a vertical or horizontal line to separate groups of
controls.
wxStaticLine is not automatically included when you use <wx.h>. You have to include
<wx/statline.h> yourself.
! parent is the parent window of the static line. This can’t be NULL!
! id is the unique identifier for the line. Use –1 when you don’t need it.
! pos is the position of the line.
! size is the size of the line.
! style is the style of the line. wxStaticLine has two additional styles:
7.16.1 Methods
bool isVertical() const
Returns true when the line is vertical.
7.16.2 Example
The example draws a static line in the center of the dialog.
- 72 -
wxWindows – Programming cross-platform GUI applications in C++ - 73 -
protected:
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
};
#endif
BEGIN_EVENT_TABLE(StaticLineDlg, wxDialog)
EVT_CLOSE(StaticLineDlg::OnClose)
END_EVENT_TABLE()
7.17 wxStaticText
wxStaticText allows you to show one or more lines of read-only text.
- 73 -
wxWindows – Programming cross-platform GUI applications in C++ - 74 -
7.17.1 Methods
wxString GetLabel() const
Returns the text.
7.17.2 Example
The example will show a dialog that contains a multiline text.
protected:
void OnClose(wxCloseEvent &event);
DECLARE_EVENT_TABLE()
private:
};
#endif
BEGIN_EVENT_TABLE(StaticTextDlg, wxDialog)
EVT_CLOSE(StaticTextDlg::OnClose)
END_EVENT_TABLE()
7.18 wxTextCtrl
A wxTextCtrl gives the user the ability to enter some text. The text can be on a single
line or multi-line.
- 74 -
wxWindows – Programming cross-platform GUI applications in C++ - 75 -
7.18.1 Methods
void AppendText(const wxString& text);
Appends the text.
void Clear();
Removes the text.
void Copy();
Copies the selected text to the clipboard.
void Cut();
Copies the selected text to the clipboard and removes it from the control.
void DiscardEdits();
Clears the modified flag.
- 75 -
wxWindows – Programming cross-platform GUI applications in C++ - 76 -
void Paste();
Copies the content of the clipboard to the selection of the text control.
void Redo();
When the last operation can be redone, it redoes the last operation.
void SetInsertionPointEnd();
Sets the insertion point at the end of the text.
- 76 -
wxWindows – Programming cross-platform GUI applications in C++ - 77 -
void Undo();
Tries to undo the last change.
The << operator can also be used to set the value of the text control.
7.18.2 Events
wxTextCtrl has two specific events:
7.18.3 Example
The example shows a dialog that contains a multi-line text control that fills the total area
of the dialog.
protected:
- 77 -
wxWindows – Programming cross-platform GUI applications in C++ - 78 -
};
#endif
BEGIN_EVENT_TABLE(TextDlg, wxDialog)
EVT_CLOSE(TextDlg::OnClose)
END_EVENT_TABLE()
- 78 -
wxWindows – Programming cross-platform GUI applications in C++ - 79 -
8 Validators
A validator is an object that mediates between data and a control (mediator pattern),
transferring the data in either direction and validating it. A validator is also able to
intercept events generated by the control, providing a filtering behavior without the need
to create a new control class.
You can use wxTextValidator and wxGenericValidator, or you can write your own.
When you’re using a panel or a window, you need to call InitDialog yourself before
showing the window.
When the user clicks a button, the wxWindow::Validate method should be called. When
this return FALSE, the button handler should return immediately. When it returns TRUE,
the TransferDataFromWindow should be called.
wxDialog contains a default command event handler for the wxID_OK button. So when
you’re using validators and a normal OK button, you don’t need to write any code for
validating the dialog.
8.2 wxTextValidator
wxTextValidator validates wxTextCtrl objects. It provides also a filtering mechanism to
prevent that the user enters invalid characters. The constructor looks like this:
Example 73 is a text control that allows only numeric characters. When the control is
validated, the text is stored in the textValue variable which type is a wxString.
Example 73. A Numeric Text Control with a wxTextValidator
wxTextCtrl *text = new wxTextCtrl(this, -1, “”, wxDefaultPostion, wxDefaultSize, 0,
wxTextValidator(wxFILTER_NUMERIC, &textValue));
8.3 wxGenericValidator
wxGenericValidator performs data transfer (no validation or filtering) for some basic
controls.
- 79 -
wxWindows – Programming cross-platform GUI applications in C++ - 80 -
! A constructor is responsible for setting the kind of validation and to set a pointer to a
C++ variable that is used to store the data of the control.
! A Validate method that returns TRUE when the data of the control is valid.
! A TransferToWindow method that transfers the data of the C++ variable to the
control.
! A TransferFromWindow method that transfers the data of the control to the C++
variable.
! A Copy constructor and a Clone method is needed because validators are passed by
reference to window constructors, and must therefore be cloned internally.
Optionally you can provide event handling. These events will be captured before the
control does. The following example implements a validator that checks that the value
entered in a text control is in a valid range.
Example 74. RangeValidator.h - A validator that checks that the value of a wxTextctrl is numeric and in a valid
range.
#ifndef _RANGE_VALIDATOR_H
#define _RANGE_VALIDATOR_H
/**
* RangeValidator. Checks if an entered value is in a given range.
*/
/**
* Copy constructor
*/
RangeValidator(const RangeValidator &toCopy);
/**
* Returns a copy of this validator
*/
virtual wxObject* Clone() const;
/**
* Validate. Returns true when the entered value is correct, otherwise false
*/
bool Validate(wxWindow *parent);
/**
* Transfer the data to the window. Returns false when there's a problem.
*/
bool TransferToWindow();
- 80 -
wxWindows – Programming cross-platform GUI applications in C++ - 81 -
/**
* Transfer the data from the window. Returns false when there's a problem.
*/
bool TransferFromWindow();
protected:
/**
* Copies the given RangeValidator to this validator
*/
bool Copy(const RangeValidator& val);
private:
long m_min;
long m_max;
wxString *m_value;
};
#endif // _RANGE_VALIDATOR_H
Of course, you could extend from wxTextValidator, but this example is to show you how
to create your own validator.
Example 75. RangeValidator.cpp – The implementation of the RangeValidator.
// For compilers that supports precompilation , includes "wx/wx.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "RangeValidator.h"
m_min = val.m_min;
m_max = val.m_max;
m_value = val.m_value;
return true;
}
wxString message;
bool result = false;
long value;
if ( ! currentValue.ToLong(&value) )
{
message.Printf("%s is not a valid number", currentValue.c_str());
}
else
{
if ( value < m_min
|| value > m_max )
{
- 81 -
wxWindows – Programming cross-platform GUI applications in C++ - 82 -
if ( ! result )
{
wxMessageBox(message);
control->SetFocus();
}
return result;
}
bool RangeValidator::TransferToWindow()
{
wxWindow *win = GetWindow();
if ( ! win )
return false;
if ( ! m_value )
return false;
if ( ! win->IsKindOf(CLASSINFO(wxTextCtrl)) )
return false;
return true;
}
bool RangeValidator::TransferFromWindow()
{
wxWindow *win = GetWindow();
if ( ! win )
return false;
if ( ! m_value )
return false;
if ( ! win->IsKindOf(CLASSINFO(wxTextCtrl)) )
return false;
return true;
}
To use this validator you have to create a text control and a class member that stores
the value of the text control. Example 76 shows you how the RangeValidator is used to
force the user to enter a valid line number. The variable m_lineNumber contains the
value that is shown in the text control. When the user clicks the Ok button, wxWindows
performs the default event handling for this button. This is validating the input and
transferring it to your C++ variable. When you implement the EVT_INIT_DIALOG event,
don’t forget to call TransferDataToWindow, otherwise the controls are not initialized.
Example 76. Using the RangeValidator.
void GotoLineDialog::OnInitDialog(wxInitDialogEvent &event)
{
RangeValidator rangeValidator(&m_lineNumber, 1, m_maxLineNumber);
m_pLineNumberCtrl->SetValidator(rangeValidator);
TransferDataToWindow();
}
- 82 -
wxWindows – Programming cross-platform GUI applications in C++ - 83 -
9 Scrolling
- 83 -
wxWindows – Programming cross-platform GUI applications in C++ - 84 -
10 Splitting windows
Sometimes it can be useful to be able to split a window. The wxSplitterWindow class
helps you doing this. A window can split vertically or horizontally.
- 84 -
wxWindows – Programming cross-platform GUI applications in C++ - 85 -
11 Common controls
11.1 Toolbar
A toolbar is a user interface component that contains bitmap buttons or toggles. A
toolbar gives the user faster access to an application’s facilities than menus.
11.1.1 Events
The toolbar class handles menu commands in the same way that a menubar does.
Therefore, you can use one EVT_MENU macro for both a menu item and a toolbar button.
The event handler functions take a wxCommandEvent argument. For most event macros,
the identifier of the tool is passed, except for EVT_TOOL_ENTER that passes the toolbar
window and the tool id is retrieved from the wxCommandEvent.
Tool commands (and UI update events) are first sent to the focus window within the
frame that contains the toolbar. If no window within the frame has the focus, then the
events are sent directly to the toolbar.
In Windows32 applications, wxTreeCtrl uses the standard common treeview control from
the system library comctl32.dll. Some versions of this library are known to have bugs
with handling the tree control colors. When you encounter these problems, the
recommended solution is to upgrade the comctrl32.dll to a newer version.
- 85 -
wxWindows – Programming cross-platform GUI applications in C++ - 86 -
! parent is the parent of the tree control. This must not be NULL.
! id is the window identifier. –1 indicates a default value.
! pos is the window position.
! size is the window size.
! style is the style of the window. Multiple styles can be specified with the or operator.
wxTR_HAS_BUTTONS
Use this style to show + and – buttons to the left of parent items.(Win32
only)
wxTR_EDIT_LABELS
Use this style when the user is allowed to change the text of the label.
wxTR_MULTIPLE
Use this style when the user is allowed to select more than one item.
! validator is a validator for this window.
! name is the window name.
11.2.1 Items
Each item has a unique id. The type of an id depends on the platform. That’s why
wxWindows wraps the id in the wxTreeItemld class. For example under Windows32, this
class wraps around the HTREEITEM handle. This way, wxWindows makes sure that your
code is portable.
Before you can add items to the tree, you need to add a root item. The AddRoot method
is used for this. AddRoot returns the id of the item. Later you can use this id to add
children to the root with the AppendItem method. When you want to insert an item at
the same level, you use the InsertItem method. Inserting an item as the first child of his
parent can be done with the PrependItem method.
To associate data with your items you can use the wxTreeItemData class. Your data class
should derive from wxTreeItemData. The association is set with the SetItemData
method. Because the tree itself controls the pointers to the wxTreeItemData instances,
you must create the data classes on the heap and you are not allowed to delete them.
Once a data class is set, the tree will delete it when the tree is destroyed. If you do
delete a data class, make sure that you’ve cleared the association with the SetItemData
(with NULL as the second argument) method to prevent that the tree deletes the pointer
for the second time.
Enumerating the children of items is done with the GetFirstChild and GetNextChild
methods. For these enumerating methods, you pass a ‘cookie’ parameter, which is
necessary to make these functions reentrant. The cookie (type long) passed to these
methods must be the same for each enumeration.
Enumerating the sibling item of a given item is done with the GetNextSibling and
GetPrevSibling methods.
Enumerating the visible items is done with the GetFirstVisibleItem, GetNextVisible and
GetPrevVisible methods.
All these enumerating methods return an invalid id when an item is not found. Use the
IsOk method of wxTreeItemId to check this.
- 86 -
wxWindows – Programming cross-platform GUI applications in C++ - 87 -
! EVT_TREE_BEGIN_DRAG(id, func)
Begin dragging with the left mouse button. Call the wxNotifyEvent Allow method to
allow dragging.
! EVT_TREE_BEGIN_RDRAG(id, func)
Begin dragging with the right mouse button. Call the wxNotifyEvent Allow method to
allow dragging.
! EVT_TREE_END_DRAG(id, func)
Drag ended (drop).
! EVT_TREE_BEGIN_LABEL_EDIT(id, func)
Begin editing a label. Call the wxNotifyEvent Veto method to disallow editing.
! EVT_TREE_END_LABEL_EDIT(id, func)
Finished editing a label. Call the wxNotifyEvent Veto method to disallow the change.
! EVT_TREE_DELETE_ITEM(id, func)
Delete an item.
! EVT_TREE_GET_INFO(id, func)
Request information from the application.
! EVT_TREE_SET_INFO(id, func)
Information is supplied.
! EVT_TREE_ITEM_ACTIVATED(id, func)
The item is activated.
! EVT_TREE_ITEM_COLLAPSED(id, func)
The item is collapsed.
! EVT_TREE_ITEM_COLLAPSING(id, func)
The item is about to be collapsed. Prevent this by calling the wxNotifyEvent Veto
method.
! EVT_TREE_ITEM_EXPANDED(id, func)
The item is expanded.
! EVT_TREE_ITEM_EXPANDING(id, func)
The item is about to be expanded. Prevent this by calling the wxNotifyEvent Veto
method.
! EVT_TREE_SEL_CHANGED(id, func)
The selection has changed.
! EVT_TREE_SEL_CHANGING(id, func)
The selection is about to be changed. Prevent this by calling the wxNotifyEvent Veto
method.
- 87 -
wxWindows – Programming cross-platform GUI applications in C++ - 88 -
! EVT_TREE_KEY_DOWN(id, func)
A key is pressed.
11.3.1 Methods
11.3.2 wxListItem
An item is inserted with the InsertItem method that returns the index of the inserted
item when it succeeds or -1 when it fails. When you want to set several attributes of an
item, you can use the wxListItem class. Associating data with an item is done with the
SetItemData method or you can use the wxListItem class again.
- 88 -
wxWindows – Programming cross-platform GUI applications in C++ - 89 -
When you have a list control in report view, you can set sub-items with the SetColumn or
the SetItem method. SetItem can also be used with the wxListItem class.
wxListItem is used together with wxListCtrl. Use this class to set/get several attributes of
an item in a wxListCtrl at once.
void Clear()
Clears all the members.
void ClearAttributes()
Clears all the attributes (font, color, …)
- 89 -
wxWindows – Programming cross-platform GUI applications in C++ - 90 -
- 90 -
wxWindows – Programming cross-platform GUI applications in C++ - 91 -
! EVT_LIST_BEGIN_DRAG(id, func)
Begin dragging with the left mouse.
! EVT_LIST_BEGIN_RDRAG(id, func)
Begin dragging with the right mouse button.
! EVT_LIST_BEGIN_LABEL_EDIT(id, func)
Begin editing a label. Call the wxNotifyEvent Veto method to disallow editing.
! EVT_LIST_END_LABEL_EDIT(id, func)
Editing a label is finished. Call the wxNotifyEvent Veto method to discard the change.
! EVT_LIST_DELETE_ITEM(id, func)
An item is deleted.
! EVT_LIST_DELETE_ALL_ITEMS(id, func)
All items are deleted.
! EVT_LIST_GET_INFO(id, func)
Request information from the application, usually the item text.
! EVT_LIST_SET_INFO(id, func)
Information is supplied. (not implemented)
! EVT_LIST_ITEM_SELECTED(id, func)
The item is selected.
! EVT_LIST_ITEM_DESELECTED(id, func)
The item is deselected.
! EVT_LIST_ITEM_ACTIVATED(id, func)
11.4 Imagelist
A wxImageList contains a list of images and is used together with wxTreeCtrl,
wxNotebook and wxListCtrl.
11.5 Tab
A Tab control is created with the wxNotebook control. The tabs can be placed on the left,
right, top or bottom side of the control.
- 91 -
wxWindows – Programming cross-platform GUI applications in C++ - 92 -
The default placement of the tabs is at the top of the control. To reduce flickering you
can use the wxCLIP_CHILDREN window style.
11.5.2 Events
To process events from a wxNotebook control you can use the following macros:
! EVT_NOTEBOOK_PAGE_CHANGED(id, func)
The page selection was changed.
! EVT_NOTEBOOK_PAGE_CHANGINGt(id, func)
The page selection is about to be changed. This can be prevented by calling Veto.
11.6 Tooltip
- 92 -
wxWindows – Programming cross-platform GUI applications in C++ - 93 -
12 Property Sheets
- 93 -
wxWindows – Programming cross-platform GUI applications in C++ - 94 -
13 HTML
- 94 -
wxWindows – Programming cross-platform GUI applications in C++ - 95 -
14 Document/View framework
- 95 -
wxWindows – Programming cross-platform GUI applications in C++ - 96 -
15 The clipboard
- 96 -
wxWindows – Programming cross-platform GUI applications in C++ - 97 -
- 97 -
wxWindows – Programming cross-platform GUI applications in C++ - 98 -
17 Printing
- 98 -
wxWindows – Programming cross-platform GUI applications in C++ - 99 -
18 Drawing
- 99 -
wxWindows – Programming cross-platform GUI applications in C++ - 100 -
19 Strings
- 100 -
wxWindows – Programming cross-platform GUI applications in C++ - 101 -
- 101 -
wxWindows – Programming cross-platform GUI applications in C++ - 102 -
21 Container classes
wxWindows provides some container classes such as dynamic arrays and hashtables.
wxWindows doesn’t use the STL container classes for some reasons. First, wxWindows
was written before STL was written. Second, there are still compilers today that cannot
deal well with all of the STL classes. When the support for STL improves, future versions
of wxWindows will use STL.
wxWindows provides three different kinds of arrays. All of them derive from the
wxBaseArray class, which handles the untyped data. wxBaseArray can’t be used directly.
wxWindows has some macros that you can use to generate a new class that derives from
wxBaseArray. Because of portability issues, wxWindows doesn’t use templates.
wxBaseArray provides you dynamic arrays. When you add an element and there’s not
enough memory allocated, wxBaseArray will allocate more memory. In debug mode,
wxBaseArray also performs range checking on the index values.
For simple types, the macro WX_DEFINE_ARRAY can be used. A simple type is a type
which size is smaller then sizeof(long). Example 77 shows you how it works. The macro
generates a class with the name IntArray that can only contain int’s.
For types with a larger size then sizeof(long) or for objects you need to use the
WX_DECLARE_OBJARRAY macro. This macro only declares the array. After you’ve
included the <wx/arrimpl.cpp> file in your implementation file, you need to use
WX_DEFINE_OBJARRAY to define the array.
Example 78. Declaring a dynamic array for an object.
#include <wx/dynarray.h>
WX_DECLARE_OBJARRAY(wxFile, ArrayOfFiles);
Example 78 shows you how to declare an array class for wxFile instances, while Example
79 shows you how to define the array class.
A sorted array is created with the WX_DEFINE_SORTED_ARRAY macro as you can see in
Example 80.
Example 80. A sorted dynamic array.
WX_DEFINE_SORTED_ARRAY(wxFile*, SortedArrayOfFiles);
- 102 -
wxWindows – Programming cross-platform GUI applications in C++ - 103 -
21.1.2 wxHashTable
The wxHashTable provides hash table functionality for wxWindows. wxHashTable is kept
simple: you can only use integers or strings as the key. The hash table is implemented
as an array of pointers to lists. The constructor of wxHashTable looks like this:
! key_type defines the type of the key. wxKEY_INTEGER for int, wxKEY_STRING for
string.
! size is the default size of the hash table. The default contains space for 1000
elements.
You can use the WX_DECLARE_HASH macro to define a type safe hash table. This macro
generates a class for you.
#define wxUSE_GLOBAL_MEMORY_OPERATORS 0
#define wxUSE_DEBUG_NEW_ALWAYS 0
You’ve to do this because wxWindows redefines new for debugging purposes and this
gives trouble with STL.
- 103 -
wxWindows – Programming cross-platform GUI applications in C++ - 104 -
22 File handling
- 104 -
wxWindows – Programming cross-platform GUI applications in C++ - 105 -
23 Multi-lingual applications
- 105 -
wxWindows – Programming cross-platform GUI applications in C++ - 106 -
24 Logging
- 106 -
wxWindows – Programming cross-platform GUI applications in C++ - 107 -
25 Databases
- 107 -
wxWindows – Programming cross-platform GUI applications in C++ - 108 -
26 Multithreading
- 108 -
wxWindows – Programming cross-platform GUI applications in C++ - 109 -
27 Debugging
- 109 -
wxWindows – Programming cross-platform GUI applications in C++ - 110 -
28 Class reference
- 110 -
wxWindows – Programming cross-platform GUI applications in C++ - 111 -
28.1 wxAcceleratorEntry
28.1.1 Overview
An object used by an application, which want to create an accelerator table.
! Derived from
None
! Include files
#include <wx/accel.h>
! See also
wxAcceleratorTable
28.1.2 Example
- 111 -
wxWindows – Programming cross-platform GUI applications in C++ - 112 -
28.2 wxAcceleratorTable
28.2.1 Overview
- 112 -
wxWindows – Programming cross-platform GUI applications in C++ - 113 -
28.3 wxFrame
28.3.1 Overview
- 113 -
wxWindows – Programming cross-platform GUI applications in C++ - 114 -
! See also
- 114 -
wxWindows – Programming cross-platform GUI applications in C++ - 115 -
Event Macros
EVT_ACTIVATE(func) An activate event is sent when a
wxActivateEvent EVT_ACTIVATE_APP(func) window or application is activated or
deactivated.
wxCommandEvent EVT_COMMAND(id, event,
func)
EVT_COMMAND_RANGE(id1,
id2, event, func)
EVT_BUTTON(id, func)
EVT_CHECKBOX(id, func)
EVT_CHOICE(id, func)
EVT_LISTBOX(id, func)
EVT_LISTBOX_DCLICK(id,
func)
EVT_TEXT(id, func)
EVT_TEXT_ENTER(id, func)
EVT_MENU(id, func)
EVT_MENU_RANGE(id1, id2,
func)
EVT_SLIDER(id, func)
EVT_RADIOBOX(id, func)
EVT_RADIOBUTTON(id, func)
EVT_SCROLLBAR(id, func)
EVT_COMBOBOX(id, func)
EVT_TOOL(id, func)
EVT_TOOL_RANGE(id1, id2,
func)
- 115 -
wxWindows – Programming cross-platform GUI applications in C++ - 116 -
- 116 -
wxWindows – Programming cross-platform GUI applications in C++ - 117 -
- 117 -