Create the OpenDlg Function

You need to create a dialog-box function to process the controls in the Open dialog box. When the dialog box is first displayed, the dialog function needs to fill the list box and the edit control, then give the input focus to the edit control and select the entire specification. If the user selects a filename in the list box, the dialog function should copy the name to the edit control. If the user clicks the Open button, the dialog function should retrieve the filename from the edit control and prepare to open the file. If the user double-clicks a filename in the list box, the dialog function should retrieve the filename, copy it to the edit control, and prepare to open the file.

Add the following function to your source file:

HANDLE FAR PASCAL OpenDlg(hDlg, message, wParam, lParam)

HWND hDlg;

unsigned message;

WORD wParam;

LONG lParam;

{

WORD index; /* index to the filenames in the list box */

PSTR pTptr; /* temporary pointer */

HANDLE hFile; /* handle to the opened file */

switch (message) {

case WM_COMMAND:

switch (wParam) {

case IDC_LISTBOX:

switch (HIWORD(lParam)) {

case LBN_SELCHANGE:

if (!DlgDirSelect(hDlg, str, IDC_LISTBOX)) {

SetDlgItemText(hDlg, IDC_EDIT, str);

SendDlgItemMessage(hDlg, IDC_EDIT,

EM_SETSEL,

NULL,

MAKELONG(0, 0x7fff));

}

else {

strcat(str, DefSpec);

DlgDirList(hDlg, str, IDC_LISTBOX,

IDC_PATH, 0x4010);

}

break;

case LBN_DBLCLK:

goto openfile;

} /* Ends IDC_LISTBOX case */

return (TRUE);

case IDOK:

openfile:

GetDlgItemText(hDlg, IDC_EDIT, OpenName, 128);

if (strchr(OpenName, '*') ||

strchr(OpenName, '?')) {

SeparateFile(hDlg, (LPSTR) str, (LPSTR) DefSpec,

(LPSTR) OpenName);

if (str[0])

strcpy(DefPath, str);

ChangeDefExt(DefExt, DefSpec);

UpdateListBox(hDlg);

return (TRUE);

}

if (!OpenName[0]) {

MessageBox(hDlg, “No filename specified.”,

NULL, MB_OK | MB_ICONQUESTION);

return (TRUE);

}

AddExt(OpenName, DefExt);

EndDialog(hDlg, NULL);

return(TRUE);

case IDCANCEL:

EndDialog(hDlg, NULL);

return(TRUE);

}

break;

case WM_INITDIALOG: /* Request to initalize */

UpdateListBox(hDlg);

SetDlgItemText(hDlg, IDC_EDIT, DefSpec);

SendDlgItemMessage(hDlg, /* dialog handle */

IDC_EDIT, /* where to send message */

EM_SETSEL, /* select characters */

NULL, /* additional information */

MAKELONG(0, 0x7fff)); /* Accept entire contents */

SetFocus(GetDlgItem(hDlg, IDC_EDIT));

return (FALSE); /* Indicates focus is set to a control */

}

return (FALSE);

}

When the dialog function receives the WM_INITDIALOG message, the SetDlgItemText function copies the initial filename to the edit control, and the SendDlgItemMessage function sends the EM_SETSEL message to the control in order to select the entire contents of the edit control for editing. The SetFocus function gives the input focus to the edit control. (The GetDlgItem function retrieves the window handle of the edit control.) The UpdateListBox function, given at the beginning of the WM_INITDIALOG case, is a locally defined function that fills the list box with a list of files in the current directory.

When the dialog function receives the WM_COMMAND message, it looks for three different values: IDC_LISTBOX, IDOK, and IDCANCEL.

For IDC_LISTBOX, the dialog function checks the notification-message type. If it is LBN_SELCHANGE, the dialog function retrieves the new selection using the DlgDirSelect function. It then copies the new filename to the edit control using the SetDlgItemText function and selects it for editing by sending a EM_SETSEL message. If the current selection is not a filename, the dialog function uses DlgDirList to copy the default specification to the list box. This fills the list box with all files in the current directory.

If the IDC_LISTBOX notification type is LBN_DBLCLK, the dialog function carries out the same action as for the IDOK case. A list box sends an LBN_DBLCLK message only after sending an LBN_SELCHANGE message. This means you do not have to retrieve the new filename when you receive a double-click notification.

For IDOK, the dialog function retrieves the contents of the edit control and checks the filename to see if it is valid. The strchr function searches for wildcard characters in the name. If it finds a wildcard character, it divides the filename into separate path and filename parts using the locally defined SeparateFile function. The strcpy function updates the DefPath variable with a new default path, if any. The locally defined ChangeDefExt function updates the DefExt variable with a new default filename extension, if any. After the default path, filename, and filename extension are updated, the UpdateListBox function updates the contents of the list box, and the dialog function returns to let the user select a valid filename from the new list.

If a filename has no wildcard characters, the dialog function makes sure the file is not empty. If it is empty, the dialog function displays a warning message, but does not terminate the dialog box. This lets the user try again. If the filename has no wildcards and the file is not empty, and if the user has entered a filename that does not have an extension, the dialog function uses the locally defined AddExt function to append the default filename extension. The dialog function then calls the EndDialog function to terminate the modal dialog box and sets the dialog-box return value to NULL.

For IDCANCEL, the dialog function calls the EndDialog function to terminate the dialog box and cancel the command. The return value is set to NULL.

The dialog function can also check the existence and access mode of the given file before terminating the dialog box. The existence check, not given in this example, is entirely up to the application. For information on simple ways of checking whether a file exists and is accessible, see Chapter 22, “File Input and Output.”