Changing extension in Save Dialog (Views: 100)


How can I make the Save dialog automatically change the file extension of the filename when the user selects a different Filter?


The solution to this problem is to handle the OnTypeChange event of the TSaveDialog and directly send a message to the dialog. Start by assigning an event handler for the OnTypeChange event (this is called whenever the user selects a different filter in the dialog). Delphi keeps track of which FilterIndex is currently selected even when the dialog is open, so we can write the following code:

procedure TForm1.SaveDialogTypeChange(Sender: TObject);
  buf: array[0..MAX_PATH] of char;
  S: string;
  od: TSaveDialog;
  H: THandle;
  // get a pointer to the dialog
  od := (Sender as TSaveDialog);
  // Send the message to the dialogs parent so it can handle it the normal way
  H := GetParent(od.Handle);
  // get the currently entered filename
  SendMessage(H, CDM_GETSPEC, MAX_PATH, integer(@buf));
  S := buf;
  // change the extension to the correct one
  case od.FilterIndex of
      S := ChangeFileExt(S, '.rtf');
      S := ChangeFileExt(S, '.html');
      S := ChangeFileExt(S, '.txt');
  // finally, change the currently selected filename in the dialog
  SendMessage(H, CDM_SETCONTROLTEXT, edt1, integer(PChar(S)));

In the example, I have three filters for RTF, HTML and TXT and the code changes the extension to the correct one simply by calling ChangeFileExt on the existing filename. The CDM_* constants are defined in CommDlg.pas, so you must add this to your uses clause (or redeclare them in your unit). The constant edt1 is taken from the file Dlgs.pas where every constant used in the common dialogs are listed. edt1 is the first edit control on any common dialog, edt2 the second etc.

<< Back to main page