Home

VCL Controls: The Save Dialog Box

 

Files

 

Introduction

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.

Author Note 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 Practical Learning: Introducing Common Dialogs

  1. Start Borland C++ Builder or create a new project with its default form
  2. Save it in a new folder named FileProcess1
  3. Save the unit as Exercise and save the project as FileProc
  4. Change the Caption to File Processing

The Save As Dialog Box

 

Overview of the Save As Dialog Box

Most of the applications users open display an empty document. In other words, users are supposed to create files. Once a file has been created, a user would usually want to store the contents of that file on a media (hard drive, floppy disk, etc). Microsoft Windows provides a common dialog box for this purpose: The Save As dialog box:

The primary role of the Save As dialog box is to allow users to store a file on the hard drive of the computer, on a portable media such as a floppy disk, or on a network drive. To make this efficient and complete, the user must supply two valuable pieces of information: the location and the name of the file. The location of a file is also known as its path.

The name of a file follows the directives of the operating system. On MS DOS and Windows 3.X, it had to be in an 8.3 format. The actual name had to have a maximum of 8 characters with restrictions on the characters that could be used. The user also had to specify three characters after a period. The three characters, known as the file extension, were used by the operating system to classify the file. That was all necessary for those 8-bit and 16-bit operating systems.

Various rules have changed. For example, the names of folders and files on Microsoft Windows >= 95 can have up to 255 characters. The extension of the file is mostly left to the judgment of the programmer but the files are still using extensions. Applications can also be configured to save different types of files; that is, files with different extensions.
To use the Save As dialog box, users usually click an item under the File menu. Here is how it works for most regular applications. The user creates a new file. If the user wants to save the file, she can click File -> Save. If the file was not previously saved, the application would call the Save As dialog box. If a file is displaying, whether it was saved previously or not, the user can also click File -> Save As... which also would call the Save As dialog box.

Two objects are particularly important on the Save As dialog box: The Save In combo box and the File Name edit box or combo box (the File Name box is made of a combo box to make it user-friendly but over all, users hardly use the list side of this combo box). Since Windows 95, the user does not have to specify an extension if the programmer makes it easy. To help with this, the Save As dialog box is equipped with a Save As Type combo box. This combo box allows the user to select one of the extensions. The available extensions have to be created by the programmer so the user can select from this preset list. If the programmer neglects this, the user would have no extension to select from. Although the file can still be saved, the operating system would not associate it with a known type of file. Therefore, if you specify a series of extensions, the user can select one of these and, in the File Name box, she can simply type a name for the file. If the user does not specify an extension, the operating system would allocate the extension of the Save As Type combo box. Users of regular commercial applications, such as word processors, spreadsheet programs, or databases, etc, are usually trained not to care about the extensions and let the application deal with that detail. In some other circumstances, the users must pay close attention to the extension they give a file (this is common on web development or graphics design).

After working on a Save As dialog box, the user can click Save or press Enter, which would validate her entries. To change her mind, regardless of what she did on the Save As dialog box, she can click Cancel or press Esc, which would dismiss the dialog box and ignore what she did (in reality, some actions cannot be ignored, such as creating a new file or folder inside of the Save As dialog box, deleting, cutting, or pasting files, etc; but if the user clicked Cancel or pressed Esc, the new file would not be saved).

Save As Dialog Box Creation

In the VCL, the Save As dialog box is performed using the TSaveDialog class. To visually add a file saving capability to your application, on the Dialogs property page of the Component Palette, you can click the SaveDialog button and click on a form.

Alternatively, if you cannot add a SaveDialog control at design time, you can create one at run time when you need it in an event or a function. If you want the dialog box to be accessible to more than one event or function, you can declare a pointer to a TSaveDialog class. Here is an example:

private:
	AnsiString CurrentFile;
	TSaveDialog * dlgSave; // User declarations
public: // User declarations
	__fastcall TForm1(TComponent* Owner);
};

To make the control available to the form, you can initialize it in the constructor of the form as follows:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
	dlgSave = new TSaveDialog(Form1);
}
//---------------------------------------------------------------------------

Eventually, when the form closes, you can make sure the memory occupied by the control is freed by deleting the dynamic control. This can be done in the OnDestroy event of the form:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
	delete dlgSave;
	dlgSave = NULL;
}
//---------------------------------------------------------------------------

Characteristics of the Save As Dialog Box

To make sure that your application can open the allowed types of files for your application, depending on your goals, you should create a list of extensions that you want the users to be able to open. The allowed extensions form a group called a filter. The filter is like a funnel that selects the good items. For a text-based application, you may allow only text files, that is, files with a txt extension. For a rich text-based application, you may allow only Rich Text Format files, which are files with rtf extension. On the other hand, if you are creating an application for web files, you can allow as many file extensions as necessary, such as htm, html, php, asp, etc. As you may realize, text files or web files are all text-based files. This means that if you create a text-based or rich-text based application, you should allow the users to decide whether the file they are trying to open can be "read" by a text-based control. To provide this ability, you can specify an unknown extension specified as All Files.

To create a list of allowable extensions for your SaveDialog object, use the Filter property from the Object Inspector. At run time, you can create a list of file extensions as a string. If the Save dialog box will need only one extension, you can create the string using the following syntax:

