您的位置:首页 > 其它

整理: CFileDialog基本操作

2010-09-24 22:32 295 查看
// CMyFileDialog.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "CMyFileDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
CWinApp theApp;
using namespace std;
int FnOpenFileDlg();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;
	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		FnOpenFileDlg();
		getchar();
	}
	return nRetCode;
}
int FnOpenFileDlg()
{
	CFileDialog dlg(TRUE, "png", 0, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "Portable Network Graphics (.png)|*.png||");
	
	//初始化要打开的路径
	PCHAR pObjFile = "d://tmp//";
	dlg.m_ofn.lpstrInitialDir = pObjFile;
	const int const ndepth = 4096;
	PCHAR pPathName = new CHAR[ndepth];
	
	if(dlg.DoModal() == IDCANCEL)
	{
		delete pPathName;
		return S_FALSE;
	}
	printf("您选择的路径是:%s/n", dlg.GetPathName());
	delete pPathName;
	return S_OK;
}




//打开单类型或多类型的文件
	CString csSoundFileName;
	CFileDialog dlg(TRUE, "*.mid", 0, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "MIDI声音文件(*.mid)|*.mid|W***声音文件(*.wav)|*.wav|RMI声音文件(*.rmi)|*.rmi|本程序支持的所有声音文件(*.mid;*.wav;*.rmi)|*.mid;*.wav;*.rmi||");


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

int FnOpenFileDlg(CString & csFilePathName)  
{  
    CFileDialog dlg(FALSE, "bmp", 0, 
		OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, 
		"xx文件 (.bmp)|*.bmp||");  
      
    //初始化要打开的路径  
	dlg.m_ofn.lpstrTitle = "请选择xx文件的保存位置";
    PCHAR pObjFile = "c://";  
    dlg.m_ofn.lpstrInitialDir = pObjFile;  
    int const ndepth = 4096;  
    PCHAR pPathName = new CHAR[ndepth]; 
      
    if(dlg.DoModal() == IDCANCEL)  
    {  
        delete pPathName;  
        return S_FALSE;  
    }  
    printf("您选择的路径是:%s/n", dlg.GetPathName());  
	csFilePathName = dlg.GetPathName();
    delete pPathName;  
    return S_OK;  
}
void CFileDlgSaveToDlg::OnButton1() 
{
	// TODO: Add your control notification handler code here
	CString csFilePathName;
	CString csMsg;
	if(S_OK == FnOpenFileDlg(csFilePathName))
	{
		csMsg.Format("请接着xx文件[%s]", csFilePathName);
		AfxMessageBox(csMsg);
	}
}


<2010_1223>

//整理了一版, 打开文件
void CDlgSelectSkinFile::OnBtnSelectSkinFile() 
{
	CMainFrame * pFrame = (CMainFrame *)AfxGetMainWnd();
	CFileDialog dlg(TRUE, "*.msstyles", "*.msstyles", OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, "皮肤文件(*.msstyles)|*.mid||");
	dlg.m_ofn.lpstrInitialDir = pFrame->GetDefaultSkinFilePath();
	dlg.m_ofn.lpstrTitle = "请选择皮肤文件";
	int const ndepth = 4096;
	PCHAR pPathName = new CHAR[ndepth];
	memset(pPathName, 0, ndepth);
	if(IDOK == dlg.DoModal())
	{
		m_strSkinFilePathName = dlg.GetPathName();
		UpdateData(FALSE);
	}
	delete pPathName;
	pPathName = NULL;
}


<2011_0105>

CFileDialog 打开保存xx文件, 代码太相似, 做个实验, 重构一下, 使代码量降低.

比如一下工程中要用到大量的CFileDialog, 代码中充斥这大量类似的CFileDialog代码.

这个重构工作还是值得的.



<2011_0108>

CFileDialog的重构完成, 调用时清爽多了.

