11
votes

CFileDialog :: Parcourir les dossiers

Lorsque j'essaie d'instancier un objet cfiledialog , il affiche les dossiers et les fichiers. Comment créez-vous un cfiledialog qui navigue pour les dossiers seuls?


0 commentaires

7 Réponses :


11
votes

Vous ne pouvez pas le faire avec cfiledialog .

Soit vous utiliserez Fonction ShbrowseForFolderFefolder ou un wrapper Pour cela,
comme ColderDialog - Sélection des dossiers.


3 commentaires

shbrowseforforolder est fortement obsolète. Dès la remarque: "pour Windows Vista ou plus tard, il est recommandé d'utiliser ifiledialog avec l'option FOS_PICKLIDERS plutôt que la fonction shbrowseforFolderSolder. Cela utilise la boîte de dialogue Ouvrir des fichiers dans le mode de pick dossiers et est la mise en œuvre préférée."


Vous pouvez réellement, si vous êtes prêt à réimplément cfiledialog - voir ici .


@JUV, la question concerne l'affichage dans la boîte de dialogue uniquement les dossiers.



6
votes

À partir de Vista, il est recommandé d'utiliser ifiledialog avec l'option Fos_PickFolders ( Voir 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();


1 commentaires

Démarrer Visual Studio 2010 Cela ne fonctionnera pas. Utilisez cflderPickerDialog à la place ( msdn.microsoft.com/ ru-ru / bibliothèque / dd795962% 28v = vs.120% 29.asp x )



0
votes

me semble que la réponse que vous demandez est à l'intérieur du code de xxx

du fichier xxx

.

Si vous n'avez pas accès au code, je posterai la partie essentielle de celui-ci: xxx

comme vous le voyez, Microsoft elle-même n'utilise pas la classe CFileDialog. Lorsqu'il veut ouvrir une boîte de dialogue pour choisir des dossiers.

Pour utiliser le code comme celui-ci, votre classe d'application doit être dérivée de CWinappex, pas CWinApp


0 commentaires

16
votes

C'est très simple, vraiment.

Utilisez cflderPickerDialog qui est dérivé de la classe cfiledialog !


1 commentaires

Cette classe existe à partir de Visual Studio 2010. Nous venons de passer de VS2008 à VS2013 et iFILEOPENDIOG :: Seoptions (Fos_PickFolders) a surpreneusement cessé de fonctionner. IMHO C'est contre la compatibilité arriérée.



4
votes

Comme quelqu'un mentionné, utilisez cflderPickerDialog qui fonctionne bien. Je tiens à vous donner l'exemple de l'utiliser surtout lors de l'utilisation du drapeau multi-sélectionnel:

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);

        }
    }


0 commentaires

3
votes

À partir de Windows Vista, vous pouvez utiliser Dialogue d'élément commun .

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();
  }
  }


0 commentaires

0
votes

En réalité, il y a un moyen de faire cela - je l'ai trouvé dans CodeGuru: "Fichiers et dossiers sélectionnés dans CFileDialog"

Si vous êtes prêt à faire votre propre implémentation de CFileDialog, telle que: Classe CMYFileDialog: Publique CfileDialog Code> P>

Vous pouvez ajouter le code suivant et il devrait fonctionner (il est légèrement différent de la codeGURU Exemple ): p>

// This code overrides the OnNotify message of the CFileDialog
// and catches the CDN_SELCHANGE, this way you can also do 
// something with the selected folders.
BOOL CMyFileDialog::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    NMHDR* pNotificationParam = (NMHDR*)lParam;

    // Check that we got to the selection change notification.
    int code = pNotificationParam->code;
    if (code == CDN_SELCHANGE)
    {
        CStringArray theSelection;

        GetListControllSelectedItems(theSelection);

        // Do as you want with theSelection.
    }

    return CFileDialog::OnNotify(wParam, lParam, pResult);
}

// The following Code is accessing the selection in the CFileDialog
// and filling a string array with the selected names
BOOL CMyFileDialog::GetListControllSelectedItems(CStringArray& selectedItemNames)
{
    BOOL rc = FALSE;
    // Get the list control of the file dialog.
    CWnd* pParentWnd = GetParent();
    CWnd* pListControlWnd = pParentWnd->GetDlgItem(lst2);
    if (pListControlWnd) {

        // Get the selection from the list control.
        CListCtrl* pListCtrl = (CListCtrl*)(pListControlWnd->GetDlgItem(1));

        UINT selectionCount = pListCtrl->GetSelectedCount();

        // When there are items selected.
        if (selectionCount) {
            rc = TRUE;
            selectedItemNames.RemoveAll();
            POSITION itemPos = pListCtrl->GetFirstSelectedItemPosition();
            while (itemPos != NULL)
            {
                int itemNum = pListCtrl->GetNextSelectedItem(itemPos);
                CString currentItemName = pListCtrl->GetItemText(itemNum, 0);
                selectedItemNames.Add(currentItemName);
            }
        }
    }
    
    return rc;
}


0 commentaires