Проблемы с использованием IFileDialog в Windows 7 - PullRequest
2 голосов
/ 13 января 2012

Я сталкиваюсь со странным (по крайней мере для меня) поведением при использовании диалогов «Общие элементы» в моем приложении MFC для Windows, работающем в Windows 7 или Vista.

Согласно 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...

Таким образом, диалоговое окно появляется и работает нормально, если я хочу выбрать файл с обычного диска. Я могу перемещаться по папкам и выбирать любой файл, который я хочу. При выходе из диалогового окна я также получаю правильную информацию о файле.

Но это не работает для одной из библиотек в навигационной панели слева. Всякий раз, когда я пытаюсь выбрать библиотеку, такую ​​как «Документы», «Видео» или «Изображения», диалоговое окно не обновляет правую панель, которая показывает содержимое папки / библиотеки.

Что я заметил, так это то, что при нажатии на кнопку «Библиотека» в диалоговом окне открытия / сохранения файла вызывается событие OnFolderChanging () интерфейса IFileDialogEvents, а не OnFolderChange () и OnSelectionChange (). Эти события запускаются, если я нажимаю и перемещаюсь по «обычному» диску, например C.

Я также пытался вызывать диалоговые окна в начале моего метода InitInstance, чтобы избежать возможных побочных эффектов с моим другим кодом, но это тоже не помогло.

Есть ли кто-то, кто имел такое же поведение и смог решить эту проблему?

Большое спасибо!

1 Ответ

1 голос
/ 30 августа 2012

Итак, я наконец-то нашел ответ на этот вопрос.Создание нового проекта MFC для приложения было реальным намеком на решение этой проблемы.Причина была в том, что «резервный размер стека» был слишком велик.В настройках старого проекта VS6.0 размер стека был увеличен до более чем 100 МБ.По-видимому, диалоговые окна на основе IFileDialog не работают должным образом, когда зарезервированный размер стека просто слишком велик (другое может работать не так, как ожидается).Поэтому в моем случае мне пришлось установить значение 15 МБ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...