First | Next | Previous | Last | Glossary | About

# Programming with wxWindows - Using custom dialogs

- Introduction
- Using a first custom dialog
- Building a first custom dialog
- Summary

## Introduction

It's plain that common dialogs are only going to meet common needs and there are many occasions when we need to build custom dialogs.

It isn't particularly difficult to build custom dialogs but it can be complex depending on the approach you take and most of the initial complexity comes from actually designing the look of the custom dialog box, for example where controls will be located and what the sizes of the controls will be. We first look at doing it the hard way by hard-coding the dialog box appearance.

There are much better ways which involve using resource tools like Julian Smart's Dialog Editor and/or Robert Roebling's wxDesigner. Dialog Editor is distributed with wxWindows, wxDesigner is a shareware product and is well worth the few dollars it costs. You can go a fair way with Dialog Editor but the differences between the two are quite significant and I very much recommend getting wxDesigner.

## Building and using a first custom dialog

Here is a very simple dialog box, it contains three controls, a text control and two buttons. The dialog box itself has a location on screen relative to its parent window and a height and a width. Each of the controls has a location relative to the dialog which is the parent window of the controls, and each of the controls has a size.

First I'll show you how we use it then we can look at the beast in detail.

    void BasicFrame::OnAbout(wxCommandEvent & event)
    {
      BasicDialog
       aboutDialog ( this,
                     -1,
                     "Your very own dialog",
                     wxPoint(100,100),
                     wxSize(200,200)
                   );
      if (aboutDialog.ShowModal() != wxID_OK)
       theText->AppendText("The about box was cancelled.\n");
      else
       theText->AppendText(aboutDialog.GetText());
    }

Here you can see how we call the dialog. The dialog is instantiated in the BasicFrame's About method.

To use it we:

- Construct the dialog, setting the arguments to the constructor as appropriate: aboutdialog is of type BasicDialog.
- We call the dialog's ShowModal method which displays the dialog. We could call Show() in which case the dialog wouldn't hijack the focus but most dialogs are meant to be used modally, i.e. when a modal dialog is displayed we can't shift the input focus to anything else in the application.
- We get a return status which we test. If the ShowModal method returns a value which is the same as wxID_OK we do one thing, if it isn't we do something else.
- We then use the values held by the dialog text control.

As you can see the usage of the dialog is no different from any other dialog.

Return to top of page

## Building a custom dialog

    class BasicDialog: public wxDialog
    {
       public:
        BasicDialog
         ( wxWindow *parent,
           wxWindowID id,
           const wxString &title,
           const wxPoint& pos = wxDefaultPosition,
           const wxSize& size = wxDefaultSize,
           long style = wxDEFAULT_DIALOG_STYLE
         );
        wxTextCtrl * dialogText;
        wxString GetText();
       private:
        void OnOk( wxCommandEvent &event );
        DECLARE_EVENT_TABLE()
    };

The header file basic.h contains the dialog interface.

BasicDialog is descended from wxDialog and a dialog needs the following for its construction:

- A parent window: The dialog must belong to something.
- An ID: This can be something determined by the programmer or it can be -1 in which case a default value will be chosen.
- A title: Simply a wxString.
- A position relative to the parent.
- A size.
- A style.

The custom dialog can also have one other construction parameter inherited from wxDialog and that is a name. This property has limited, if any, use in Windows.

The implementation of the custom dialog is in basic.cpp.

BasicDialog declares two public members apart from its constructor. There is a text control and a member function which returns a string. BasicDialog also declares a private member OnOk() and an event table.

    BasicDialog::BasicDialog
     ( wxWindow *parent,
       wxWindowID id,
       const wxString &title,
       const wxPoint &position,
       const wxSize& size,
       long style
     ) :
     wxDialog( parent, id, title, position, size, style)
| The constructor which inherits from wxDialog.
     {
      wxString dimensions = "", s;
      wxPoint p;
      wxSize  sz;

      sz.SetWidth(size.GetWidth() - 20);
      sz.SetHeight(size.GetHeight() - 70);
| We declare some local variables. p and sz will used to help layout the positions and sizes of controls in the dialog. You should read about the WxPoint and wxSize classes in the wxWindows help.
      p.x = 6; p.y = 2;
      s.Printf(" x = %d y = %d\n", p.x, p.y);
      dimensions.append(s);
      s.Printf( " width = %d height = %d\n",
                sz.GetWidth(), sz.GetHeight());
      dimensions.append(s);
      dimensions.append(AUTHOR);
| We set some initial position values in p and also use the Printf method of wxString to format a message.
      dialogText =
       new wxTextCtrl ( this, -1,
    		    dimensions,
    		    p, sz,
                        wxTE_MULTILINE
    		  );
| A text control is added to the dialog, it contains whatever the string dimensions contains and is postioned and size according to p and sz.
      p.y += sz.GetHeight() + 10;
      wxButton * b =
       new wxButton( this,
    		 wxID_OK,
    		 "OK",
    		 p,
    		 wxDefaultSize);
      p.x += 110;
      wxButton * c =
       new wxButton( this,
    		 wxID_CANCEL,
    		 "Cancel",
    		 p,
    		 wxDefaultSize);
    }
| Now we adjust p, create a button b, adjust p again and create a button c. Note that wxID_OK and wxID_CANCEL are used. These are default ID's.

If you would like to see an example which uses the custom dialog then download wxbasic5.zip and read the source code.

## Summary

A note ...
    enum
    { BASIC_EXIT    =   wxID_HIGHEST + 1,
      BASIC_OPEN,
      BASIC_SAVE,
      BASIC_SAVE_AS,
      BASIC_FONT,
      BASIC_DIR,
      BASIC_ABOUT,
      BASIC_HELP
    };

If you look through the examples you will see I have made a slight change to the enumerated range that we use for our window ID's.

wxWindows uses a number of "standard" ID's and the authors recommend that users of the framework avoid simply plugging in any value for a window ID since it may conflict with one of those already allocated. We can avoid conflict by using wxID_HIGHEST + 1 when enumerating our own ID's.

A little reminder: In presenting these I have show only the salient details. You should remember that the examples also contain other code that is relevant, for example the window identifiers and the event table. I have left the bulk of the example programs out of the presentation in order to save space and minimize distraction.

Return to top of page

First | Next | Previous | Last | Glossary | About

Copyright © 1999 - 2001 David Beech