{"id":44303,"date":"2015-04-06T07:00:00","date_gmt":"2015-04-06T21:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2015\/04\/06\/opening-the-classic-folder-browser-dialog-with-a-specific-folder-preselected\/"},"modified":"2019-03-13T12:14:27","modified_gmt":"2019-03-13T19:14:27","slug":"20150406-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20150406-00\/?p=44303","title":{"rendered":"Opening the classic folder browser dialog with a specific folder preselected"},"content":{"rendered":"<p>Today&#8217;s Little Program shows how to set the initial selection in the <code>SHBrowse&shy;For&shy;Folder<\/code> dialog. <\/p>\n<p>The design of the <code>SHBrowse&shy;For&shy;Folder<\/code> function had a defect: The <code>BROWSEINFO<\/code> structure doesn&#8217;t have a <code>cbSize<\/code> member at the start. This means that the structure cannot ever change because <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2003\/12\/12\/56061.aspx\">the function would have no way of knowing whether you are calling with the old structure or the new one<\/a>. If it weren&#8217;t for this defect, setting the initial selection would have been easy: Add a <code>pidlInitialSelection<\/code> member to the structure and have people fill it in. <\/p>\n<p>Alas, any new functionality in the <code>SHBrowse&shy;For&shy;Folder<\/code> function therefore requires that the new functionality be expressed within the constraints of the existing structure. <\/p>\n<p>Fortunately, there&#8217;s a callback that takes a message number. <\/p>\n<p>The workaround, therefore, is to express any new functionalty in the form of new callback messages. <\/p>\n<p>And that&#8217;s how the ability to set the initial selection in the folder browser dialog came about. A new message <code>BFFM_INITIALIZED<\/code> was created, and in handling that message, the callback can specify what it wants the selection to be. <\/p>\n<pre>\n#define UNICODE\n#define _UNICODE\n#define STRICT_TYPED_ITEMIDS\n#include &lt;windows.h&gt;\n#include &lt;ole2.h&gt;\n#include &lt;oleauto.h&gt;\n#include &lt;shlobj.h&gt;\n#include &lt;stdio.h&gt; \/\/ horrors! Mixing C and C++!\n\nint CALLBACK Callback(\n    HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)\n{\n switch (uMsg) {\n case BFFM_INITIALIZED:\n  SendMessage(hwnd, BFFM_SETSELECTION, TRUE,\n              reinterpret_cast&lt;LPARAM&gt;(L\"C:\\\\Windows\"));\n  break;\n }\n return 0;\n}\n\nint __cdecl wmain(int, wchar_t **)\n{\n <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/05\/20\/135841.aspx\">CCoInitialize<\/a> init;\n TCHAR szDisplayName[MAX_PATH];\n BROWSEINFO info = { };\n info.pszDisplayName = szDisplayName;\n info.lpszTitle = TEXT(\"Pick a folder\");\n info.ulFlags = BIF_RETURNONLYFSDIRS;\n info.lpfn = Callback;\n PIDLIST_ABSOLUTE pidl = SHBrowseForFolder(&amp;info);\n if (pidl) {\n  SHGetPathFromIDList(pidl, szDisplayName);\n  wprintf(L\"You chose %ls\\n\", szDisplayName);\n  CoTaskMemFree(pidl);\n }\n return 0;\n}\n<\/pre>\n<p>We initialize COM and then call the <code>SHBrowse&shy;For&shy;Folder<\/code> function with information that includes a callback. The callback responds to the <code>BFFM_INITIALIZED<\/code> message by changing the selection. <\/p>\n<p>It&#8217;s not hard, but it&#8217;s a bit cumbersome. <\/p>\n<p>Sorry. <\/p>\n<p><b>Bonus chatter<\/b>: The presence of the callback means that the function cannot <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2014\/08\/11\/10548975.aspx#10549125\">shunt the work to a new thread when called from an MTA thread<\/a> because you are now stuck with the problem of which thread the callback should run on. <\/p>\n<ul>\n<li>The callback may want to access resources     that belong to the original thread,     so that argues for the callback being run on the original thraed. \n<li>The callback may also want to access resources inside the dialog box,     say in order to customize it.     That argues for the callback being run on the new thread. <\/ul>\n<p>You can&#8217;t have it both ways, so you&#8217;re stuck. <\/p>\n<p>But it doesn&#8217;t really matter, because you <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2008\/04\/24\/8420242.aspx\">shouldn&#8217;t be performing UI from a multi-threaded apartment anyway<\/a>. There&#8217;s not much point in making it easier for people to do the wrong thing. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Call me, honey.<\/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-44303","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Call me, honey.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/44303","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=44303"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/44303\/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=44303"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=44303"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=44303"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}