wxWidgets in Dev C++ - Lesson 2 of n - Hello World using the reference manual

Note: I am writing these tutorials with the assumption that the reader is familiar with C++. If you are not then you might want to brush up on your C++ skills before continuing any further.

Rather than the typical GUI hello worlds, we are going to add a little twist to demonstrate the use of the very important manual throughout the development process.

First off, start a new project File -> New -> Project…. Select the “GUI Toolkits” tab and click “wxWindows”. Name the project and click “Ok”.

Two files will be created “base.h” and “base.cpp”. The first thing one would have to do in order to use wxWidgets is create a class that inherits the wxApp class which is included from “wx/wx.h”. All this is automatically done for you if you use the project template wxWindows. In our case the application class is “MainApp” inherits wxApp with a function overriding the parent function OnInit(). The OnInit() function is where we put the initialization code and create our GUI forms. You will notice that at the top of the base.cpp file a macro IMPLEMENT_APP is used to specify the main application class. This is necessary so that wxWidgets knows which class is the main application class for program entry. wxWidgets in windows requires at least one resource file. Create a new resource file by clicking File -> New… -> Resource file and add the following line:

#include "wx/msw/wx.rc"


Creating and customizing a window

Creating a window widget – or what is also known as a frame – is done by creating a class that inherits wxFrame. The project template creates the class MainFrame which inherits the wxFrame class from wxWidgets. Any additional windows you want to create must typically follow the same approach to creating the MainFrame class. In the constructor of MainFrame we pass variables from the constructor of the child class to the parent class wxFrame. To add additional optional parameters such as specifying the style of the frame you simply add them to both constructors or to the parent class’ constructor. For instance, if we want to create a fixed-size window that only includes a window caption and a X (Close) icon, we add the following parameters to the constructor:

MainFrame::MainFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
: wxFrame((wxFrame *) NULL, -1, title, pos, size, wxCAPTION | wxCLOSE_BOX | wxSYSTEM_MENU)


To lookup the constructor parameters for the wxFrame for additional customization, open the manual by navigating to All Programs -> Bloodshed Dev-C++ -> wxWidgets -> wxWidgets Help File. Click the Content tab if it is not selected and click the “Alphabetical class reference”. Select wxFrame and click “wxFrame::wxFrame” for the constructor parameters and “wxFrame” for a detailed list of all styles available. If styling the window is not important simply leave the style off the constructor for the default style.

Because we do not want menus or a status bar for our hello world application, we will remove the code added by the template. Clear the code within the constructor for the MainFrame class leaving it as follows:

MainFrame::MainFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
: wxFrame((wxFrame *) NULL, -1, title, pos, size)
{
}


The overridden OnInit() function in the MainApp class, includes initialization code for the MainFrame class. The first line is where we initialize the MainFrame class with our parameters. You will notice that the constructor include two constructor functions wxPoint and wxSize. These will allow us to specify the &pos and the &size variables by returning the appropriate object type for both variables. Again from the “Alphabetical class reference”, lookup up the wxPoint class and the wxSize class to see what the parameters in these class constructors donate. To save you the trouble, they point to the x and y variables of a wxWidgets object representing a point or a size. The project template initializes a win MainFrame object. Change the parameters of the constructor to whatever suits your needs. The second line calls the Show() function which displays the frame to the user. The third line is optional and sets the frame as the top window on the user’s screen. We return TRUE to signal that initialization was successful. This pretty much is all there is to creating a window.

If you want to customize the appearance of the frame, call functions from the parent class wxFrame or any of the parent classes of wxFrame. For instance, the reference manual mentions that wxFrame is derived from wxTopLevelWindow and wxWindow. Adding the following function inherited from wxWindow before the win->Show(TRUE) line sets the background to white:

win->SetBackgroundColour(_(“White”));


You can lookup additional functions to customize the appearance such as the SetIcon() function inherited from wxTopLevelWindow class by navigating through the documentation for the classes that wxFrame is derived from.

Adding widgets to your windows: a wxStaticText, a wxStaticBitmap, and a wxButton

Let’s add three types of widgets to demonstrate how different sorts of widgets are added to the frame. I am going to use absolute positioning rather than relative positioning which is often mentioned in wxWidget tutorials. Future tutorials will elaborate further on widget positioning.

Adding a control to the frame is a simply done by creating a new control object in the constructor of the frame. Unless you need to refer to the controls programmatically later on, there is no need to include the control variables in the class’ private variable list. Additionally, you need to specify an ID for every control you add to the frame that will interact with user events. Although specifying an ID is optional in wxWidgets, it greatly eases the identification of controls later on when we want to deal with user events. Creating an ID is simply done by adding an ID variable to the ID enum in base.h similar to what is being practiced with controls added through a windows resource file.

Let’s lookup wxStaticText in the reference manual and default constructor wxStaticText::wxStaticText. The default constructor for wxStaticText is the following:

wxStaticText(wxWindow* parent, wxWindowID id, const wxString& label, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "staticText")


To add a wxStaticText control, we simply construct the object in the MainFrame constructor function as follows:

