{"id":96425,"date":"2017-06-19T07:00:00","date_gmt":"2017-06-19T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=96425"},"modified":"2019-03-13T01:13:03","modified_gmt":"2019-03-13T08:13:03","slug":"20170619-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20170619-00\/?p=96425","title":{"rendered":"How do I set the initial directory of the File Open dialog to a virtual directory?"},"content":{"rendered":"<p>A customer reported that they had been setting the <code>lpstrInitialDir<\/code> member of the <code>OPENFILENAME<\/code> structure to <code>\"::{645FF040-5081-101B-9F08-00AA002F954E}\"<\/code> in order to have the dialog&#8217;s default directory be the Recycle Bin. (I am not making this up.) They reported that this stopped working in Windows Vista and wanted to know why, and what they can do about it. <\/p>\n<p>The <code>lpstrInitialDir<\/code> is supposed to be the name of a directory. Virtual folders are not directories. It so happened that virtual directories were accepted in Windows XP due to a bug: The file dialog uses the <code>Path&shy;Combine<\/code> function&sup1; to combine the current directory with the <code>lpstrInitialDir<\/code>. The <code>Path&shy;Combine<\/code> function checks whether the second parameter (<code>lpstrInitialDir<\/code>) is an absolute or relative path, and in Windows XP it had a bug that if the second parameter&#8217;s second character was a colon, then it assumed that the path was absolute. It did this without verifying that the first character was a letter. <\/p>\n<p>Windows Vista fixed this bug in the <code>Path&shy;Combine<\/code> function, which means that if you passed an <code>lpstrInitialDir<\/code> of <code>\"::{...}\"<\/code>, the function said, &#8220;Oh, you almost fooled me there, but I&#8217;m onto you. That is not an absolute path. So I will combine it with the first parameter (the current directory).&#8221; The file dialog then says, &#8220;Let&#8217;s go to that folder!&#8221;, but it can&#8217;t (because there is no folder called <code>::{...}<\/code> in the current directory), so it falls back to the Documents folder. <\/p>\n<p>That explains why the undefined behavior changed. But what&#8217;s the supported way of setting the initial directory to a virtual directory? <\/p>\n<p>You use the <code>IFile&shy;Dialog<\/code> interface, which gives you more control over the file open dialog than <code>OPENFILENAME<\/code> does. In particular, you can use the <code>IFile&shy;Dialog::<\/code><code>Set&shy;Default&shy;Folder<\/code> method. <\/p>\n<p>Here&#8217;s a Little Program to demonstrate. Remember that Little Programs do little to no error checking. Today&#8217;s smart pointer library is (rolls dice) nothing! We&#8217;re going to use raw pointers. <\/p>\n<pre>\n#define STRICT\n#define STRICT_TYPED_ITEMIDS\n#include &lt;windows.h&gt;\n#include &lt;shlobj.h&gt;\n#include &lt;knownfolders.h&gt;\n\nint WINAPI WinMain(\n    HINSTANCE hinst, HINSTANCE hinstPrev,\n    LPSTR lpCmdLine, int nShowCmd)\n{\n    <a HREF=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/\">CCoInitialize<\/a> init;\n\n    IFileDialog* pfd;\n    CoCreateInstance(CLSID_FileOpenDialog, nullptr,\n        CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&amp;pfd));\n\n    IShellItem* psi;\n    SHGetKnownFolderItem(FOLDERID_RecycleBinFolder,\n        KF_FLAG_DEFAULT, nullptr, IID_PPV_ARGS(&amp;psi));\n    pfd-&gt;SetDefaultFolder(psi);\n    psi-&gt;Release();\n\n    \/\/ ... other initialization goes here ...\n\n    pfd-&gt;Show(nullptr);\n\n    \/\/ ... process the results ...\n\n    pfd-&gt;Release();\n\n    return 0;\n}\n<\/pre>\n<p>We create the file open dialog and set its default folder to the Recycle Bin. In a real program, there would be additional initialization of the dialog, but in this Little Program, we&#8217;ll accept all the other defaults. We then show the dialog with no owner (because our program doesn&#8217;t have a main window). Observe that the default initial directory is the Recycle Bin. <\/p>\n<p>&sup1; The <code>Path&shy;Combine<\/cODE> function has been superseded by <a HREF=\"https:\/\/msdn.microsoft.com\/library\/windows\/desktop\/hh707085(v=vs.85).aspx\">the <code>Path&shy;Cch&shy;Combine<\/code> function<\/a> and its friends, which support NT-style paths and extra-long paths. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use the IFileDialog::SetDefaultFolder method.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-96425","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Use the IFileDialog::SetDefaultFolder method.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96425","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=96425"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/96425\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=96425"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=96425"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=96425"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}