整理: CFileDialog基本操作

本文介绍了一个CFileDialog的封装示例,通过创建CLsFileDialog类简化文件对话框的使用流程,支持打开和保存文件,并提供了设置文件类型过滤器等功能。

 

让用户选择文件的保存路径和名称

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






 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值