各种风格的目录/文件夹选择对话框(CFolderDialog)
?
1. 标准的文件夹选择对话框:可以使用在非MFC程序中,调用的标准API SHBrowserForFolder。
源码:
#include "shlobj.h"#include <STRING>// Function name : GetFolder// Description : Open and get Folder Dialog.// Return type : true means click ok, false mean no select and cancel.// Argument : folder path reference// Argument : dialog window caption// Argument : parent window handlebool GetFolder(std::string& folderpath, const char* szCaption = NULL, HWND hOwner = NULL){bool retVal = false;// The BROWSEINFO struct tells the shell// how it should display the dialog.BROWSEINFO bi;memset(&bi, 0, sizeof(bi));bi.ulFlags = BIF_USENEWUI;bi.hwndOwner = hOwner;bi.lpszTitle = szCaption;// must call this if using BIF_USENEWUI::OleInitialize(NULL);// Show the dialog and get the itemIDList for the selected folder.LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);if(pIDL != NULL){// Create a buffer to store the path, then get the path.char buffer[_MAX_PATH] = {'\0'};if(::SHGetPathFromIDList(pIDL, buffer) != 0){// Set the string value.folderpath = buffer;retVal = true;}// free the item id listCoTaskMemFree(pIDL);}::OleUninitialize();return retVal;}?
调用:
std::string szPath("");if (GetFolder(szPath, "Select a folder.") == true){printf("You selected: \"%s\".\n", szPath.c_str());}else{printf("No folder selected!\n");}?
界面:
?
?
?
2. 带导航栏的文件夹选择对话框:只在MFC程序中使用,从MFC的CFileDialog派生。
源码-头文件-Folder_dialog.h:
#pragma once// CFolderDialog dialogclass CFolderDialog : public CFileDialog{ DECLARE_DYNAMIC(CFolderDialog)public: CFolderDialog(CString* pPath, CWnd* pParentWnd = NULL); static WNDPROC m_wndProc; CString* m_pPath;protected: DECLARE_MESSAGE_MAP()private: virtual void OnInitDone(); virtual void OnFileNameChange(); virtual void OnFolderChange(); void ChangeFolder();};?
源码-Folder_dialog.cpp:
#include "stdafx.h"#include "folder_dialog.h"#include <DLGS.H>#include <WINUSER.H>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif// CFolderDialogIMPLEMENT_DYNAMIC(CFolderDialog, CFileDialog)WNDPROC CFolderDialog::m_wndProc = NULL;// Function name : CFolderDialog::CFolderDialog// Description : Constructor// Return type :// Argument : CString* pPath ; represent string where selected folder wil be savedCFolderDialog::CFolderDialog(CString* pPath, CWnd* pParentWnd) : CFileDialog(true, NULL, _T("*..*"), 6UL, NULL, pParentWnd){ m_pPath = pPath;}BEGIN_MESSAGE_MAP(CFolderDialog, CFileDialog)END_MESSAGE_MAP()// Function name : WindowProcNew// Description : Call this function when user navigate into CFileDialog.// Return type : LRESULT// Argument : HWND hwnd// Argument : UINT message// Argument : WPARAM wParam// Argument : LPARAM lParamLRESULT CALLBACK WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ if(message == WM_COMMAND) { if(HIWORD(wParam) == BN_CLICKED) { if(LOWORD(wParam) == IDOK) { if(CFileDialog* pDlg = (CFileDialog*)CWnd::FromHandle(hwnd)) { TCHAR path[MAX_PATH]; GetCurrentDirectory(MAX_PATH, path); *((CFolderDialog*)pDlg->GetDlgItem(0))->m_pPath = CString(path); pDlg->EndDialog(IDOK); return NULL; } } } } return CallWindowProc(CFolderDialog::m_wndProc, hwnd, message, wParam, lParam);}// Function name : CFolderDialog::OnInitDone// Description : For update the wiew of CFileDialog// Return type : voidvoid CFolderDialog::OnInitDone(){ HideControl(edt1); //HideControl(stc3); //Select file static text //HideControl(cmb13); //Current file combobox HideControl(cmb1); //File filter combobox HideControl(stc2); //Filter static text //Rearrange the controls in the bottom. CWnd* pFD = GetParent(); //Get Cancel Button Position CRect rectCancel; pFD->GetDlgItem(IDCANCEL)->GetWindowRect(rectCancel); pFD->ScreenToClient(rectCancel); //Enlarge Listview control CRect rectList2; pFD->GetDlgItem(lst1)->GetWindowRect(rectList2); pFD->ScreenToClient(rectList2); pFD->GetDlgItem(lst1)->SetWindowPos(0, 0, 0, rectList2.Width(), abs(rectList2.top - (rectCancel.top - 4)), SWP_NOMOVE | SWP_NOZORDER); //Set Static text and position CRect rectText; pFD->GetDlgItem(stc3)->GetWindowRect(rectText); pFD->ScreenToClient(rectText); pFD->GetDlgItem(stc3)->SetWindowPos(0, rectList2.left, rectCancel.top + 6, 0, 0, SWP_NOZORDER | SWP_NOSIZE); SetControlText(stc3, _T("Selected:")); //ComboBox of current file CRect rectComBo; pFD->GetDlgItem(cmb13)->GetWindowRect(rectComBo); pFD->ScreenToClient(rectComBo); pFD->GetDlgItem(cmb13)->SetWindowPos(0, rectText.left + rectText.Width() - 40, rectCancel.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); //Set OK Button Position CRect rectOK; pFD->GetDlgItem(IDOK)->GetWindowRect(rectOK); pFD->ScreenToClient(rectOK); pFD->GetDlgItem(IDOK)->SetWindowPos(0, rectCancel.left - rectOK.Width() - 2, rectCancel.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); SetControlText(IDOK, _T("Select")); pFD->SetWindowText(_T("Choose folder")); pFD->CenterWindow(); m_wndProc = (WNDPROC)SetWindowLong(pFD->m_hWnd, GWL_WNDPROC, (long)WindowProcNew);}//Change the combobox context when select folder.void CFolderDialog::OnFileNameChange(){ ChangeFolder();}//If the folder contains no sub folder, the OnFileNameChange will not be triggered.//Add this OnFolderChange to double sure even if there is no sub folder.void CFolderDialog::OnFolderChange(){ ChangeFolder();}//Change the combobox text to current selected foldervoid CFolderDialog::ChangeFolder(){ TCHAR path[MAX_PATH] = {0}; GetCurrentDirectory(MAX_PATH, path); SetControlText(cmb13, path);}调用:
CString folderPath;CFolderDialog dlg(&folderPath, this);if(IDOK == dlg.DoModal()){ UpdateData(false);}??
链接:http://www.vckbase.com/english/code/dialog/folder_dialog.shtml.htm
?
3. 复杂的但是功能比较全的窗口XFolderDialog:
界面:
?
?
链接:http://www.codeproject.com/KB/dialog/XFolderDialog.aspx