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

时间:2023-01-24 21:34:54

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

调用:

std::string szPath("");  

if (GetFolder(szPath, "Select a folder.") == true)
{
printf("You selected: \"%s\".\n", szPath.c_str());
}
else
{
printf("No folder selected!\n");
}

界面:

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


2. 带导航栏的文件夹选择对话框:只在MFC程序中使用,从MFC的CFileDialog派生。

源码-头文件-Folder_dialog.h:

#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:

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

调用:

CString folderPath;  
CFolderDialog dlg(&folderPath, this);
if(IDOK == dlg.DoModal())
{
UpdateData(false);
}

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

界面:

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