文件对话框属于通用对话框范畴(另外还有颜色,查找,查找替换,字体,打印等对话框)。
借助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() );
}
}
}
}
MFC实现文件夹对话框
最新推荐文章于 2024-07-23 22:34:27 发布