在我的C++ Windows應用程序中,我有一個應該允許最終用戶選擇文件夾的功能。我正在使用SHBrowseForFolder,它工作正常,除了文件夾快捷方式沒有顯示在對話框中。SHBrowseForFolder和快捷方式
有誰知道是否可以配置SHBrowseForFolder,以便最終用戶能夠導航文件夾快捷方式?
編輯:2010年5月24日,美國東部時間1:10:
好了,我要呈現什麼我到目前爲止的代碼。我曾嘗試使用在我的回調過程中放置BFFM_IUNKNOWN回調的建議,但一直在努力弄清楚如何提供可用的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回調:
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;
};
那麼,我在哪裏?好吧,我可以顯示文件夾,我可以顯示文件夾中的鏈接,但我不確定以下:
如何輕鬆地確定我是否有該項目是一個快捷方式鏈接到一個文件夾?我寫的代碼絕對不是看這個,並顯示任何捷徑鏈接。
我該如何輕鬆讓最終用戶將轉換成快捷方式鏈接所代表的文件夾?
這段代碼是否正確並且儘可能簡單/乾淨?
感謝您的幫助!
編輯:2010年6月1日:美國東部時間2:14: 在技術上提供的答案,所以我會標記出,我要問一個問題,幫我解決這個問題的代碼。
用一些代碼更新您的問題,特別是您選擇的選項。 – 2010-05-17 20:58:43
我用代碼更新了這個問題。感謝Hans。 – 2010-05-24 18:06:57