Using Common Dialog Boxes
This section covers tasks that invoke common dialog boxes:
Choosing a Color
This topic describes sample code that displays a Color dialog box so that a user can select a color. The sample code first initializes a CHOOSECOLOR structure, and then calls the ChooseColor function to display the dialog box. If the function returns TRUE, indicating that the user selected a color, the sample code uses the selected color to create a new solid brush.
This example uses the CHOOSECOLOR structure to initialize the dialog box as follows:
- Initializes the lpCustColors member with a pointer to a static array of values. The colors in the array are initially black, but the static array preserves custom colors created by the user for subsequent ChooseColor calls.
- Sets the CC_RGBINIT flag and initializes the rgbResult member to specify the color that is initially selected when the dialog box opens. If not specified, the initial selection is black. The example uses the rgbCurrent static variable to preserve the selected value between calls to ChooseColor.
- Sets the CC_FULLOPEN flag so the custom colors extension of the dialog box is always displayed.
Choosing a Font
This topic describes sample code that displays a Font dialog box so that a user can choose the attributes of a font. The sample code first initializes a CHOOSEFONT structure, and then calls the ChooseFont function to display the dialog box.
This example sets the CF_SCREENFONTS flag to specify that the dialog box should display only screen fonts. It sets the CF_EFFECTS flag to display controls that allow the user to select strikeout, underline, and color options.
If ChooseFont returns TRUE, indicating that the user clicked the OK button, the CHOOSEFONT structure contains information that describes the font and font attributes selected by the user, including the members of the LOGFONT structure pointed to by the lpLogFont member. The rgbColors member contains the selected text color. The sample code uses this information to set the font and text color for the device context associated with the owner window.
Opening a File
Starting with WindowsВ Vista, the Common File Dialog has been superseded by the Common Item Dialog when used to open a file. We recommend that you use the Common Item Dialog API instead of the Common File Dialog API. For more information, see Common Item Dialog.
This topic describes sample code that displays an Open dialog box so that a user can specify the drive, directory, and name of a file to open. The sample code first initializes an OPENFILENAME structure, and then calls the GetOpenFileName function to display the dialog box.
In this example, the lpstrFilter member is a pointer to a buffer that specifies two file name filters that the user can select to limit the file names that are displayed. The buffer contains a double-null terminated array of strings in which each pair of strings specifies a filter. The nFilterIndex member specifies that the first pattern is used when the dialog box is created.
This example sets the OFN_PATHMUSTEXIST and OFN_FILEMUSTEXIST flags in the Flags member. These flags cause the dialog box to verify, before returning, that the path and file name specified by the user actually exist.
The GetOpenFileName function returns TRUE if the user clicks the OK button and the specified path and file name exist. In this case, the buffer pointed to by the lpstrFile member contains the path and file name. The sample code uses this information in a call to the function to open the file.
Although this example does not set the OFN_EXPLORER flag, it still displays the default Explorer-style Open dialog box. However, if you want to provide a hook procedure or a custom template and you want the Explorer user interface, you must set the OFN_EXPLORER flag.
In the C programming language, a string enclosed in quotation marks is null-terminated.
Displaying the Print Dialog Box
This topic describes sample code that displays a Print dialog box so that a user can select options for printing a document. The sample code first initializes a PRINTDLG structure, and then calls the PrintDlg function to display the dialog box.
This example sets the PD_RETURNDC flag in the Flags member of the PRINTDLG structure. This causes PrintDlg to return a device context handle to the selected printer in the hDC member. You can use the handle to render output on the printer.
On input, the sample code sets the hDevMode and hDevNames members to NULL. If the function returns TRUE, these members return handles to DEVNAMES structures that contain the user input and information about the printer. You can use this information to prepare the output to be sent to the selected printer.
Using the Print Property Sheet
This topic describes sample code that displays a Print property sheet so that a user can select options for printing a document. The sample code first initializes a PRINTDLGEX structure, then calls the PrintDlgEx function to display the property sheet.
The sample code sets the PD_RETURNDC flag in the Flags member of the PRINTDLG structure. This causes the PrintDlgEx function to return a device context handle to the selected printer in the hDC member.
On input, the sample code sets the hDevMode and hDevNames members to NULL. If the function returns S_OK, these members return handles to DEVNAMES structures containing the user input and information about the printer. You can use this information to prepare the output to be sent to the selected printer.
After the printing operation has been completed, the sample code frees the DEVMODE, DEVNAMES, and PRINTPAGERANGE buffers and calls the DeleteDC function to delete the device context.
Setting Up the Printed Page
This topic describes sample code that displays a Page Setup dialog box so that a user can select the attributes of the printed page, such as the paper type, paper source, page orientation, and page margins. The sample code first initializes a PAGESETUPDLG structure, and then calls the PageSetupDlg function to display the dialog box.
This example sets the PSD_MARGINS flag in the Flags member and uses the rtMargin member to specify the initial margin values. It sets the PSD_INTHOUSANDTHSOFINCHES flag to ensure that the dialog box expresses margin dimensions in thousandths of an inch.
On input, the sample code sets the hDevMode and hDevNames members to NULL. If the function returns TRUE, the function uses these members to return handles to DEVNAMES structures containing the user input and information about the printer. You can use this information to prepare the output to be sent to the selected printer.
The following example also enables a PagePaintHook hook procedure to customize drawing the contents of the sample page.
The following example shows a sample PagePaintHook hook procedure that draws the margin rectangle in the sample page area:
Finding Text
This topic describes sample code that displays and manages a Find dialog box so that the user can specify the parameters of a search operation. The dialog box sends messages to the window procedure so you can perform the search operation.
The code for displaying and managing a Replace dialog box is similar, except that it uses the ReplaceText function to display the dialog box. The Replace dialog box also sends messages in response to user clicks on the Replace and Replace All buttons.
To use the Find or Replace dialog box, you must perform three separate tasks:
- Get a message identifier for the FINDMSGSTRING registered message.
- Display the dialog box.
- Process FINDMSGSTRING messages when the dialog box is open.
When you initialize your application, call the RegisterWindowMessage function to get a message identifier for the FINDMSGSTRING registered message.
To display a Find dialog box, first initialize a FINDREPLACE structure and then call the FindText function. Note that the FINDREPLACE structure and the buffer for the search string should be a global or static variable so that it does not go out of scope before the dialog box closes. You must set the hwndOwner member to specify the window that receives the registered messages. After you create the dialog box, you can move or manipulate it by using the returned handle.
When the dialog box is open, your main message loop must include a call to the IsDialogMessage function. Pass a handle to the dialog box as a parameter in the IsDialogMessage call. This ensures that the dialog box correctly processes keyboard messages.
To monitor messages sent from the dialog box, your window procedure must check for the FINDMSGSTRING registered message and process the values passed in the FINDREPLACE structure as in the following example.
Windows open file dialog box
A file is a series of bits of data that are arranged in a particular way to produce a usable document. For easy storage, location, and management, the bits are stored on a medium such as a hard disc, a floppy disc, a compact disc, or any valid and supported type of storage. When these bits belong to a single but common entity, the group is referred to as a file. For even greater management, files can be stored in a parent object called a directory or a folder. Since a file is a unit of storage and it stores information, it has a size which is the number of bits it contains. To manage it, a file also has a location also called a path that specifies where and/or how the file can be retrieved. Also, for better management, a file has attributes that indicate what can be done on a file or that provide specific information that the programmer or the operating system can use when dealing with the file.
File processing consists of creating, storing, and/or retrieving the contents of a file from a recognizable medium. For example, it is used to save word-processed files to a hard drive, to store a presentation on floppy disk, or to open a file from a CD-ROM. To perform file processing on VCL applications, you have four main choices, two derived from C and C++ languages, one or a few classes provided by the Visual Component Library, or use the Win32 API.
Characteristics of a File
In order to manage files stored in a computer, each file must be able to provide basic pieces of information about itself. This basic information is specified when the file is created but can change during the life time of a file.
To create a file, a user must first decide where it would be located: this is a requirement. A file can be located on the root drive. Alternatively, a file can be positioned inside of an existing folder. Based on security settings, a user may not be able to create a file just anywhere in the (file system of the) computer. Once the user has decided where the file would reside, there are various means of creating files that the users are trained to use. When creating a file, the user must give it a name following the rules of the operating system combined with those of the file system.
At the time of this writing, the rules for file names were on the MSDN web site at Windows Development\Windows Base Services\Files and I/O\SDK Documentation\Storage\Storage Overview\File Management\Creating, Deleting, and Maintaining Files\Naming a File (because it is a web site and not a book, its pages can change anytime). |
The most fundamental piece of information a file must have is a name. Once the user has created a file, whether the file is empty or not, the operating system assigns basic pieces of information to it. Once a file is created, it can be opened, updated, modified, renamed, etc.
Introduction to Common File Dialog Boxes
Because files on a computer can be stored in various places, Microsoft Windows provides various means of creating, locating, and managing files through objects called Windows Common Dialog Boxes. Indeed, these dialog boxes are part of the operating system and are equipped with all the necessary operations pertinent to their functionality. To support this, Borland C++ Builder ships these ready-made dialog boxes so that, instead of, or before creating a new commonly used dialog box, first find out if C++ Builder already provides an object that can do the job. The objects of C++ Builder are highly efficient and were tested enough to be reliable. This means that whenever possible, you should use them.
To use a standard Windows dialog box, from the Dialogs tab of the Component Palette, click the desired dialog’s button and click anywhere on the form. The position of the control on the form has no importance because it is only a representative. It will not appear when the form is running. Once the desired dialog’s icon is on the form, place a button that will be used to call the dialog. A dialog is called using the DialogName->Execute() method. You can find out what button the user clicked when closing the dialog, and act accordingly.
Practical Learning: Introducing Common Dialogs
- Start Borland C++ Builder or create a new project with its default form
- Save it in a new folder named FileProcess1
- Save the unit as Exercise and save the project as FileProc
- Change the Caption to File Processing
One of the most usual involvements with computer files consists of opening them for review or for any other reason the user judges appropriate. Microsoft Windows provides a convenient dialog box to handle the opening of files. The job is performed by using the Open File dialog box:
To provide the means of opening files, you can use the TOpenDialog class. The easiest way to use it is to click the OpenDialog button from the Dialogs tab of the Component Palette and click on the form. The OpenDialog icon can be positioned anywhere on the form because it would not be seen at run time. After placing it on the form, you can use the Object Inspector to configure it.
If you prefer to dynamically create an Open dialog box, declare a pointer to TOpenDialog and use the new operator to call its constructor and specify its owner. The technique is the same we applied for the TSaveDialog class. Here is an example:
Characteristics of an Open Dialog Box
One of the most important properties of an Open dialog box is the file it presents to the user. This is represented by the FileName property. If you want a default file to be specified when the dialog box comes up, you can specify this in the FileName property of the Object Inspector. If you need to use this property, you should make sure the file can be found. If the file is located in the same folder as the application, you can provide just its name. If the file is located somewhere in the hard drive, you should provide its complete path. Most of the time, you will not be concerned with this property if you are creating an application that will allow the user to open any file of her choice. Once a file is located, it can be accessed using the TOpenDialog::FileName property.
To make your application more effective, you should know what types of files your application can open. This is taken care by specifying a list of extensions for the application. To control the types of files that your application can open, specify their extensions using the Filter Property. The Filter string is created exactly like that of a SaveDialog control as we saw earlier.
Like the SaveDialog control, the default extension is the one the dialog box would first filter during file opening. If you want the Open File dialog to easily recognize a default type of file when the dialog box opens, you can specify the extension’s type using the DefaultExt property.
For convenience, or for security reasons, Open File dialog boxes of applications are sometimes asked to first look for files in a specific location when the Open File dialog box comes up. This default folder is specified using the InitialDir property.
The essence of using the Open File dialog box is to be able to open a file. This job is handled by the Execute() method which is easily called using a pointer to the OpenDialog object you are using.
Practical Learning: Using the Open Dialog Box
- On the Dialogs tab of the Component, click the OpenDialog button and click the form
- While the OpenDialog1 icon is still selected on the form, in the Object Inspector, click DefaultExt and type rtf
- Click Filter and click its ellipsis button
- Complete the Filter Editor dialog box as follows: