Common Dialogs - SJSU



Common Dialogs

The Win32 API provides five "common dialogs" which you should use when you need to allow the user to

• print

• open or save a file

• select a color

• select a font

• find-and-replace in a text file

In practice, unless you are writing a word processor, you will not use the last two. Also, if you are using MFC, the code to open or save a file is already written by AppWizard, so you won't need to write additional code unless your application uses other files than its own saved documents.

That does happen, however. Examples of applications that open other files than their own: Visual C++, which lets you select files to insert or add to the project; Web site managers like Adobe GoLive that let you add files to your web site; MP3 players that let you open .mp3 files, etc.

As usual, MFC wraps these Win32 dialogs in C++ classes. These classes are derived from CDialog.

Common Dialog Classes

|Derived dialog class |Purpose |

|CColorDialog |Lets user select colors. |

|CFileDialog |Lets user select a filename to open or to save. |

|CFindReplaceDialog |Lets user initiate a find or replace operation in a text file. |

|CFontDialog |Lets user specify a font. |

|CPrintDialog |Lets user specify information for a print job. |

There is one important point: The purpose of the file dialog is to select a filename. What you do with that filename (e.g. open the file) is up to you. The dialog does NOT open a file. Similarly for colors and fonts.

Position of CFileDialog in the MFC class hierarchy:

Here's the most important part of the manual entry for CFileDialog:

To use a CFileDialog object, first create the object using the CFileDialog constructor.

After the dialog box has been constructed, you can set or modify any values in the m_ofn structure to initialize the values or states of the dialog box’s controls. The m_ofn structure is of type OPENFILENAME. For more information, see the OPENFILENAME structure in the Win32 SDK documentation.

After initializing the dialog box’s controls, call the DoModal member function to display the dialog box and allow the user to enter the path and file. DoModal returns whether the user selected the OK (IDOK) or the Cancel (IDCANCEL) button.

If DoModal returns IDOK, you can use one of CFileDialog’s public member functions to retrieve the information input by the user.

Did you get the essence here? You fill out an OPENFILENAME structure and then run the dialog. When using MFC, however, most of the time you can supply the information to the constructor of a CFileDialog, which fills in the OPENFILENAME structure for you. So all you have to do is construct the CFileDialog object and then call its DoModal member function.

Here's a sample file-opening dialog clipped from Visual C++:

This picture shows a “classic style” dialog. The Windows user can

have a choice of “Explorer style” dialogs or “classic style”. Here’s

an Explorer style dialog for comparison:

[pic]

Notice the combo box labeled "Files of type:".

Each line of this combo box contains description of a file type, and the associated filename extensions. When you select something from this combo box, the files displayed in the list above are those that match the specified filename extensions. The programmer has to specify BOTH things when programming this dialog: the description string (that will appear in the combo box) and separately the list of filename extensions to be matched when that description is selected. This is confusing because usually the description ALSO contains the list of filename extensions. In principle though you have the freedom to use one set of filename extensions for the matching and any text whatever in the description.

The way you do this is that you specify for each line of the combo box a pair of “filter strings”. The first filter string of each pair consists of a display string, such as "C++ files (*.cpp)". (That’s the text for one line of the combo box.) The second string is a list of one or more "filter patterns" (such as ".cpp"). (That’s the corresponding list of extensions to be used for matching.) This list of filter strings has to be given by the programmer, usually in the constructor of a CFileDialog object. From there, MFC puts the information into an OPENFILENAME structure, where it is passed to the Win32 file dialog when DoModal runs. If the second member of the pair lists more than one file type, semicolons separate them (and no spaces may occur). You use wild-cards. For example,

"*.c;*.cpp;*.cxx;*.tli;*lh;*inl;*.rc" for the above dialog.

This information all has to go into one string, which is passed to the CFileDialog constructor, or when using the OPENFILENAME structure, is placed into the lpstrFilter member of the structure. How can we pack a list of strings into a single string? The answer is, they need to be separated by some character which is not used in filenames. In the Windows API the null character is used. This is awkward because usually this character is used to terminate strings. This particular character array is then terminated by two null characters. When using the constructor of a CFileDialog object, instead we use the vertical bar character, with two vertical bars at the end. (MFC then internally replaces the vertical bars with null characters in the structure that it passes to the Win32 API function.)

CFileDialog::CFileDialog

CFileDialog( BOOL bOpenFileDialog,

LPCTSTR lpszDefExt = NULL,

LPCTSTR lpszFileName = NULL,

DWORD dwFlags = OFN_HIDEREADONLY |

OFN_OVERWRITEPROMPT,

LPCTSTR lpszFilter = NULL,

CWnd* pParentWnd = NULL );

