Initial directory is not working for CFileDialog
Asked Answered
C

4

8

I am using CFileDialog, I have set the initial path like below , as shown in the code. It's not working . Correct me if I made a mistake.

   CFileDialog* filedlg = new CFileDialog(TRUE,(LPCTSTR)NULL ,  (LPCTSTR)NULL , OFN_HIDEREADONLY| OFN_ENABLESIZING , (LPCTSTR)NULL , FromHandle (hImgDlg) ,0 , FALSE  );

   filedlg ->m_ofn.lpstrInitialDir = "C:\\" ;

   if ( filedlg ->DoModal() == IDOK )
   {
       /***  do somthing here *****/
   }
Chamois answered 23/4, 2013 at 8:35 Comment(4)
What do you mean by "not working"? Do you get compiler errors? Runtime errors or crashes? The initial directory not what you expect it to be?Boles
Not showing the mentioned initial path it's automatically taken last selected path.Chamois
Are you on Windows 7 (or later), or on an earlier version of Windows?Boles
Another case to consider is when the lpstrInitialDir is set to a non-existent folder. In that case Windows7 defaults to the most recent folder.Caliphate
B
6

If you see the reference for the OPENFILENAME structure, you will see that for the lpstrInitialDir field it states that:

If lpstrInitialDir has the same value as was passed the first time the application used an Open or Save As dialog box, the path most recently selected by the user is used as the initial directory.

This means that the lpstrInitialDir field can really only be used the first time you use the dialog in a program. The rest of the time it will use the last directory selected by the user.

Boles answered 23/4, 2013 at 10:10 Comment(6)
Any other alternative API ?Chamois
@user948231 Not that I know of.Boles
Tanks you @joachim pileborgChamois
I just stumbled upon the same problem. I really wonder what kind of substance the guy responsible for this strange behaviour has smoked.Whippletree
Just got defect request to fix such a behavior in my program, but no idea how to.Rosabella
Other than making a dummy CFileDialog and getting its initial directory, is there any way of getting the aforementioned last directory used by the user?Fuentes
R
6

Two options: 1. Old-fashioned dialog style, specifying OFN::lpstrInitialDir

CFileLatinDialog dlg (TRUE, "", "" /*lpszFileName */,
   OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
   "All Files(*.*)|*.*||", this, 0,
   FALSE /*bVistaStyle*/);
dlg.m_ofn.lpstrInitialDir = "C:\\Models\\";
  1. Vista style dialog, specifying lpszFileName parameter
CFileLatinDialog dlg (TRUE, "", "C:\\Models\\" /*lpszFileName */,
   OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
   "All Files(*.*)|*.*||", this);
Rosabella answered 17/2, 2015 at 10:28 Comment(0)
O
5

If you set the filename location, you can get the dialog to open to a specific location. I would only use this if you really needed the folder location to open or if you have a default filename that you use.

CFileDialog* filedlg = new CFileDialog(TRUE, (LPCTSTR)NULL,  (LPCTSTR)_T("C:\\MyFolder\\DefaultFileName.ext"), OFN_HIDEREADONLY | OFN_ENABLESIZING, (LPCTSTR)NULL, FromHandle (hImgDlg), 0, FALSE);

or you could use the Windows function GetModuleFileName:

CString csAppFolder;
TCHAR szPath[MAX_PATH]; 

// form the path to where we want to store the file
if (GetModuleFileName(NULL, szPath, MAX_PATH))
{
    PathRemoveFileSpec(szPath);
    csAppFolder = szPath;
}

CFileDialog* filedlg = new CFileDialog(TRUE, (LPCTSTR)NULL, (LPCTSTR)(csAppFolder + _T("\\DefaultFileName.ext")), OFN_HIDEREADONLY | OFN_ENABLESIZING, (LPCTSTR)NULL, FromHandle (hImgDlg), 0, FALSE);
Oregon answered 28/4, 2014 at 16:21 Comment(4)
What you suggest is exactly the thing that doesn't work as expected on Windows 7.Whippletree
Then I must be doing something further that allows me to get the directory each time I open it. I don't know what that would be. But specifying the actual file name on instantiation works. Its in production and I only develop on Win 7. I wonder why it is working.Oregon
Why do you specify bVistaStyle=FALSE? In case of Vista Style dialog , specifying lpstrInitialDir helpsRosabella
I will have to give that a try, to see how that affects my app. Thanks.Oregon
P
0

I am a bit late to the party but just for anyone else who faces isssues. In my application multiple file dialogs are used in various places and for different purposes. So you are likely to be in different folders as a user when saving or loading a file. Hence it was a very bad user experience to always get the last used folder presented on the startup of any Dialog. After a lot of time wasting I finally find the docu on msdn which states it clearly:

Controlling the Default Folder

Almost any folder in the Shell namespace can be used as the default folder for the dialog (the folder presented when the user chooses to open or save a file). Call IFileDialog::SetDefaultFolder prior to calling Show to do so. The default folder is the folder in which the dialog starts the first time a user opens it from your application. After that, the dialog will open in the last folder a user opened or the last folder they used to save an item. See State Persistence for more details."*

State Persistence

Prior to Windows Vista, a state, such as the last visited folder, was saved on a per-process basis. However, that information was used regardless of the particular action. For example, a video editing application would present the same folder in the Render As dialog as it would in the Import Media dialog. In Windows Vista you can be more specific through the use of GUIDs. To assign a GUID to the dialog, call iFileDialog::SetClientGuid.

And that was all I needed. SetDefaultFolder for the first time opening for a user + SetClientGuid so that each instance remembers their own location, for each other opening.

IFileOpenDialog* dlg = fileDialog->GetIFileOpenDialog(); // fileDialog == CFileDialog*
if (dlg) 
dlg->SetClientGuid({0x6666a009, 0x6251, 0x4132, 0x23, 0xa5, 0xd4, 0x6, 0x69, 0xc2, 0x89, 0xf}); 
//new GUID for each different Dialog

This means OP could try to create and assign a new GUID on each opening to make sure that the initial DIR is always used. This feels more like a workaround though, but I wanted to point out the connection of the GUID and the initial DIR with my answer. For my purpose, seperating each different Dialog by a single GUID was enough. If the user really navigates somewhere else for a certain action then they probably know what they are doing and will end up in their folder of choice again on the next opening for the same action(dialog).

Pressurize answered 28/6 at 11:42 Comment(4)
This is an answer to a different question.Neumark
Not really. This is the way to give your Dialog it's own remembering of selected paths. To reach what OP wants: Just Generate a GUID on each opening and assign it => New GUID => Initial dir will be used. Tell me another proper solution for this, if you know.Pressurize
"Tell me another proper solution for this, if you know." - I don't know of a competing solution to this problem. But that is not what the question is asking for. It's asking specifically why passing "C:\\" as the lpstrInitialDir doesn't open the dialog in the "C:\" directory. This proposed answer doesn't address this specific issue.Neumark
It does not open it in C:// because the GUID is NULL. Thus taking the commonly shared remebered last opened Dialog path. Dont understand why you try Hard to unsee this. New guid => C: will be taken.Pressurize

© 2022 - 2024 — McMap. All rights reserved.