2009-08-20 12 views
5

Quando si tenta di istanziare un oggetto CFileDialog, mostra sia le cartelle che i file. Come si crea un CFileDialog che cerca solo le cartelle?CFileDialog :: Sfoglia cartelle

Grazie ...

risposta

4

A partire da Vista si consiglia di utilizzare IFileDialog con l'opzione FOS_PICKFOLDERS (see msdn):

CFileDialog od(TRUE/*bOpenFileDialog*/, NULL, NULL, 
     OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT , NULL, NULL, 0, 
     TRUE/*bVistaStyle*/); 
    IFileOpenDialog * openDlgPtr = od.GetIFileOpenDialog(); 
    if (openDlgPtr != NULL) 
    { 
     openDlgPtr->SetOptions(FOS_PICKFOLDERS); 
     openDlgPtr->Release(); 
    } 

    od.DoModal(); 
+0

L'avvio di Visual Studio 2010 non funzionerà. Utilizzare invece CFolderPickerDialog (https://msdn.microsoft.com/ru-ru/library/dd795962%28v=vs.120%29.aspx) – BlackBada

0

mi sembra la risposta che stai chiedendo è all'interno del codice di

CMFCPropertyGridFileProperty::OnClickButton(CPoint /*point*/) 

del

<Your Visual Studio installation folder>\VC\atlmfc\src\mfc\afxpropertygridctrl.cpp 

file.

Se non si ha accesso al codice, mi post la parte essenziale di esso:

CString strPath = m_varValue.bstrVal; 
BOOL bUpdate = FALSE; 

if (m_bIsFolder) 
{ 
    if (afxShellManager == NULL) 
    { 
     CWinAppEx* pApp = DYNAMIC_DOWNCAST(CWinAppEx, AfxGetApp()); 
     if (pApp != NULL) 
     { 
      pApp->InitShellManager(); 
     } 
    } 

    if (afxShellManager == NULL) 
    { 
     ASSERT(FALSE); 
    } 
    else 
    { 
     bUpdate = afxShellManager->BrowseForFolder(strPath, m_pWndList, strPath); 
    } 
} 
else 
{ 
    CFileDialog dlg(m_bOpenFileDialog, m_strDefExt, strPath, m_dwFileOpenFlags, m_strFilter, m_pWndList); 
    if (dlg.DoModal() == IDOK) 
    { 
     bUpdate = TRUE; 
     strPath = dlg.GetPathName(); 
    } 
} 

Come si vede, la stessa Microsoft non utilizza la classe CFileDialog quando vuole aprire una finestra di dialogo per la raccolta cartelle.

Per utilizzando il codice del genere, la classe di applicazione deve essere derivato dal CWinAppEx, non CWinApp

4

E 'molto semplice, davvero. Utilizzare CFolderPickerDialog derivato dalla classe CFileDialog!

+1

Questa classe esiste a partire da Visual Studio 2010. siamo passati da VS2008 a VS2013 e IFileOpenDialog :: SetOptions (FOS_PICKFOLDERS) hanno sorprendentemente smesso di funzionare. IMHO è contro la retrocompatibilità. – BlackBada

0

Come qualcuno menzionato, utilizzare CFolderPickerDialog che funziona benissimo. Vorrei darvi esempio come usarlo soprattutto quando si utilizza il prescelto bandiera a più:

CFolderPickerDialog folderPickerDialog(initialFolder, OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_ENABLESIZING, this, 
     sizeof(OPENFILENAME)); 

    CString folderPath; 

    if (folderPickerDialog.DoModal() == IDOK) 
    { 

     POSITION pos = folderPickerDialog.GetStartPosition(); 

     while (pos) 
     { 
      folderPath = folderPickerDialog.GetNextPathName(pos); 

     } 
    } 
1

a partire da Windows Vista, è possibile utilizzare il Common Item Dialog.

void CQiliRegrvDlg::OnBnClickedSelectDir() 
{ 
HRESULT hr = S_OK; 

// Create a new common open file dialog. 
IFileOpenDialog *pfd = NULL; 
hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, 
    IID_PPV_ARGS(&pfd)); 
if (SUCCEEDED(hr)) 
{ 
    // Set the dialog as a folder picker. 
    DWORD dwOptions; 
    hr = pfd->GetOptions(&dwOptions); 
    if (SUCCEEDED(hr)) 
    { 
     hr = pfd->SetOptions(dwOptions | FOS_PICKFOLDERS); 
    } 

    // Set the title of the dialog. 
    if (SUCCEEDED(hr)) 
    { 
     hr = pfd->SetTitle(L"Folder"); 
    } 
    // Show the open file dialog. 
    if (SUCCEEDED(hr)) 
    { 
     hr = pfd->Show(m_hWnd); 
     if (SUCCEEDED(hr)) 
     { 
      // Get the selection from the user. 
      IShellItem *psiResult = NULL; 
      hr = pfd->GetResult(&psiResult); 
      if (SUCCEEDED(hr)) 
      { 
       PWSTR pszPath = NULL; 
       hr = psiResult->GetDisplayName(SIGDN_FILESYSPATH, &pszPath); 
       if (SUCCEEDED(hr)) 
       { 
        m_appDir = pszPath; 
        SetDlgItemText(IDC_STATIC, m_appDir); 
        CoTaskMemFree(pszPath); 
       } 
       psiResult->Release(); 
      } 
     } 
    } 

    pfd->Release(); 
    } 
    }