在Windows 7上使用IFileDialog的问题

时间:2012-01-13 19:17:27

标签: c++ mfc

在Windows 7或Vista上运行的MFC Windows应用程序中使用Common Item Dialogs时,我面临一些奇怪的行为(至少对我而言)。

根据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方法中尽早调用对话框,以避免可能的副作用与我的其他代码,但这也没有帮助。

是否有人有相同的行为并且能够解决这个问题?

非常感谢!

1 个答案:

答案 0 :(得分:1)

所以我终于找到了这个问题的答案。为应用程序创建新的MFC项目是解决此问题的实际提示。原因是“堆栈储备规模”太大了。旧的VS6.0项目中的设置使堆栈大小增加到100MB以上。显然,当保留的堆栈大小太大时,基于IFileDialog的对话框无法正常工作(其他东西可能也不能按预期工作)。所以我不得不把它设置回15MB。