// LsFileDialogPrj.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "LsFileDialogPrj.h"
#include "LsFileDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
CWinApp theApp;
using namespace std;
INT TestFileDailog();
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;
	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		CString strHello;
		strHello.LoadString(IDS_HELLO);
		cout << (LPCTSTR)strHello << endl;
		TestFileDailog();
	}

	getchar();
	return nRetCode;
}
INT TestFileDailog()
{
	CLsFileDialog Dlg;
	Dlg.SetDefaultExt("*.exe");
	Dlg.SetDefaultFileName("*.exe");
	Dlg.SetFileTypeFilter("EXE文件 (*.exe)|*.exe|DLL文件 (*.dll)|*.dll|OCX文件 (*.ocx)|*.ocx|RAR文件 (*.rar)|*.rar|PDF文件 (*.pdf)|*.pdf||");
	Dlg.SetInitialPath("c://windows//");
	Dlg.SetOpenType(TRUE);
	Dlg.SetTitle("请选择存在的可执行类型文件");
	//打开一个现有文件
	if(IDOK == Dlg.UsrDoModal())
		printf("pathname to load = [%s]/n", Dlg.m_pfileDlg->GetPathName());
	//让用户选择一个要保存的全路径文件名
	Dlg.SetOpenType(FALSE);
	Dlg.SetTitle("请选择要保存的可执行类型文件");
	if(IDOK == Dlg.UsrDoModal())
		printf("pathname to save = [%s]/n", Dlg.m_pfileDlg->GetPathName());
	/**
	* 运行结果
	* pathname to load = [C:/WINDOWS/twunk_16.exe]
	* pathname to save = [C:/WINDOWS/twunk_32.exe]
	*/
	return S_OK;
}


CLsFileDialog封装了CFileDialog操作, 变化的部分都在CLsFileDialog调用者那里

#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(CString strTitle);
	void SetOpenType(BOOL bOpen);/**< 打开还是保存, TRUE<打开> : FALSE<保存> */
	void SetDefaultExt(CString strDefaultExt);
	void SetDefaultFileName(CString strDefaultFileName);
	void SetFileTypeFilter(CString strFileTypeFilter);
	void SetInitialPath(CString strInitialPath);
	INT UsrDoModal();/**< 包装标准Fialog的DoModal操作 */
public:
	CFileDialog * m_pfileDlg;/**< 选择完文件的操作很多, 不封装了, 直接暴露给调用者 */
	CString m_strFileNameSelect;//选择的文件名数组
private:
	PCHAR GetTitle();
	BOOL GetOpenType();
	PCHAR GetDefaultExt();
	PCHAR GetDefaultFileName();
	PCHAR GetFileTypeFilter();
	PCHAR 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 "LsFileDialogPrj.h"
#include "LsFileDialog.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(CString strTitle)
{
	m_strTitle = strTitle;
}
void CLsFileDialog::SetOpenType(BOOL bOpen)
{/**< 打开还是保存, TRUE<打开> : FALSE<保存> */
	m_bOpenFile = bOpen;
}
void CLsFileDialog::SetInitialPath(CString strInitialPath)
{
	m_strInitialPath = strInitialPath;
}
PCHAR CLsFileDialog::GetInitialPath()
{
	return (LPSTR)(LPCSTR)m_strInitialPath;
}
void CLsFileDialog::SetDefaultExt(CString strDefaultExt)
{
	m_strDefaultExt = strDefaultExt;
}
void CLsFileDialog::SetDefaultFileName(CString strDefaultFileName)
{
	m_strDefaultFileName = strDefaultFileName;
}
void CLsFileDialog::SetFileTypeFilter(CString strFileTypeFilter)
{
	m_strFileTypeFilter = strFileTypeFilter;
}
PCHAR CLsFileDialog::GetTitle()
{
	return (LPSTR)(LPCSTR)m_strTitle;
}
BOOL CLsFileDialog::GetOpenType()
{
	return m_bOpenFile;
}
PCHAR CLsFileDialog::GetDefaultExt()
{
	return (LPSTR)(LPCSTR)m_strDefaultExt;
}
PCHAR CLsFileDialog::GetDefaultFileName()
{
	return (LPSTR)(LPCSTR)m_strDefaultFileName;
}
PCHAR CLsFileDialog::GetFileTypeFilter()
{
	return (LPSTR)(LPCSTR)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操作 */
	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)
					{
						CString csMsg;
						csMsg.Format("选择的文件[%s]不存在, 请重新选择", m_strFileNameSelect);
						AfxMessageBox(csMsg);
					}
				}
			}
			else
			{
				nRc = TRUE;
				bNeedContinueSelect = FALSE;
			}
		}
		delete pPathName;
		pPathName = NULL;
	}
	
	return nRc;
}




<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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: