CFileDialog的各种风格的目录/文件夹选择对话框---(CFolderDialog)

来源:岁月联盟 编辑:exp 时间:2012-04-01

1. 标准的文件夹选择对话框:可以使用在非MFC程序中,调用的标准API SHBrowserForFolder。
源码:
[cpp]
#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 handle   
bool 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 list   
        CoTaskMemFree(pIDL);   
    }   
   
    ::OleUninitialize();   
   
    return retVal;   
}  

调用:
[cpp]
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:

[cpp]print?#pragma once    
   
// CFolderDialog dialog    
class 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();   
};   
#pragma once 
 
// CFolderDialog dialog 
class 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:

[cpp]print?#include "stdafx.h"    
#include "folder_dialog.h"    
#include <DLGS.H>    
#include <WINUSER.H>    
   
#ifdef _DEBUG    
#define new DEBUG_NEW    
#undef THIS_FILE    
static char THIS_FILE[] = __FILE__;   
#endif    
   
// CFolderDialog    
IMPLEMENT_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 saved    
CFolderDialog::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 lParam    
LRESULT 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      : void    
void 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 folder    
void CFolderDialog::ChangeFolder()   
{   
    TCHAR path[MAX_PATH] = {0};   
    GetCurrentDirectory(MAX_PATH, path);   
    SetControlText(cmb13, path);   
}   
#include "stdafx.h" 
#include "folder_dialog.h" 
#include <DLGS.H> 
#include <WINUSER.H> 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
// CFolderDialog 
IMPLEMENT_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 saved 
CFolderDialog::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 lParam 
LRESULT 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      : void 
void 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 folder 
void CFolderDialog::ChangeFolder() 

    TCHAR path[MAX_PATH] = {0}; 
    GetCurrentDirectory(MAX_PATH, path); 
    SetControlText(cmb13, path); 

调用:


[cpp]print?CString folderPath;   
CFolderDialog dlg(&folderPath, this);   
if(IDOK == dlg.DoModal())   
{   
    UpdateData(false);   
}   
CString folderPath; 
CFolderDialog dlg(&folderPath, this); 
if(IDOK == dlg.DoModal()) 

    UpdateData(false); 


3. 复杂的但是功能比较全的窗口XFolderDialog:

界面:

链接:http://www.codeproject.com/KB/dialog/XFolderDialog.aspx

 

摘自  w174504744