2012-01-13 121 views
2

在Windows 7或Vista上運行的MFC Windows應用程序中使用Common Item對話框時,我面臨一些奇怪的問題(至少對我而言)。在Windows 7上使用IFileDialog的問題

按照MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx我使用新接口來顯示文件打開和保存對話框:

bool OpenFileDialog(CString& strFile, CString strTitle, CStringArray& astrFilter, CStringArray& astrFilterExtension, ULONG nFlags, HWND hParentWnd) 
{ 
USES_CONVERSION; 

INT_PTR nResult = 0; 
INT_PTR nFilterCount = astrFilter.GetCount(); 

IFileDialog* pfod = 0; 
HRESULT hr = ::CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfod)); 

if(SUCCEEDED(hr)) 
{ 
    // New dialog starting with Vista/Windows 7 
    COMDLG_FILTERSPEC* pOpenTypes = 0; 

    if((nFilterCount > 0) && (nFilterCount == astrFilterExtension.GetCount())) 
    { 
     pOpenTypes = new COMDLG_FILTERSPEC[nFilterCount]; 

     for(int nIdx = 0; nIdx < nFilterCount; nIdx++) 
     { 
      pOpenTypes[nIdx].pszName = astrFilter[nIdx].GetBuffer(); 
      pOpenTypes[nIdx].pszSpec = astrFilterExtension[nIdx].GetBuffer(); 
     } 
    } 

    // Set the file types to display. 
    if(pOpenTypes) 
    { 
     hr = pfod->SetFileTypes(nFilterCount, pOpenTypes); 

     if(SUCCEEDED(hr)) 
      hr = pfod->SetFileTypeIndex(0); 
    } 

    if(!strFile.IsEmpty()) 
     pfod->SetFileName(strFile); 

    if(!strTitle.IsEmpty()) 
     pfod->SetTitle(strTitle); 

    if(SUCCEEDED(hr)) 
    { 
     // Ensure the dialog only returns file system paths. 
     DWORD dwFlags; 
     hr = pfod->GetOptions(&dwFlags); 

     if(SUCCEEDED(hr)) 
     { 
      dwFlags |= FOS_FORCEFILESYSTEM; 

      if(nFlags & OFN_FILEMUSTEXIST) 
       dwFlags |= FOS_FILEMUSTEXIST; 

      if(nFlags & OFN_PATHMUSTEXIST) 
       dwFlags |= FOS_PATHMUSTEXIST; 

      hr = pfod->SetOptions(dwFlags); 

      if(SUCCEEDED(hr)) 
      { 
       // Create an event handling object, and hook it up to the dialog. 
       IFileDialogEvents* pfde = NULL; 
       DWORD dwCookie; 

       // Actually only added for debugging purposes 

       /*hr = CDialogEventHandler_CreateInstance(IID_PPV_ARGS(&pfde)); 

       if(SUCCEEDED(hr)) 
       { 
        // Hook up the event handler. 
        hr = pfod->Advise(pfde, &dwCookie); 

        if(!SUCCEEDED(hr)) 
        { 
         pfde->Release(); 
         pfde = 0; 
        } 
       }*/ 

       // Now show the dialog. Usually called with hParent == 0 
       if(hParentWnd) 
        hr = pfod->Show(::GetWindow(hParentWnd, GW_OWNER)); 
       else 
        hr = pfod->Show(0); 

       // do something with the path when the dialog was closed... 

所以出現的對話框中,如果我要選擇一個正常的驅動文件工作正常。我可以瀏覽文件夾並選擇任何我想要的文件。在離開對話框時我也會得到正確的文件信息。

但它不適用於左側導航窗格中的某個庫。每當我嘗試選擇文檔,視頻或圖片等庫時,對話框不會更新顯示文件夾/庫內容的右窗格。

我注意到,在文件打開/保存對話框中單擊庫時,IFileDialogEvents接口的OnFolderChanging()事件被觸發,但OnFolderChange()和OnSelectionChange()不是。如果我點擊並導航像「C」這樣的「普通」驅動器,則會觸發這些事件。我也嘗試在InitInstance方法的早期調用對話框以避免可能的副作用,但是這並不能幫助您無論是。

有沒有人有同樣的行爲,並能夠解決這個問題?

非常感謝!

+0

你準確設置了哪些選項?你可以在'CoCreateInstance()'和'Show()'之間顯示你的完整代碼嗎? – 2012-01-13 21:09:48

+0

@ RemyLebeau-TeamB嗨,我在調用Show()之前添加了代碼,感謝您的關注! – Fluffi1974 2012-01-14 12:33:40

+0

自從至少VS2008以來,這在MFC中已得到很好的支持,其中包括來自OFN標誌的映射。保持你的工具更新,以避免編寫這樣的代碼。 – 2012-01-14 13:30:03

回答

1

所以我終於找到了這個問題的答案。爲應用程序創建新的MFC項目是解決此問題的實際提示。原因是「堆棧儲備規模」太大。舊VS6.0項目中的設置將堆棧大小增加到100MB以上。顯然,當保留的堆棧大小太大時,基於IFileDialog的對話框不能正常工作(其他的東西也可能無法按預期工作)。所以我不得不將它重新設置爲15MB。