Я сталкиваюсь со странным (по крайней мере для меня) поведением при использовании диалогов «Общие элементы» в моем приложении 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, чтобы избежать возможных побочных эффектов с моим другим кодом, но это тоже не помогло.
Есть ли кто-то, кто имел такое же поведение и смог решить эту проблему?
Большое спасибо!