自定义MFC的文件夹浏览控件类

文件对话框属于通用对话框范畴(另外还有颜色,查找,查找替换,字体,打印等对话框)。
借助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函数。
三个步骤:配置对话框,打开对话框,获取返回值(文件夹路径)。

  1. // 获取特定文件夹的LPITEMIDLIST,可以将之理解为HANDLE
  2. // 所谓的特定文件夹,你可以用CSIDL_XXX来检索之。
  3. LPITEMIDLIST rootLoation;
  4. SHGetSpecialFolderLocation( NULL, CSIDL_DESKTOP, &rootLoation );
  5. if ( rootLoation == NULL ) {
  6.    // unkown error
  7.    // return
  8. }

  9. // 配置对话框
  10. BROWSEINFO bi;
  11. ZeroMemory( &bi, sizeof( bi ) );
  12. bi.pidlRoot = rootLoation; // 文件夹对话框之根目录,不指定的话则为我的电脑
  13. bi.lpszTitle = _T( "对话框抬头" ); // 可以不指定
  14. // bi.ulFlags = BIF_EDITBOX | BIF_RETURNONLYFSDIRS;

  15. // 打开对话框, 有点像DoModal
  16. LPITEMIDLIST targetLocation = SHBrowseForFolder( &bi );
  17. if ( targetLocation != NULL ) {
  18.    TCHAR targetPath[ MAX_PATH ];
  19.    SHGetPathFromIDList( targetLocation, targetPath );
  20.    // MessageBox( targetPath );
  21. }
更详细的配置

如果为BROWSEINFO配置回调函数,那么在对话框有事件发生时(比如对话框刚被打开等),回调函数被调用,这样你就有机会得以进行更详细的配置,下面是一个封装完好的例子:

  1. //------------------------------------------------------
  2. // 头文件
  3. #ifndef MFCExt_Control_FolderDialog_H_INCLUDED_
  4. #define MFCExt_Control_FolderDialog_H_INCLUDED_
  5. namespace MFCExt { namespace Control {
  6.     class CFolderDialog {
  7.     public:
  8.         CFolderDialog(
  9.             int rootDirFlag = CSIDL_DESKTOP,
  10.             const CString& focusDir = _T( "" ),
  11.             const CString& title = _T( "" ),
  12.             DWORD browseInfoFlag = 0
  13.             );
  14.         INT_PTR DoModal();
  15.         const CString& GetPath() const { return finalPath_; }
  16.     private:
  17.         void OnCallback( HWND hWnd, UINT uMsg, LPARAM lParam );
  18.         void SetFocusDirectory();
  19.     private:
  20.         const int rootDirFlag_;
  21.         const CString focusDir_;
  22.         const CString title_;
  23.         const DWORD browseInfoFlag_;
  24.         HWND hDialog_;
  25.         CString finalPath_;
  26.         friend int CALLBACK BrowseDirectoryCallback( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData );
  27.     };  
  28. } }
  29. namespace MFCExt {
  30.     using Control::CFolderDialog;
  31. }
  32. namespace AutoTest {
  33.     void TestMFCExtFolderDialog();
  34. }
  35. #endif // MFCExt_Control_FolderDialog_H_INCLUDED_
  36. //------------------------------------------------------
  37. // 实现文件
  38. #include "stdafx.h"
  39. #include "FolderDialog.h"
  40. namespace MFCExt { namespace Control {
  41.    
  42.     static int CALLBACK BrowseDirectoryCallback( HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData ) {
  43.         CFolderDialog* folderDialog = reinterpret_cast< CFolderDialog* >( lpData );
  44.         folderDialog->OnCallback( hWnd, uMsg, lParam );           
  45.         return 0;
  46.     }   
  47.     CFolderDialog::CFolderDialog(
  48.         int rootDirFlag,
  49.         const CString& focusDir,
  50.         const CString& title,
  51.         DWORD browseInfoFlag
  52.         )
  53.         : rootDirFlag_( rootDirFlag )
  54.         , focusDir_( focusDir )
  55.         , title_( title )
  56.         , browseInfoFlag_( browseInfoFlag )
  57.         , hDialog_( NULL )
  58.         , finalPath_( _T( "" ) )
  59.     {}
  60.     INT_PTR CFolderDialog::DoModal() {
  61.         LPITEMIDLIST rootLoation;
  62.         SHGetSpecialFolderLocation( NULL, rootDirFlag_, &rootLoation );
  63.         if ( rootLoation == NULL ) {
  64.             throw new CInvalidArgException();
  65.         }
  66.         BROWSEINFO browseInfo;
  67.         ZeroMemory( &browseInfo, sizeof( browseInfo ) );
  68.         browseInfo.pidlRoot = rootLoation;
  69.         browseInfo.ulFlags = browseInfoFlag_;
  70.         browseInfo.lpszTitle = title_;
  71.         browseInfo.lpfn = BrowseDirectoryCallback;
  72.         browseInfo.lParam = ( LPARAM )this;
  73.        
  74.         LPITEMIDLIST targetLocation = SHBrowseForFolder( &browseInfo );
  75.         if ( targetLocation == NULL ) {
  76.             return IDCANCEL;
  77.         }
  78.        
  79.         TCHAR targetPath[ MAX_PATH ] = { _T( '/0' ) };
  80.         SHGetPathFromIDList( targetLocation, targetPath );
  81.         finalPath_ = targetPath;
  82.        
  83.         return IDOK;
  84.     }
  85.     void CFolderDialog::OnCallback( HWND hWnd, UINT uMsg, LPARAM lParam ) {
  86.         hDialog_ = hWnd;
  87.         if ( uMsg == BFFM_INITIALIZED ) {
  88.             SetFocusDirectory();           
  89.         }
  90.     }
  91.     void CFolderDialog::SetFocusDirectory() {
  92.         ASSERT( hDialog_ != NULL );
  93.         if ( focusDir_ != _T( "" ) ) {
  94.             ::SendMessage( hDialog_, BFFM_SETSELECTION, TRUE, ( LPARAM )focusDir_.GetString() );
  95.         }
  96.     }
  97. } }
  98. namespace AutoTest {
  99.     void TestMFCExtFolderDialog() {
  100.         {       
  101.             MFCExt::CFolderDialog dlg;
  102.             if ( dlg.DoModal() == IDOK ) {
  103.                 AfxMessageBox( dlg.GetPath() );
  104.             }
  105.         }
  106.         {       
  107.             MFCExt::CFolderDialog dlg( CSIDL_DRIVES, _T( "C://Windows" ), _T( "Title" ) );
  108.             if ( dlg.DoModal() == IDOK ) {
  109.                 AfxMessageBox( dlg.GetPath() );
  110.             }
  111.         }
  112.     }
  113. }





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值