Prompt|Extension

The Prompt is a section that defines what the user would see in the Save As Type combo box. An example would be 24-bit Bitmap. Such a string does not let the user know what actual extension the file would use. Therefore, as a courtesy, you can specify, between parentheses, the extension that would be applied if this extension is used. Therefore, the Prompt can be 24-bit Bitmap (*.bmp). In this case, the extension used would be bmp. The asterisk * lets the user know that whatever is provided as the file name would be used in place of the asterisk. The period indicates the separation from the file to its extension. This means that the characters on the left of the period would be the file name, the characters on the right side of the period would be used as the actual file extension.

To specify the extension that the operating system would use to associate to the file, you provide a second part of the string as Extension. In Microsoft Windows, most extensions are made of three characters. Some applications use a 2-letter extensions (for example Perl files have a pl extension) and some others use 4 letters (such as html for some HTML files). This depends on the programmer (or the company that is publishing the application). An example of a string the species an extension is:

24-bit Bitmap (*.bmp)|*.bmp

If you want to provide various extensions to your Save dialog box, you can separate them with a | symbol. An example would be:

HTML Files (*.htm)|*.htm|Active Server Pages (*.asp)|*.asp|Perl Script (*.pl)|*.pl

To make the extensions available to the SaveDialog control, you can assign the string to the Filter property. Here is an example:

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
	dlgSave = new TSaveDialog(Form1);
	dlgSave->Filter = "HTML Files (*.htm)|*.htm|"
			  "Active Server Pages (*.asp)|*.asp|"
			  "Apache Files (*.php)|*.php|"
			  "Perl Script (*.pl)|*.pl|"
			  "All Files";
}
//---------------------------------------------------------------------------

This would produce:

Once you know the types of files that your application will be dealing with, you can make your dialog box friendly by displaying the most likely extension for a document created using your application. For example, if you create a Memo-based application, users are more likely to create a text file with it. If you create a RichEdit-based application, users are more likely to create a Rich Text Format file with it. This most likely extension is known as the default extension, it allows the user not to specify an extension. By simply providing a file name and clicking Save, the operating system would associate the file with the default extension. Of course, if you create a filter, the user can specify a desired allowed extension.

To specify the default extension for your SaveDialog object, type the desired extension in the DefaultExt field of the Object Inspector.

If you had created a Filter and if you provide a default extension for a SaveDialog object, make sure it is one of the file extensions specified in the Filter list.

Microsoft Windows operating systems, especially since Windows 9X, are configured to have a default folder in which users are most likely to save their files. On Windows 9X, it is C:\My Documents. On Windows NT, it is usually specified by the network administrator. On Windows 2000 and Windows XP, it uses a more customized scenario. These settings are known to the operating system and you will usually not be concerned with them. In a rare circumstance, if you want to specify in which folder the users should save their files by default, you can provide it in the InitialDir property. This directory usually ends with \My Documents. If you want to find the path to the My Documents for a user, you can call the SHGetFolderPath(). Its syntax is:

HRESULT SHGetFolderPath(
	HWND hwndOwner,
	int nFolder,
	HANDLE hToken,
	DWORD dwFlags,
	LPTSTR pszPath
);

Here is an example:

//---------------------------------------------------------------------------
#include <vcl.h>
#include <shfolder.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	char strBuffer[MAX_PATH];
	SHGetFolderPath(NULL,
			CSIDL_PERSONAL,
			NULL,
			NULL,
			strBuffer);

	Edit1->Text = strBuffer;
}
//---------------------------------------------------------------------------

Once again, most of the time, you will not be concerned with this issue if you are creating an application for any user.

Probably the most important issue users care about, as far as they are concerned, is a name for the file they are trying to save. Users know that they can set the name of the file in the File Name box. To make their saving a little faster, you can provide a default name for a file in case a user does not want to specify a file name. This is done by typing a name in the FileName field of the Object Inspector. In practicality, the FileName value is the string that displays in the File Name box of the Save As dialog box.

Practical Learning Practical Learning: Using the Save As Dialog Box

  1. On the Dialogs tab of the Component Palette, click the SaveDialog button and click the form
  2. While the Save Dialog1 button is still selected on the dialog, in the Object Inspector, click the DefaultExt field and type rtf
  3. Click Filter and click its ellipsis button
  4. Complete the Filter Editor dialog box as follows:
     
  5. Click OK
  6. Click Title, type Save File As and press Enter
  7. Click an empty area on the form to select it
  8. In the Object Inspector, click the Events tab and double-click OnDblClick
  9. Implement the event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormDblClick(TObject *Sender)
    {
    	if( SaveDialog1->Execute() == True )
    	{
    		ShowMessage("The Save button was clicked or Enter key was pressed"
    			    "\nThe file would have been saved as " +
    			    SaveDialog1->FileName);
    	}
    	else
    		ShowMessage("The Cancel button was clicked or Esc was pressed");
    }
    //---------------------------------------------------------------------------
  10. Execute the application. To test the Save As dialog box, double-click anywhere on the form
     
  11. Close the application and return to Bcb
Home Copyright © 2005-2012, FunctionX, Inc.