文件对话框属于通用对话框范畴(另外还有颜色,查找,查找替换,字体,打印等对话框)。
借助MFC现成的类CFileDialog你可以轻易操作文件对话框。
CFileDialog dlg( TRUE, _T( "txt" ), _T( "b.txt" ), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, _T( "文本|*.txt|所有文件|*||" ) );
if ( dlg.DoModal() == IDOK ) {
// dlg.GetPathName();
}
第一个参数TRUE:打开文件对话框,FALSE:保存文件对话框
第二个参数表示要打开文件的默认扩展名(保存文件是显得比较重要)
第三个参数表示要打开的目标文件名,如果未提供扩展名将使用第二个参数指定的名称
第四个参数 OFN_FILEMUSTEXIST表示目标必须存在, OFN_HIDEREADONLY不显示只读文件,还有些其他参数可用OFN_XXX自行检索之
第五个参数表示过滤字符串表,按照这个格式"标题|过滤表|标题|过滤表||"
打开一个文件夹对话框没有现成的MFC类可用,你需要借助一类称为Shell操控的API函数。
三个步骤:配置对话框,打开对话框,获取返回值(文件夹路径)。
- // 获取特定文件夹的LPITEMIDLIST,可以将之理解为HANDLE
- // 所谓的特定文件夹,你可以用CSIDL_XXX来检索之。
- LPITEMIDLIST rootLoation;
- SHGetSpecialFolderLocation( NULL, CSIDL_DESKTOP, &rootLoation );
- if ( rootLoation == NULL ) {
- // unkown error
- // return
- }
- // 配置对话框
- BROWSEINFO bi;
- ZeroMemory( &bi, sizeof( bi ) );
- bi.pidlRoot = rootLoation; // 文件夹对话框之根目录,不指定的话则为我的电脑
- bi.lpszTitle = _T( "对话框抬头" ); // 可以不指定
- // bi.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS;
- // 打开对话框, 有点像DoModal
- LPITEMIDLIST targetLocation = SHBrowseForFolder( &bi );
- if ( targetLocation != NULL ) {
- TCHAR targetPath[ MAX_PATH ];
- SHGetPathFromIDList( targetLocation, targetPath );
- // MessageBox( targetPath );
- }
如果为BROWSEINFO配置回调函数,那么在对话框有事件发生时(比如对话框刚被打开等),回调函数被调用,这样你就有机会得以进行更详细的配置,下面是一个封装完好的例子:
- //------------------------------------------------------
- // 头文件
- #ifndef MFCExt_Control_FolderDialog_H_INCLUDED_
- #define MFCExt_Control_FolderDialog_H_INCLUDED_
- namespace MFCExt { namespace Control {
- class CFolderDialog {
- public:
- CFolderDialog(
- int rootDirFlag = CSIDL_DESKTOP,
- const CString& focusDir = _T( "" ),
- const CString& title = _T( "" ),
- DWORD browseInfoFlag = 0
- );
- INT_PTR DoModal();
- const CString& GetPath() const { return finalPath_; }
- private:
- void OnCallback( HWND hWnd, UINT uMsg, LPARAM lParam );
- void SetFocusDirectory();
- private:
- const int rootDirFlag_;
- const CString focusDir_;
- const CString title_;
- const DWORD browseInfoFlag_;
- HWND hDialog_;
- CString finalPath_;
- friend int CALLBACK BrowseDirectoryCallback( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData );
- };
- } }
- namespace MFCExt {
- using Control::CFolderDialog;
- }
- namespace AutoTest {
- void TestMFCExtFolderDialog();
- }
- #endif // MFCExt_Control_FolderDialog_H_INCLUDED_
- //------------------------------------------------------
- // 实现文件
- #include "stdafx.h"
- #include "FolderDialog.h"
- namespace MFCExt { namespace Control {
- static int CALLBACK BrowseDirectoryCallback( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData ) {
- CFolderDialog* folderDialog = reinterpret_cast< CFolderDialog* >( lpData );
- folderDialog->OnCallback( hWnd, uMsg, lParam );
- return 0;
- }
- CFolderDialog::CFolderDialog(
- int rootDirFlag,
- const CString& focusDir,
- const CString& title,
- DWORD browseInfoFlag
- )
- : rootDirFlag_( rootDirFlag )
- , focusDir_( focusDir )
- , title_( title )
- , browseInfoFlag_( browseInfoFlag )
- , hDialog_( NULL )
- , finalPath_( _T( "" ) )
- {}
- INT_PTR CFolderDialog::DoModal() {
- LPITEMIDLIST rootLoation;
- SHGetSpecialFolderLocation( NULL, rootDirFlag_, &rootLoation );
- if ( rootLoation == NULL ) {
- throw new CInvalidArgException();
- }
- BROWSEINFO browseInfo;
- ZeroMemory( &browseInfo, sizeof( browseInfo ) );
- browseInfo.pidlRoot = rootLoation;
- browseInfo.ulFlags = browseInfoFlag_;
- browseInfo.lpszTitle = title_;
- browseInfo.lpfn = BrowseDirectoryCallback;
- browseInfo.lParam = ( LPARAM )this;
- LPITEMIDLIST targetLocation = SHBrowseForFolder( &browseInfo );
- if ( targetLocation == NULL ) {
- return IDCANCEL;
- }
- TCHAR targetPath[ MAX_PATH ] = { _T( '/0' ) };
- SHGetPathFromIDList( targetLocation, targetPath );
- finalPath_ = targetPath;
- return IDOK;
- }
- void CFolderDialog::OnCallback( HWND hWnd, UINT uMsg, LPARAM lParam ) {
- hDialog_ = hWnd;
- if ( uMsg == BFFM_INITIALIZED ) {
- SetFocusDirectory();
- }
- }
- void CFolderDialog::SetFocusDirectory() {
- ASSERT( hDialog_ != NULL );
- if ( focusDir_ != _T( "" ) ) {
- ::SendMessage( hDialog_, BFFM_SETSELECTION, TRUE, ( LPARAM )focusDir_.GetString() );
- }
- }
- } }
- namespace AutoTest {
- void TestMFCExtFolderDialog() {
- {
- MFCExt::CFolderDialog dlg;
- if ( dlg.DoModal() == IDOK ) {
- AfxMessageBox( dlg.GetPath() );
- }
- }
- {
- MFCExt::CFolderDialog dlg( CSIDL_DRIVES, _T( "C://Windows" ), _T( "Title" ) );
- if ( dlg.DoModal() == IDOK ) {
- AfxMessageBox( dlg.GetPath() );
- }
- }
- }
- }