How to get OpenDialog to change the current directory when a file is selected?

464 Views Asked by At

I have ported a C++Builder 6 application to compile with C++Builder 11.

One issue I have found in testing is that the TOpenDialog behaves differently between the two versions.

The C++Builder 6 version changes the current directory when Open is clicked while the C++Builder 11 version leaves the current directory unchanged.

I have tried setting the OpenDialog Options to ensure that they do not include ofNoChangeDir but this makes no difference.

Both C++Builder 6 and 11 versions are running on Windows 10.

I would like to make the C++Builder 11 version change the current directory on Open so that everything downstream will work in the same way, but so far through clearing and setting options I have had no luck.

I could just change the current directory after OpenDialog->Execute() returns but this seems a bit cludgy when there are Options that should dictate the dialog behavior.

// Check the current directory before and after the OpenDialog executes ...
String CurrentDirectory = GetCurrentDir();

OpenDialog1->Options.Clear();
OpenDialog1->Options << ofHideReadOnly << ofEnableSizing;  // seems to be the default

if (OpenDialog1->Execute())
{
  // do whatever
}

CurrentDirectory = GetCurrentDir(); // no change!? :|
1

There are 1 best solutions below

2
Remy Lebeau On

The difference in behavior is because the two versions are using different Win32 APIs under the hood.

In C++Builder 6, TOpenDialog uses GetOpenFileNameA(), which has an OFN_NOCHANGEDIR flag that IS NOT enabled by default, hence the working directory changes unless ofNoChangeDir is specified in the Options.

Whereas in C++Builder 11, TOpenDialog uses IFileOpenDialog 1 on Vista+, which has a FOS_NOCHANGEDIR flag that IS enabled by default, hence the working directory does not change. However, TOpenDialog disables FOS_NOCHANGEDIR if ofNoChangeDir is not specified in the Options. It's possible that the dialog is ignoring this for safety reasons, though. So, in your situation, it is best to just set the working directory yourself after TOpenDialog::Execute() exits. 2

1: on pre-Vista systems, or under certain configurations that the VCL can't support using IFileOpenDialog, TOpenDialog will use GetOpenFileNameW() instead - but that will just use IFileOpenDialog internally on Vista+.

2: you really shouldn't be relying on the working directory to begin with. There are other factors that can change the working directory at runtime. You should always use absolute paths only.