Parameters

bOpenFileDialog

Set to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box.

lpszDefExt

The default filename extension. If the user does not include an extension in the Filename edit box, the extension specified by lpszDefExt is automatically appended to the filename. If this parameter is NULL, no file extension is appended.

lpszFileName

The initial filename that appears in the filename edit box. If NULL, no filename initially appears.

dwFlags

A combination of one or more flags that allow you to customize the dialog box. For a description of these flags, see the OPENFILENAME structure in the Win32 SDK documentation. If you modify the m_ofn.Flags structure member, use a bitwise-OR operator in your changes to keep the default behavior intact.

lpszFilter

A series of string pairs that specify filters you can apply to the file. If you specify file filters, only selected files will appear in the Files list box. See below for more information on how to work with file filters.

pParentWnd

A pointer to the file dialog-box object’s parent or owner window.

Remarks

Call this function to construct a standard Windows file dialog box-object. Either a File Open or File Save As dialog box is constructed, depending on the value of bOpenFileDialog.

The lpszFilter parameter is used to determine the type of filename a file must have to be displayed in the file list box. The first string in the string pair describes the filter; the second string indicates the file extension to use. Multiple extensions may be specified using ‘;’ as the delimiter. The string ends with two ‘|’ characters, followed by a NULL character. You can also use a CString object for this parameter.

For example, Microsoft Excel permits users to open files with extensions .XLC (chart) or .XLS (worksheet), among others. The filter for Excel could be written as:

static char szFilter[] =

"Chart Files (*.xlc)|*.xlc|

Worksheet Files (*.xls)|*.xls|

Data Files (*.xlc;*.xls)|*.xlc; *.xls|

All Files (*.*)|*.*||";

(Note, line breaks are in these notes for clarity—you can’t have a line break inside a constant string in actual code.)

Member functions of CFileDialog:

|DoModal |Displays the dialog box and allows the user to make a selection. |

|GetPathName |Returns the full path of the selected file. |

|GetFileName |Returns the filename of the selected file. |

|GetFileExt |Returns the file extension of the selected file. |

|GetFileTitle |Returns the title of the selected file. |

|GetNextPathName |Returns the full path of the next selected file. |

|GetReadOnlyPref |Returns the read-only status of the selected file. |

|GetStartPosition |Returns the position of the first element of the filename list. |

The title of the file includes only its prefix, without the path or the extension. For example, GetFileTitle will return "TEXT" for the file C:\FILES\TEXT.DAT. GetFileExt will return "DAT" (not including the period).

GetNextPathName and GetStartPosition are used when you want to allow multiple path selection. By default this is not allowed. If you want to do this, read the manual entries.

GetReadOnlyPref tells you whether the user has checked the "read only" box--see below.

CFileDialog::CFileDialog

CFileDialog( BOOL bOpenFileDialog,

LPCTSTR lpszDefExt = NULL,

LPCTSTR lpszFileName = NULL,

DWORD dwFlags = OFN_HIDEREADONLY |

OFN_OVERWRITEPROMPT,

LPCTSTR lpszFilter = NULL,

CWnd* pParentWnd = NULL );

Parameters

bOpenFileDialog

Set to TRUE to construct a File Open dialog box or FALSE to construct a File Save As dialog box.

lpszDefExt

The default filename extension. If the user does not include an extension in the Filename edit box, the extension specified by lpszDefExt is automatically appended to the filename. If this parameter is NULL, no file extension is appended.

lpszFileName

The initial filename that appears in the filename edit box. If NULL, no filename initially appears.

dwFlags

A combination of one or more flags that allow you to customize the dialog box. For a description of these flags, see the OPENFILENAME structure in the Win32 SDK documentation [some are included below]. If you modify the m_ofn.Flags structure member, use a bitwise-OR operator in your changes to keep the default behavior intact.

lpszFilter

A series of string pairs that specify filters you can apply to the file. If you specify file filters, only selected files will appear in the Files list box. See the Remarks section for more information on how to work with file filters.

pParentWnd

A pointer to the file dialog-box object’s parent or owner window.

Here are some of the flags you can use to control a file dialog.

There are many details, but these details are important.

Is the user allowed to use a filename extension different from the default? Do you want to do something about it if they do? Then use the OFN_EXTENSIONDIFFERENT flag, which specifies that the user typed a filename extension different from that specified by

lpstrDefExt.

Should the current directory change to the directory of the selected file? Or should it stay in the application's directory (or wherever it was before)? To leave it where is was, use the OFN_NOCHANGEDIR flag.

