The DlgDirList and DlgDirSelect Functions

You'll recall from working with list boxes in Chapter 6 that you can fill a list box with a list of files, subdirectories, and disk drives by sending the list box a message:

SendMessage (hwndList, LB_DIR, wAttr, (LONG) lpszFileSpec) ;

The wAttr parameter is an MS-DOS file attribute (with some additional bits to indicate the listing of subdirectories and disk drives), and lpszFileSpec is a far pointer to a filename specification such as ”*.*“.

Although this list box message is quite convenient, within a dialog box you can use an even more sophisticated function:

iStatus = DlgDirList (hDlg, lpszFileSpec, nIDList, nIDStatic, wAttr) ;

The nIDList parameter is the ID of the list box, and nIDStatic is the ID of a static text field. DlgDirList parses the string pointed to by lpszFileSpec to extract any disk drive or subdirectory information from it. It then changes the current disk drive or subdirectory using MS-DOS function calls.

DlgDirList sends an LB_DIR message to the list box indicated by nIDList to fill it with filenames meeting the file specification and the file attribute word. The current disk drive and subdirectory path are then displayed in the static text field whose ID is nIDStatic. When DlgDirList returns, the string pointed to by lpszFileSpec contains only the file specification without any drive or subdirectory. The function returns nonzero if it is successful and 0 otherwise. A 0 value usually indicates that the string pointed to by lpszFileSpec does not contain a valid drive or subdirectory.

For example, suppose that drive C has a directory named WINDOWS and that your dialog box procedure contains this code:

char szFileSpec [] = "C:\\WINDOWS\\*.TXT" ;

[other program lines]

DlgDirList (hDlg, szFileSpec, IDD_FLIST, IDD_FPATH, 0x4010) ;

When DlgDirList returns, the current disk drive and subdirectory for the instance of the program will have been changed to C:\WINDOWS. The list box whose ID is IDD_FLIST will list files with the extension .TXT, all subdirectories of the directory WINDOWS, and all valid disk drives. The static text field whose ID is IDD_FPATH will display the text C:\WINDOWS. The szFileSpec string array will contain ”*.TXT“. If either the nIDList or nIDStatic parameter is 0, however, DlgDirList will assume that the list box or static text field does not exist.

Both FileOpenDlgProc and FileSaveDlgProc use DlgDirList while processing the WM_INITDIALOG message. (In FileSaveDlgProc, DlgDirList is called with the nIDList parameter set to 0 because the dialog box does not contain a list box.)

SetDlgItemText is used to set the text of the edit control to the text file specification:

SetDlgItemText (hDlg, IDD_FNAME, szFileSpec) ;

This function does the same thing as the SetWindowText function or the WM_SETTEXT message. You can use the companion function GetDlgItemText to obtain the contents of the edit control.

FileOpenDlgProc also uses DlgDirSelect extensively. This function returns the currently selected string from a list box:

bDirectory = DlgDirSelect (hDlg, lpszString, nIDList) ;

The nIDList parameter is the ID of the list box. The currently selected string is copied to the character array pointed to by lpszString. If the return value is TRUE (nonzero), meaning that the string is either a disk drive or subdirectory name, DlgDirSelect removes the hyphens and brackets that appear when disk-drive letters and the subdirectory names are displayed in a list box. The function appends a colon to disk-drive letters and a backslash to subdirectory names when copying them to the lpszString array.

If DlgDirSelect returns a disk drive or directory, you can then append the default file specification (”*.TXT“, for instance) to the string and use that as the lpszFileSpec parameter to DlgDirList. DlgDirList will then change the drive or directory and update the static text field. The file specification pointed to by lpszFileSpec on return from DlgDirList can then be transferred to the edit control. If DlgDirSelect returns FALSE (0), meaning that lpszString contains a filename from the list box, then this filename can be transferred to the edit field directly.