1

I put a TFileSaveDialog on a form in C++ Builder and set the options fdoOverWritePrompt, fdoStrictFileTypes, fdoPathMustExist, and fdoCreatePrompt.

When the dialog opens and I select an existing file, it prompts if I want to overwrite like it should. However, if I type in some random name that doesn't exist and click "Save", the dialog just closes - there is no confirmation prompt if it's okay to create one.

Any idea why that is happening?

AmigoJack
  • 5,234
  • 1
  • 15
  • 31
user3161924
  • 1,849
  • 18
  • 33

1 Answers1

4

OFN_CREATEPROMPT, corresponding to

is only honored for the Open dialog and never for the Save dialog. Try the same thing with a TFileOpenDialog and you get that prompt.

Proof for the other dialog types:

var
  sd: TSaveDialog;
  od: TOpenDialog;
begin
  sd:= TSaveDialog.Create( self );
  sd.Options:= [ofCreatePrompt];  // Has no effect: no typed-in filename triggers this
  sd.Execute();
  sd.Free;

  od:= TOpenDialog.Create( self );
  od.Options:= [ofCreatePrompt];  // When trying to OPEN a not yet existing file
  od.Execute();
  od.Free;

Why? Logic wise when saving a file in the majority of cases you want to create a new file (select a non-existing filename) anyway - why is there a need to confirm that again when you already have the "Save" button? Saving a file implies that a file is created. Confirming to overwrite/change an existing file is less common.

If you still want such a behavior you have to do it yourself: use the OnCanClose event and then check the filename being chosen/entered so far:

procedure TForm1.SaveDialog1CanClose(Sender: TObject; var CanClose: Boolean);
begin
  if not FileExists( SaveDialog1.FileName ) then begin
    // Reject closing the window for every choice but "Yes"
    CanClose:= MessageBox( SaveDialog1.Handle, 'Create it?', 'Does not exist yet', MB_YESNO )= IDYES;
  end;
end;
AmigoJack
  • 5,234
  • 1
  • 15
  • 31
  • 2
    Your answer mostly refers to old components, not the newer component the OP is using. `OFN_CREATEPROMPT` is a flag for the old `Get(Open|Save)FileName()` API that `T(Open|Save)Dialog` use. `TFile(Open|Save)Dialog` uses the newer `IFileDialog`/`IFile(Open|Save)Dialog` API instead, which has [`FOS_CREATEPROMPT`](https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/ne-shobjidl_core-_fileopendialogoptions). Also, `TFile(Open|Save)Dialog` do not have an `OnCanClose` event like `T(Open|Save)Dialog` do. The `CanClose` parameter is in the `OnFileOkClick` event instead. – Remy Lebeau Apr 20 '23 at 16:30
  • 1
    Other than that, your reasoning that a create prompt only applies to an OPEN dialog and not a SAVE dialog is correct. – Remy Lebeau Apr 20 '23 at 16:35
  • So the documentation is wrong. – Mike Versteeg Apr 23 '23 at 15:38
  • @MikeVersteeg yes. Embarcadero's documentation says: "*`fdoCreatePrompt` Prompt for creation if returned item **in save dialog** does not exist. This does not create the item.*" This is wrong. Microsoft's documentation says: "*`FOS_CREATEPROMPT` Prompt for creation if the item returned **in the open dialog** does not exist. Note that this does not actually create the item.*" This is correct. – Remy Lebeau Apr 23 '23 at 23:04