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