Lorsque j'essaie d'instancier un objet cfiledialog code>, il affiche les dossiers et les fichiers. Comment créez-vous un
cfiledialog code> qui navigue pour les dossiers seuls? p>
7 Réponses :
Vous ne pouvez pas le faire avec cfiledialog code>.
Soit vous utiliserez Fonction ShbrowseForFolderFefolder ou un wrapper Pour cela,
comme ColderDialog - Sélection des dossiers. p>
shbrowseforforolder code> 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." je>
Vous pouvez réellement, si vous êtes prêt à réimplément cfiledialog code> - voir ici .
@JUV, la question concerne l'affichage dans la boîte de dialogue uniquement les dossiers.
À 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();
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 )
me semble que la réponse que vous demandez est à l'intérieur du code de du fichier p> . p > Si vous n'avez pas accès au code, je posterai la partie essentielle de celui-ci: p> 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. P> Pour utiliser le code comme celui-ci, votre classe d'application doit être dérivée de CWinappex, pas CWinApp P> P>
C'est très simple, vraiment. p>
Utilisez cflderPickerDialog code>
qui est dérivé de la classe cfiledialog code>! p>
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.
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); } }
À 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(); } }
En réalité, il y a un moyen de faire cela - je l'ai trouvé dans Si vous êtes prêt à faire votre propre implémentation de CFileDialog, telle que:
Vous pouvez ajouter le code suivant et il devrait fonctionner (il est légèrement différent de la codeGURU Exemple ): p> Classe CMYFileDialog: Publique CfileDialog Code> 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;
}