Writing Your First Application-Common Dialogs

From WxWiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Besides creating your own dialog windows, in wxWidgets it is easy to use whats called "common dialogs". Common dialogs are pre-made dialogs for various operations. The advantage is that there is less work involved in creating the dialogs, and the dialogs inherit the look and feel of the operating system on which your application runs. This is a big advantage for creating portable applications.

There are common dialogs ranging from a simple message box, to a user input box, to a full, file selection dialog. We cover the file selection dialog for opening and saving files here. If you would like to see what other ones are available there is some good information in the manual.

Initializing the file selection dialog isn't hard--we just declare a new wxFileDialog object and initialize it with the following arguments:

  1. A parent window. We'll just use this.
  2. The title for the dialog window.
  3. The default directory. We'll just use an empty string.
  4. The default file name. Again we'll use a empty string.
  5. A wildcard for the file types we'll be using in this format: "File type (*.ext)|*.ext|"
  6. The dialog style. Use either wxFD_OPEN if you intend to open a file, wxFD_MULTIPLE to allow multiple file selections, wxFD_SAVE if it is intended to save a file, and wxFD_OVERWRITE_PROMPT to prompt the user for confirmation if they attempt to overwrite a file.

When we want to get the data for the file the user selected, we first check to see if wxFileDialog->ShowModal() returns wxID_OK (meaning the user pressed the "OK" button). Then we use GetDirectory to return the directory the in which the file is located, GetFilename to return the file name without the directory, GetFilenames if we set wxMULTIPLE when creating the dialog, and GetPath to return the full path to the file chosen. Heres an example of an improved OpenFile() function:

void MainFrame::OpenFile(wxCommandEvent& WXUNUSED(event))
{
	wxFileDialog* OpenDialog = new wxFileDialog(
		this, _("Choose a file to open"), wxEmptyString, wxEmptyString, 
		_("Text files (*.txt)|*.txt|C++ Source Files (*.cpp, *.cxx)|*.cpp;*.cxx|
		C Source files (*.c)|*.c|C header files (*.h)|*.h"),
		wxFD_OPEN, wxDefaultPosition);

	// Creates a "open file" dialog with 4 file types
	if (OpenDialog->ShowModal() == wxID_OK) // if the user click "Open" instead of "Cancel"
	{
		CurrentDocPath = OpenDialog->GetPath();
		// Sets our current document to the file the user selected
		MainEditBox->LoadFile(CurrentDocPath); //Opens that file
		SetTitle(wxString("Edit - ") << 
			OpenDialog->GetFilename()); // Set the Title to reflect the file open
	}

	// Clean up after ourselves
	OpenDialog->Destroy();
}

And here is the source to create this:

#include <wx/string.h>
#include <wx/menu.h>
#include <wx/textctrl.h>

// MainApp is the class for our application, it just acts
// as a container for the window or frame in MainFrame.
class MainApp: public wxApp
{
public:
	virtual bool OnInit();
};

// MainFrame is the class for our window, it
// contains the window and all objects in it.
class MainFrame: public wxFrame
{
public:
	MainFrame( const wxString &title, const wxPoint &pos, const wxSize &size );

	void Quit( wxCommandEvent& event );
	void NewFile( wxCommandEvent& event );
	void OpenFile( wxCommandEvent& event );
	void SaveFile( wxCommandEvent& event );
	void SaveFileAs( wxCommandEvent& event );
	void CloseFile( wxCommandEvent& event );

	wxTextCtrl *MainEditBox;
	wxMenuBar *MainMenu;
	// The Path to the file we have open
	wxString CurrentDocPath;

	DECLARE_EVENT_TABLE()
};

enum
{
	// declares an id which will be used to call our button
	TEXT_Main = wxID_HIGHEST + 1,
	MENU_New,
	MENU_Open,
	MENU_Close,
	MENU_Save,
	MENU_SaveAs,
	MENU_Quit
};

BEGIN_EVENT_TABLE ( MainFrame, wxFrame )
	EVT_MENU(MENU_New, MainFrame::NewFile)
	EVT_MENU(MENU_Open, MainFrame::OpenFile) 
	EVT_MENU(MENU_Close, MainFrame::CloseFile)
	EVT_MENU(MENU_Save, MainFrame::SaveFile)
	EVT_MENU(MENU_SaveAs, MainFrame::SaveFileAs)
	EVT_MENU(MENU_Quit, MainFrame::Quit)
END_EVENT_TABLE()
#include <wx/wxprec.h>

#ifndef WX_PRECOMP
#	include <wx/wx.h>
#endif

#include "base.h"

IMPLEMENT_APP(MainApp) // Initializes the MainApp class...

// .. and tells our program to run it
bool MainApp::OnInit()
{
	// Create an instance of our frame, or window
	MainFrame *MainWin = new MainFrame(
		_("Edit"), wxPoint(1, 1), wxSize(300, 200));
	MainWin->Show(TRUE); // show the window
	SetTopWindow(MainWin); // and finally, set it as the main window
	return TRUE;
}

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

	MainMenu = new wxMenuBar();
	wxMenu *FileMenu = new wxMenu();

	FileMenu->Append(MENU_New,
		_("&New"), _("Create a new file"));

	FileMenu->AppendSeparator();
	FileMenu->Append(MENU_Open,
		_("&Open"), _("Open an existing file"));
	FileMenu->Append(MENU_Close,
		_("&Close"), _("Close the current document"));

	FileMenu->AppendSeparator();
	FileMenu->Append(MENU_Save,
		_("&Save"), _("Save the current document"));
	FileMenu->Append(MENU_SaveAs,
		_("Save &As"), _("Save the current document under a new file  name"));

	FileMenu->AppendSeparator();
	FileMenu->Append(MENU_Quit,
		_("&Quit"), _("Quit the editor"));

	MainMenu->Append(FileMenu, _("&File"));
	SetMenuBar(MainMenu);

	MainEditBox = new wxTextCtrl(
		this, TEXT_Main, _("Hi!"), wxDefaultPosition, wxDefaultSize, 
		wxTE_MULTILINE | wxTE_RICH , wxDefaultValidator, wxTextCtrlNameStr);

	Maximize(); // Maximize the window
}