Want to not allow the selection of a read-only file? Use the OFN_NOREADONLYRETURN flag. This also blocks files for which the user does not have write permission, which is common on a network.

Should they be able to open files over the network? If not then use the OFN_NONETWORKBUTTON flag.

Should they see a "Read Only" check box? (Maybe you want to let them save files as "read only".) This is controlled by the OFN_HIDEREADONLY flag, which is set by default.

Sample Code:

void CFileDemoView::OnOpentextfile()

{

CFileDialog myDialog(TRUE, // file open; FALSE means "save as"

"txt", // default file extension

NULL, // file name to show initially

OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,

"Text Files (*.txt)|*.txt|" // filter string );

int id = myDialog.DoModal();

if(id == IDOK)

{ // open the file, or do whatever you want with the file.

}

}

In this code, "Text Files (*.txt)" will appear as text for the user to read, while "*.txt" is used to control what files are displayed to choose from. Note that you don’t need TWO vertical bars at the end, since the string already terminates in a null character, and after the vertical bars are replaced with null characters, there will be two nulls at the end. You DO need the period in the second *.txt.

If you want to try this code out, as I did in class, you will need to know how to open a file in Windows. Here is some sample code that opens a text file and reads the contents into a single CString, here called m_edit.

CFile file(filename, CFile::modeReadWrite | CFile::shareDenyNone);

// this constructor also opens the file

char buffer[1500];

int nchars;

m_edit = "";

buffer[1000] = '\0';

while((nchars = file.Read(buffer,1000)) == 1000)

{ m_edit = m_edit + CString(buffer);

}

buffer[nchars] = 0;

m_edit = m_edit + CString(buffer);

File Errors

Traditionally, opening and saving files is a difficult programming task because there are many possible errors:

• an open drive door

• a full disk

• write protection tab on

• network permission problems

• a bad disk

The CFileDialog by default tests whether the file can be opened or created, then closes it again. That's the only certain way to be sure that none of these errors occur. Therefore, you don't have to check for these errors before proceeding to open the file.

However, there is such a thing as a "create non-modify network share", and if you must allow users to work with such network permissions, this default behavior must be disabled, or else the trial opening will create the file and then the user won't be able to modify it. See the manual if you have this problem.

The CColorDialog class allows you to incorporate a color-selection dialog box into your application.

A CColorDialog object is a dialog box with a list of colors that are defined for the display system. The user can select or create a particular color from the list, which is then reported back to the application when the dialog box exits.

After initializing the dialog box’s controls, call the DoModal member function to display the dialog box and allow the user to select a color. DoModal returns the user’s selection of either the dialog box’s OK (IDOK) or Cancel (IDCANCEL) button.

If DoModal returns IDOK, you can use one of CColorDialog’s member functions to retrieve the information input by the user.

CColorDialog::CColorDialog

CColorDialog(

COLORREF clrInit = 0,

DWORD dwFlags = 0,

CWnd* pParentWnd = NULL );

clrInit

The default color selection. If no value is specified, the default is RGB(0,0,0) (black).

dwFlags

A set of flags that customize the function and appearance of the dialog box. For more information, see the CHOOSECOLOR structure in the Win32 SDK documentation.

pParentWnd

A pointer to the dialog box’s parent or owner window.

Examples

// Show the Color dialog with all the default settings.

CColorDialog dlg;

int retval = dlg.DoModal();

if(retval == IDOK)

// retrieve the chosen color

COLORREF color = dlg.GetColor();

Note that black is the initially selected color above. The dialog is "fully opened", meaning the custom color boxes show. If it's not fully opened, the Define Custom Colors button shows, but the custom color boxes don't show until you push that button. You can also show it with the Define Custom Colors button disabled. To do that set the CC_PREVENTFULLOPEN flag when calling the constructor. The CC_SOLIDCOLOR flag prevents showing hatched colors.

// Show the fully opened Color dialog with red as the selected color.

CColorDialog dlg(RGB(255, 0, 0), CC_FULLOPEN);

int retval = dlg.DoModal();

if(retval == IDOK)

// retrieve the chosen color

COLORREF color = dlg.GetColor();

Member Functions:

|DoModal |Displays a color dialog box and allows the user to make a selection. |

|GetColor |Returns a COLORREF structure containing the values of the selected color. |

|GetSavedCustomColors |Retrieves custom colors created by the user. |

|SetCurrentColor |Forces the current color selection to the specified color. |

You would normally use only the first two or three of these.

Instead of using SetCurrentColor, you use the constructor of CColorDialog as in the above example.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download