First Next Previous Last Glossary About

Programming with wxWindows - Using common dialogs


Introduction

Many operations in a GUI are repetitive, for example opening files, printing, changing directories. It helps the user if the tools they use for these operations are consistent in the way they look and behave and most API's (application programming interfaces) provide for the common operations. This saves the programmer much time and also ensures a consistent interface. The user can make a selection from a menu and expect to see a dialog that looks familiar and behaves consistently no matter what application they are running.

wxWindows provides for common dialog usage through a number of classes:

During the rest of this session we will use a number of these and will start by using the wxFileDialog class to extend the example from the earlier sessions. Before we start though keep in mind what we are doing: we are going to generate events from menu selections and launch common dialogs and use them.


Using the file dialog - wxFileDialog

File Open Dialog

When we use wxFileDialog as an "open file" dialog we see the familiar dialog box as shown here.

This is the file dialog for the Windows platform and would look different on Linux or Mac.

Since wxWindows is a cross-platform framework it will present whatever the common dialog is that is availabe on the particular platform or, if the common dialog is not available, wxWindows will substitute a generic dialog.


void BasicFrame::OnOpenFile (wxCommandEvent & event)
{ wxFileDialog
   * openFileDialog =
       new wxFileDialog ( this,
                          "Open file",
                          "",
                          "",
                          FILETYPES,
                          wxOPEN,
                          wxDefaultPosition);

   if (openFileDialog->ShowModal() == wxID_OK)
    { SetCurrentFilename(openFileDialog->GetFilename());
      theText->LoadFile(openFileDialog->GetFilename());
      SetStatusText(GetCurrentFilename(), 0);
      SetStatusText(openFileDialog->GetDirectory(),1);
    }
}

Here is an example event handler which presents an open file dialog to the user.

To use it we:

  • Construct the dialog, setting the arguments to the constructor as appropriate
  • Display the dialog
  • Get a return status when to user dismisses the dialog
  • Use the values held by the dialog if we need to



Construction involves declaring a variable openFileDialog which is a pointer to a type wxFileDialog. The arguments to the constructor are:

The member function ShowModal() displays the dialog. A dialog box can be either modal or modeless. If it is modal then no other window of the application can get the focus until the dialog box is closed. The user will dismiss the dialog box by selecting either the OK or Cancel buttons. ShowModal() returns an integer and if this is the same as wxID_OK we process the values held in the dialog box data structures by calling the various file dialog member functions.

In our case we get the filename with openFileDialog->GetFilename() and use this as an argument to SetCurrentFilename() which is a method of the parent frame. We also use openFileDialog->GetFilename() to load the file contents into theText. We also call SetStatusText() to set some values in the status bar and finally exit from the event handler at which point the file dialog instance is destroyed.

The Save file and Save as file dialogs are virtually the same as the Open file file dialog. The difference is a matter of how you use them. If you would like to see an example which uses all three then download wxbasic4a.zip and read the source code. I will continue this session with the font dialog.


Return to top of page


Using the font dialog - wxFontDialog

Font Chooser Dialog

The font dialog enables us to change the font of a parent window, in our case the text control theText. It is a little bit trickier to use than the file dialogs since we (should) determine what the current font settings of the parent window are before constructing and using the font dialog.

To do this we use three other classes



void BasicFrame::OnChooseFont(wxCommandEvent & event)
{ wxFontData fontData;
  wxFont     theFont;
  wxColour   colour;

  theFont = theText->GetFont();
  fontData.SetInitialFont(theFont);
  colour = theText->GetForegroundColour();
  fontData.SetColour(colour);
  fontData.SetShowHelp(true);
  wxFontDialog *dialog = new wxFontDialog(this, &fontData);
  if (dialog->ShowModal() == wxID_OK)
   { fontData = dialog->GetFontData();
     theFont = 	fontData.GetChosenFont();
     theText->SetFont(theFont);
     theText->SetForegroundColour(fontData.GetColour());
   }
}

Here is an example which uses the dialog and associated classes. There are a number of steps before constructing and after dismissing the font dialog instance:

If you would like to see an example which uses the font dialog and the other classes then download wxbasic4b.zip and read the source code.

A little reminder: In presenting the two examples 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.



Using the directory dialog - wxDirDialog

Directory Chooser Dialog

Whenever we have used the open file dialog we have found ourselves peering at some default directory, in my case "My Documents" (who would call a directory "My Documents"? - If it's your computer the directory isn't likely to be called "Someone Else's Documents"), it can be tedious.

To relieve the tedium and place us in a more useful location in the file system structure we can use a dialog and some useful functions. The dialog is the familiar directory chooser shown here and the useful functions are:

If we add a data member to store the CWD to our BasicFrame instance then we can retain the CWD during the execution of the program and never see "My Documents" again, unless we choose to.


void BasicFrame::OnChooseDir(wxCommandEvent & event)
{ wxDirDialog
   *d = new wxDirDialog
   	 (this,
          "Choose a directory",
          GetCurrentPath(),
          0,
          wxDefaultPosition);
  if (d->ShowModal() ==  wxID_OK)
   { SetCurrentPath(d->GetPath());}
}

Here is the event handler which produces the change directory dialog. When you compare it with the other dialogs it has a reassuringly familiar look. The arguments to the constructor are:

There is also the familiar if statement:

      if (d->ShowModal() ==  wxID_OK)
and after the directory dialog has been dismissed we can use one of its methods to get the selected directory:
      SetCurrentPath(d->GetPath())
SetCurrentPath() is a simple method we supply to update the BasicFrame data member we have already declared.

If you would like to see an example which uses the directory dialog and the functions then download wxbasic4c.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