让用户选择文件的保存路径和名称
<2010_1223>
<2011_0105>
CFileDialog 打开保存xx文件, 代码太相似, 做个实验, 重构一下, 使代码量降低.
比如一下工程中要用到大量的CFileDialog, 代码中充斥这大量类似的CFileDialog代码.
这个重构工作还是值得的.
<2011_0108>
CFileDialog的重构完成, 调用时清爽多了.
CLsFileDialog封装了CFileDialog操作, 变化的部分都在CLsFileDialog调用者那里
<2013_0901>
今天将LsFileDialog用在unicode工程中, 编译不过~
搞了一个unicode版, 以前用 tchar 就好了.
因为以后的工程不会再用MBCS, 用到宽字符的地方, 直接用 L"xx"
调用方代码
LRESULT CViewPE::OnPeFileParse(WPARAM wparam, LPARAM lparam)
{
BOOL bRc = FALSE;
std::wstring strMsg;
CpeParse PeParse;
CLsFileDialog Dlg;
WriteToRichEditCtrl(L">> CViewPE::OnPeFileParse");
Dlg.SetDefaultExt(L"*.exe");
Dlg.SetDefaultFileName(L"*.exe");
Dlg.SetFileTypeFilter(
L"EXE文件 (*.exe)|*.exe|"
L"DLL文件 (*.dll)|*.dll|"
L"OCX文件 (*.ocx)|*.ocx||");
Dlg.SetInitialPath(GetTheModulePath().c_str());
Dlg.SetOpenType(TRUE);
Dlg.SetTitle(L"请选择存在的PE文件");
/// 打开一个现有文件
if (IDOK != Dlg.UsrDoModal())
return -1;
/// use Dlg.m_pfileDlg->GetPathName()
bRc = PeParse.parse((LPTSTR)(LPCTSTR)Dlg.m_pfileDlg->GetPathName());
strMsg = StringFormatV(
L"file path name = %s",
Dlg.m_pfileDlg->GetPathName());
WriteToRichEditCtrl(strMsg.c_str());
return bRc ? 0 : -1;
/// use PeParse do next task
}
定义
#if !defined(AFX_LSFILEDIALOG_H__51B8CD18_6B93_44C1_B9ED_6E785F4B0A92__INCLUDED_)
#define AFX_LSFILEDIALOG_H__51B8CD18_6B93_44C1_B9ED_6E785F4B0A92__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// LsFileDialog.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CLsFileDialog dialog
#define G_LS_FILE_DIALOG_BUF_LEN_MAX 4096 /**< 存取文件的Buffer深度 */
class CLsFileDialog : public CObject
{
DECLARE_DYNAMIC(CLsFileDialog)
public:
CLsFileDialog();
~CLsFileDialog();
public:
void SetTitle(const wchar_t * pcTitle);
void SetOpenType(BOOL bOpen);/**< 打开还是保存, TRUE<打开> : FALSE<保存> */
void SetDefaultExt(const wchar_t * pcDefaultExt);
void SetDefaultFileName(const wchar_t * pcDefaultFileName);
void SetFileTypeFilter(const wchar_t * pcFileTypeFilter);
void SetInitialPath(const wchar_t * pcInitialPath);
INT UsrDoModal();/**< 包装标准Fialog的DoModal操作 */
public:
CFileDialog * m_pfileDlg;/**< 选择完文件的操作很多, 不封装了, 直接暴露给调用者 */
CString m_strFileNameSelect;//选择的文件名数组
private:
wchar_t * GetTitle();
BOOL GetOpenType();
wchar_t * GetDefaultExt();
wchar_t * GetDefaultFileName();
wchar_t * GetFileTypeFilter();
wchar_t * GetInitialPath();
DWORD GetOpenFlag();
private:
CString m_strTitle;/**< 对话框标题 */
BOOL m_bOpenFile;/**< 打开还是保存 */
CString m_strDefaultExt;/** 默认的文件扩展名 */
CString m_strDefaultFileName;/** 默认的文件名 */
CString m_strFileTypeFilter;/** 文件类型选择过滤器 */
CString m_strInitialPath;/**< 文件选择的初始目录 */
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LSFILEDIALOG_H__51B8CD18_6B93_44C1_B9ED_6E785F4B0A92__INCLUDED_)
实现
// LsFileDialog.cpp : implementation file
//
#include "stdafx.h"
#include "mfcFileDlgHelper.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CLsFileDialog
IMPLEMENT_DYNAMIC(CLsFileDialog, CObject)
CLsFileDialog::CLsFileDialog()
{
m_pfileDlg = NULL;
}
CLsFileDialog::~CLsFileDialog()
{
if(m_pfileDlg)
{
delete m_pfileDlg;
m_pfileDlg = NULL;
}
}
void CLsFileDialog::SetTitle(const wchar_t * pcTitle)
{
m_strTitle = pcTitle;
}
void CLsFileDialog::SetOpenType(BOOL bOpen)
{/**< 打开还是保存, TRUE<打开> : FALSE<保存> */
m_bOpenFile = bOpen;
}
void CLsFileDialog::SetInitialPath(const wchar_t * pcInitialPath)
{
m_strInitialPath = pcInitialPath;
}
wchar_t * CLsFileDialog::GetInitialPath()
{
return (LPTSTR)(LPCTSTR)m_strInitialPath;
}
void CLsFileDialog::SetDefaultExt(const wchar_t * pcDefaultExt)
{
m_strDefaultExt = pcDefaultExt;
}
void CLsFileDialog::SetDefaultFileName(const wchar_t * pcDefaultFileName)
{
m_strDefaultFileName = pcDefaultFileName;
}
void CLsFileDialog::SetFileTypeFilter(const wchar_t * pcFileTypeFilter)
{
m_strFileTypeFilter = pcFileTypeFilter;
}
wchar_t * CLsFileDialog::GetTitle()
{
return (LPTSTR)(LPCTSTR)m_strTitle;
}
BOOL CLsFileDialog::GetOpenType()
{
return m_bOpenFile;
}
wchar_t * CLsFileDialog::GetDefaultExt()
{
return (LPTSTR)(LPCTSTR)m_strDefaultExt;
}
wchar_t * CLsFileDialog::GetDefaultFileName()
{
return (LPTSTR)(LPCTSTR)m_strDefaultFileName;
}
wchar_t * CLsFileDialog::GetFileTypeFilter()
{
return (LPTSTR)(LPCTSTR)m_strFileTypeFilter;
}
DWORD CLsFileDialog::GetOpenFlag()
{
DWORD dwRc = 0;
if(GetOpenType())
{//打开
dwRc = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT;
}
else
{//保存
dwRc = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
}
return dwRc;
}
INT CLsFileDialog::UsrDoModal()
{/**< 包装标准Fialog的DoModal操作 */
CString csMsg;
int nRc = IDCANCEL;
if(m_pfileDlg)
{
delete m_pfileDlg;
m_pfileDlg = NULL;
}
m_strFileNameSelect.Empty();
m_pfileDlg = new CFileDialog(
GetOpenType(),
GetDefaultExt(),
GetDefaultFileName(),
GetOpenFlag(),
GetFileTypeFilter(),
NULL);
if(!m_pfileDlg)
return nRc;
m_pfileDlg->m_ofn.lpstrInitialDir = GetInitialPath();
m_pfileDlg->m_ofn.lpstrTitle = GetTitle();
PCHAR pPathName = new CHAR[G_LS_FILE_DIALOG_BUF_LEN_MAX];
if(pPathName)
{
ZeroMemory(pPathName, G_LS_FILE_DIALOG_BUF_LEN_MAX);
BOOL bNeedContinueSelect = TRUE;
while(bNeedContinueSelect)
{
m_strFileNameSelect.Empty();
if(IDOK == m_pfileDlg->DoModal())
{
nRc = IDOK;
bNeedContinueSelect = GetOpenType() ? TRUE : FALSE;
m_strFileNameSelect = m_pfileDlg->GetPathName();
if(bNeedContinueSelect)
{//打开文件时, 需要判断文件是否存在
CFileFind find;
bNeedContinueSelect = find.FindFile(m_strFileNameSelect) ? FALSE : TRUE;
find.Close();
if(bNeedContinueSelect)
{
csMsg.Format(L"选择的文件[%s]不存在, 请重新选择", m_strFileNameSelect);
AfxMessageBox(csMsg);
}
}
}
else
{
nRc = TRUE;
bNeedContinueSelect = FALSE;
}
}
delete pPathName;
pPathName = NULL;
}
return nRc;
}
本文介绍了一个CFileDialog的封装示例,通过创建CLsFileDialog类简化文件对话框的使用流程,支持打开和保存文件,并提供了设置文件类型过滤器等功能。
2873

被折叠的 条评论
为什么被折叠?



