SHBrowseForFolder和快捷键

在我的C ++ Windows应用程序中,我有一个应该允许最终用户select文件夹的function。 我正在使用SHBrowseForFolder,它工作正常,除了文件夹快捷方式不显示在对话框中。

有谁知道是否有可能configurationSHBrowseForFolder,以便最终用户将能够导航文件夹快捷方式?

编辑:2010年5月24日,1:10 EST:

好吧,我要展示我迄今为止的代码。 我曾尝试使用在我的callback过程中使用BFFM_IUNKNOWNcallback的build议,但一直在努力弄清楚如何提供一个IFolderFilter后代工作。

1.被调用的代码:

Error CFolderChooserDialog::RunDialog() { Error runResult = kError_NotInitialized; if (VERIFYN(kLyndsey, m_ReferenceCount > 0)) { runResult = kError_Unexpected; m_AllFoldersFilter = new TAllFoldersFilter(); if (VERIFYN(kLyndsey, m_AllFoldersFilter)) { char selectedDirectoryBuffer[MAX_PATH]; m_DirectoryPath.CopyInto(selectedDirectoryBuffer); BROWSEINFO bi; memset(&bi, 0, sizeof(bi)); bi.hwndOwner = MyGetMainHWND(m_CBP); bi.pidlRoot = NULL; bi.pszDisplayName = selectedDirectoryBuffer; bi.lpszTitle = (const char*)m_Description; bi.ulFlags |= BIF_RETURNONLYFSDIRS; bi.ulFlags |= BIF_BROWSEINCLUDEFILES; bi.lpfn = SHBrowseForFolderCallbackProc; bi.lParam = (LPARAM)this; bi.iImage = 0; LPITEMIDLIST resultInfo = SHBrowseForFolder(&bi); if (resultInfo) { runResult = kError_NoError; if (SHGetPathFromIDList(resultInfo, selectedDirectoryBuffer)) { m_DirectoryPath = selectedDirectoryBuffer; } } else { runResult = kError_Failed; } delete m_AllFoldersFilter; m_AllFoldersFilter = nil; CoTaskMemFree(resultInfo); } } return runResult; } 

2.从SHBrowseForFolder调用的callback:

 int CALLBACK CFolderChooserDialog::SHBrowseForFolderCallbackProc(HWND window, UINT message, LPARAM messageValue, LPARAM clientData) { CFolderChooserDialog* thisPtr = (CFolderChooserDialog*)clientData; if (VERIFYN(kLyndsey, thisPtr)) { switch (message) { case BFFM_INITIALIZED: { if (!thisPtr->m_DialogTitle.IsEmpty()) { ::SetWindowText(window, (const char*) thisPtr->m_DialogTitle); } if (!thisPtr->m_DirectoryPath.IsEmpty()) { LPCTSTR startDirectory = thisPtr->m_DirectoryPath; ::SendMessage(window, BFFM_SETSELECTION, TRUE, (LPARAM)startDirectory); } break; } case BFFM_IUNKNOWN: { IUnknown* theInterface = (IUnknown*)messageValue; if (VERIFYN(kLyndsey, theInterface)) { IFolderFilterSite* filter = NULL; theInterface->QueryInterface(IID_IFolderFilterSite, (void**)&filter); if (VERIFYN(kLyndsey, filter)) { filter->SetFilter((IUnknown*)thisPtr->m_AllFoldersFilter); filter->Release(); } } break; } default: break; } } return 0; } 

3.应该为每个项目调用的IFolderFilter过滤进出对话框:

 class TAllFoldersFilter : public IFolderFilter { public: TAllFoldersFilter() { refCount = 0;} HRESULT STDMETHODCALLTYPE QueryInterface(const IID& iid, void** obj) { if (!obj) return E_INVALIDARG; *obj = NULL; if (iid == IID_IUnknown || iid == IID_IFolderFilter) { *obj = (void*)this; AddRef(); return NOERROR; } return E_NOINTERFACE; } ULONG STDMETHODCALLTYPE AddRef() { refCount++; return refCount; } ULONG STDMETHODCALLTYPE Release() { refCount--; return refCount; } HRESULT STDMETHODCALLTYPE GetEnumFlags(IShellFolder* sf, LPCITEMIDLIST pidlFolder, HWND* window, DWORD* flags) { return 0; } HRESULT STDMETHODCALLTYPE ShouldShow(IShellFolder* sf, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidlItem) { HRESULT resultCode = S_OK; ULONG attributes = 0UL; if (SUCCEEDED(sf->GetAttributesOf(1, &pidlItem, &attributes))) { if (attributes & SFGAO_FOLDER) { resultCode = S_OK; // Yes, I see the folders } else if (attributes & SFGAO_LINK) { resultCode = S_OK; // Yes, this shows the folder shortcut links, but I cannot explore them. When I "expand" them (click on the plus-sign-box), nothing happens. } } return resultCode; } protected: ULONG refCount; }; 

那么,我在哪里? 那么,我可以显示文件夹,我可以显示文件夹链接,但我不确定以下内容:

  1. 如何轻松确定我所拥有的项目是否是文件夹的快捷链接? 我写的代码绝对不是在看,并显示任何捷径链接。

  2. 我如何轻松地让最终用户钻研快捷链接所代表的文件夹?

  3. 这段代码是否正确,简单/干净?

感谢您所有的帮助!

编辑:2010年6月1日,美国东部时间2:14:答案在技术上提供,所以我会标记,我要问另一个问题,以帮助我解决这个代码。

Solutions Collecting From Web of "SHBrowseForFolder和快捷键"

我想你可以添加BIF_BROWSEINCLUDEFILES风格,然后过滤项目只显示文件夹和.lnk的文件夹(这是你是什么后?)

要过滤项目,您需要添加一个回调func到BROWSEINFO ,捕获BFFM_IUNKNOWN并查询IFolderFilterSite并设置一个过滤器

更好的答案是使用IFOSOpenDialog和FOS_PICKFOLDERS作为Windows Vista及更高版本的选项。