void MainFrame::NewFile(wxCommandEvent& WXUNUSED(event))
{
	// Clear the edit box
	MainEditBox->Clear();
	// reset the path of our current open file
	CurrentDocPath = wxT("C:/");
	// Set the Title to reflect the file open
	SetTitle(_("Edit - untitled *"));
}

void MainFrame::OpenFile(wxCommandEvent& WXUNUSED(event))
{
	wxFileDialog *OpenDialog = new wxFileDialog(
		this, _("Choose a file to open"), wxEmptyString, wxEmptyString,
		_("Text files (*.txt)|*.txt|C++ Source Files (*.cpp, *.cxx)|*.cpp;*.cxx|
		C Source files (*.c)|*.c|C header files (*.h)|*.h"),
		wxFD_OPEN, wxDefaultPosition);

	// Creates a "open file" dialog with 4 file types
	if (OpenDialog->ShowModal() == wxID_OK) // if the user click "Open" instead of "cancel"
	{
		CurrentDocPath = OpenDialog->GetPath();

		// Sets our current document to the file the user selected
		MainEditBox->LoadFile(CurrentDocPath); //Opens that file
		// Set the Title to reflect the  file open
		SetTitle(wxString("Edit - ") << OpenDialog->GetFilename());
	}
}

void MainFrame::CloseFile(wxCommandEvent& WXUNUSED(event))
{
	// Clear the Text Box
	MainEditBox->Clear();
	// Reset the current File being edited
	CurrentDocPath = wxT("C:/");
	// Set the Title to reflect the file open
	SetTitle(_("Edit - untitled *"));
}

void MainFrame::SaveFile(wxCommandEvent& WXUNUSED(event))
{
	// Save to the already-set path for the document
	MainEditBox->SaveFile(CurrentDocPath);
}

void MainFrame::SaveFileAs(wxCommandEvent& WXUNUSED(event))
{
	wxFileDialog *SaveDialog = new wxFileDialog(
		this, _("Save File As _?"), wxEmptyString, wxEmptyString,
		_("Text files (*.txt)|*.txt|C++ Source Files (*.cpp)|*.cpp|
		C Source files (*.c)|*.c|C header files (*.h)|*.h"),
		wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition);

	// Creates a Save Dialog with 4 file types
	if (SaveDialog->ShowModal() == wxID_OK) // If the user clicked "OK"
	{
		CurrentDocPath = SaveDialog->GetPath();
		// set the path of our current document to the file the user chose to save under
		MainEditBox->SaveFile(CurrentDocPath); // Save the file to the selected path
		// Set the Title to reflect the file open
		SetTitle(wxString("Edit - ") << SaveDialog->GetFilename());
	}

	// Clean up after ourselves
	SaveDialog->Destroy();
}

void MainFrame::Quit(wxCommandEvent& WXUNUSED(event))
{
	Close(TRUE); // Close the window
}