一旦你用起来以后会发现另外的问题:那就是如何让MFC识别它?如果你深入到MFC中,会发现MFC在一个叫CDocManager::DoPromptFileName的函数中调用文件对话框。幸运的是这个函数是个虚函数,所以你可以重写它,但那需要一个从CDocManager派生一个新类CDocManagerEx,并将它装入你的应用程序。下面就是这个新的派生类:
DocMgrEx头文件和实现文件////////////////////////////////////////////////////////////////// DocMgrEx.h // #pragma once//////////////////// CDocManagerEx: 扩展 CDocManager 类使用 CFileOpenEx.class CDocManagerEx : public CDocManager {public: CDocManagerEx(); ~CDocManagerEx(); // 为"打开/保存"对话框重载 virtual BOOL DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);protected: // 创建"打开"文件对话框的新函数 virtual CFileDialog* OnCreateFileDialog(BOOL bOpenFileDialog); DECLARE_DYNAMIC(CDocManagerEx)};////////////////////////////////////////////////////////////////// DocMgrEx.cpp // // CDocManagerEx 为了Windows 2000中使用"打开"文件对话框,// 重写 CDocManager 中的一个函数 DoPromptFileName.// 使用这个类时, 在你添加任何文档模版之前,添加下列一行代码到应用// 程序的实例化函数:InitInstance().// m_pDocManager = new CDocManagerEx;// #include "stdafx.h"#include #include "DocMgrEx.h"#include "FileDialogEx.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifAFX_STATIC void AFXAPI _AfxAppendFilterSuffix(CString& filter, OPENFILENAME& ofn, CDocTemplate* pTemplate, CString* pstrDefaultExt);IMPLEMENT_DYNAMIC(CDocManagerEx, CDocManagerEx)CDocManagerEx::CDocManagerEx(){}CDocManagerEx::~CDocManagerEx(){}////////////////////////////////////////////////////////////////////////// 创建文件对话框的新函数,你可以重载它以创建一些不同类型的CFileDialog,// 缺省情况下创建 CFileDialogEx.//CFileDialog* CDocManagerEx::OnCreateFileDialog(BOOL bOpenFileDialog){ TRACE(_T("CDocManagerEx::OnCreateFileDialog\n")); return new CFileDialogEx(bOpenFileDialog);}/////////////////////////////////////////////////////////////////////////// 这个函数是从MFC的 docmgr.cpp文件中考过来的,只对它做了稍微的修改以便// 使用 CFileDialogEx. //BOOL CDocManagerEx::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate){ // 修改日期 5-15-99 : 调用虚拟函数来创建对话框 CFileDialog* pDlg = OnCreateFileDialog(bOpenFileDialog); ASSERT(pDlg); CFileDialog& dlgFile = *pDlg; CString title; VERIFY(title.LoadString(nIDSTitle)); dlgFile.m_ofn.Flags |= lFlags; CString strFilter; CString strDefault; if (pTemplate != NULL) { ASSERT_VALID(pTemplate); _AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault); } else { // 用于所有的文档模板 POSITION pos = m_templateList.GetHeadPosition(); BOOL bFirst = TRUE; while (pos != NULL) { CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos); _AfxAppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, bFirst ? &strDefault : NULL); bFirst = FALSE; } } // 添加 "*.*" 对全部文件过滤 CString allFilter; VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER)); strFilter += allFilter; strFilter += (TCHAR)''\0''; // 下一个串 strFilter += _T("*.*"); strFilter += (TCHAR)''\0''; // 最后一个串 dlgFile.m_ofn.nMaxCustFilter++; dlgFile.m_ofn.lpstrFilter = strFilter; dlgFile.m_ofn.lpstrTitle = title; dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH); int nResult = dlgFile.DoModal(); fileName.ReleaseBuffer(); // 修改日期 5-15-99 : 删除对话框 delete pDlg; return nResult == IDOK;}////////////////////////////////////////////////////////////////////////// 这个函数是原封不动地从MFC的 docmgr.cpp文件中考过来的,因为它是静态函数,// 所以在这里是必须的.//AFX_STATIC void AFXAPI _AfxAppendFilterSuffix(CString& filter, OPENFILENAME& ofn, CDocTemplate* pTemplate, CString* pstrDefaultExt){ ASSERT_VALID(pTemplate); ASSERT_KINDOF(CDocTemplate, pTemplate); CString strFilterExt, strFilterName; if (pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt) && !strFilterExt.IsEmpty() && pTemplate->GetDocString(strFilterName, CDocTemplate::filterName) && !strFilterName.IsEmpty()) { // 添加一个基于文档模板的文件到过滤器 ASSERT(strFilterExt[0] == ''.''); if (pstrDefaultExt != NULL) { // 设置缺省扩展名 *pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1; // skip the ''.'' ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt); ofn.nFilterIndex = ofn.nMaxCustFilter + 1; // 1 based number } // 添加过滤器 filter += strFilterName; ASSERT(!filter.IsEmpty()); // 必须有一个文件类型名 filter += (TCHAR)''\0''; // 下一个串 filter += (TCHAR)''*''; filter += strFilterExt; filter += (TCHAR)''\0''; // 下一个串 ofn.nMaxCustFilter++; }}
在程序中使用这个类时,你必须在应用的InitInstance函数中添加一行如下代码:
// 使用扩展的 CDocManager.// 在创建任何文档模板前添加!m_pDocManager = new CDocManagerEx;
DocMgrEx.cpp 有一对从MFC拷贝过来的函数,用重新写的 DoPromptFileName 创建 CFileDialogEx,而不是不 CFileDialog。实际上,为了创建对话框,CDocManagerEx 调用一个新的虚函数----OnCreateFileDialog,从而解决了使用 CDocManager 创建对话框产生的问题。也就是说,没有能重写的虚函数来创建不同种类的对话框。真是聪明......