wxStaticText *sometext = new wxStaticText(this, wxID_ANY, _(“Hello world label”), wxPoint(100,100));

We specify the current frame as the parent window. Because no ID is needed for this control, the default wxID_ANY is specified. The text is specified in the label variable and the pos variable specifies where the control will be located. Other variables are left to their defaults. Again, to customize the control, the documentation in the reference manual includes functions to set properties to the control. Navigate through the main class functions as well as any class that was derived from. For instance, the function SetLabel() inherited from wxControl can be used to set the control’s text either during construction or later on if you include a reference to the control in the MainFrame private variables list.

The wxStaticBitmap control is similar to wxStaticText. As mentioned in the reference, the difference between the default constructor of the two is in the third parameter which specifies a wxBitmap rather than a wxString. There are two ways to add a bitmap image to your application. You can either include it as a resource or load it from a file.

To add a resource to your project open the resource file you created earlier and include the following line:

IDC_MYIMAGE BITMAP “bitmap-filename-goes-here.bmp”


Where IDC_MYIMAGE is the resource identifier, BITMAP is the resource type, and "bitmap-filename-goes-here.bmp" is where to place the path to the bitmap. Now using the wxBITMAP() macro we specify the resource bitmap to the wxBitmap class constructor giving us an object containing the required bitmap image. We add the control to the frame by constructing it in the MainFrame class constructor as follows:

wxStaticBitmap *someBitmap = new wxStaticBitmap(this, wxID_ANY, wxBitmap(wxBITMAP(IDC_MYIMAGE)), wxPoint(100,0));


If, on the other hand, we want to specify an external file to be loaded during runtime we use the following wxBitmap constructor mentioned in the reference manual:

wxBitmap(const wxString& name, long type)


Where name is the file name of the bitmap and type is the type. From the manual we can choose different types as we require. For instance if we are creating a bmp bitmap we specify wxBITMAP_TYPE_BMP.

With regards to the wxButton control. Two additional steps are necessary to interact with the user’s click. Firstly we need to create a function that handles the click event and then attach this function to the event table using wxWidget’s BEGIN_EVENT_TABLE and END_EVENT_TABLE set of macros. Let’s add a OnButtonClick() function. Open the base.h file and add the declaration:

void OnButtonClick(wxCommandEvent &event);


To the public functions list. Now implement the OnButtonClick() function in base.cpp to show a message box saying Hi. We add the following code to the MainFrame::OnButtonClick(wxCommandEvent &event) function:

wxMessageDialog *aMsg = new wxMessageDialog(this,_("Hello World!"), _("A Hello World Dialog"), wxOK);
aMsg->ShowModal();
free(aMsg);


We are simply referring to the reference manual’s entry for wxMessageDialog to create a new message dialog and then showing it to the user using the ShowModal() function. The free() function is merely for garbage collection.

Now we need to create an ID for the button to be handled by the EVENT_TABLE set of macros. In the base.h file add the following ID declaration to the ID enum:

ID_MYBUTTON_CLICK 4001


The number 4001 is arbitrary. However it has been common amongst programmers to use numbers starting from 4000 to donate ID numbers of GUI controls.

We move on to the MainFrame class constructor to add the wxButton control. Using the default constructor as mentioned in the reference, we create a wxButton with an id of ID_MYBUTTON_CLICK. The following code demonstrates the construction of the control:

wxButton *myButton = new wxButton(this,ID_MYBUTTON_CLICK, _("Click here"), wxPoint(100,200));

Finally, we attach the ID to the frame’s event table. Look for the line that starts with BEGIN_EVENT_TABLE in base.cpp. The wxButton control triggers the EVT_BUTTON as mentioned in the main page for the wxButton control in the reference manual. So we add the following line to attach our function to the button click event:

EVT_BUTTON(ID_MYBUTTON_CLICK, MainFrame::OnButtonClick)


Compiling and running the program should display the following picture:



To download the source code for the resulting program click here

Next
Pending…

Previous
wxWidgets in Dev C++ - Lesson 1 of n – Installation


Lesson 3: using wxDev-C++

Hi,

Thanks for your tutorial. But because I was unable to compile and run the suggested example, I looked over again and I discovered wxDev-C++, at http://wxdsgn.sourceforge.net which is a Dev-C++ environment prepared to work with wxWidgets.

It is much simpler to use, I think, but I'm new to Dev-C++ and Windows based development. (I'm interested in portable applications, to run either on Linux and Windows).

I hope this pointer to wxDev-C++ helps.

Regards,

Jorge

Widgets for Dev C++

Hi,
I am new to using Dev C++, usually I develop computer graphics code using Linux Environment. I have installed the Dev C++ and have also added graphics.h, and glut package as are needed to compile my code successfully. But now I am getting an error with widget function. Can you please tell me how do I deal with that?
Thanks,
-Preeti

This program is extremely

This program is extremely useful if you have a windows program that only supports basic authentication proxy servers and not NTLM authentication proxy servers. This is common in open-source programs and legacy programs with basic or no support for proxy authentication. This program works as a tunnel between your NTLM proxy server and a program that can only support basic proxy servers wax jackets | boys coats | maternity coats | winter coats for women

Recent comments