相关参考:http://www.codeguru.com/Cpp/W-D/dislog/commondialogs/article.php/c1967 在我告诉大家怎么样修改MFC浏览程序中文件读写对话框的缺省设置之前呢,我们应该先知道MFC是怎么样显示 文件打开和文件保存对话框的。如果你选择了文件菜单中的打开,那么就会有一个消息发送给CWinApp::OnFileOpen,通过一个成员变量 m_pDocManager(一个指向CDocManager 对象的指针)来调用CDocManager::OnFileOpen,那么函数就会调用CDocManager的虚函数 DoPromptFileName,成功后再调用CWinApp::OpenDocumentFile函数,这个文件对话框就是在 DoPromptFileName的虚函数中显示的。当我们打开的是保存对话框时,文件保存(或另存为)命令消息就会发给 CDocument::OnFileSave (or CDocument::OnFileSaveAs),在这2种情况下,CDocument::DoSave函数都会被调用。最后,如果文件名是空的,那么 CDocument::DoSave就会调用CWinApp::DoPromptFileName,使得成员变量m_pDocManager有效,并且调 用CDocManager::DoPromptFileName来显示保存对话框。 那么现在大家都明白了,CDocManager::DoPromptFileName函数(注意它是一个虚函数)就是负责显示标准的文件打开和保存对话框的(可是有一个BOOL变量来决定显示哪一个对话框的)。 现在看起来,这好象对改变默认的对话框设置没什么用。你可能也没有考虑过在类CDocManager中的DoPromptFileName函 数,或者不知道怎么改,来使用你自己的CDocManager类。那么你不用急,下面的代码就是告诉你怎么自定义CDocManager。 // CDocManager class declaration class CDocManagerEx : public CDocManager // Construction // Attributes // Operations // Overrides // Implementation #include "stdafx.h" #ifdef _DEBUG static void AppendFilterSuffix(CString& filter, OPENFILENAME& ofn, CString strFilterExt, strFilterName; // add to filter ///////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC(CDocManagerEx, CDocManager) CDocManagerEx::CDocManagerEx() CDocManagerEx::~CDocManagerEx() BOOL CDocManagerEx::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate) CString title; dlgFile.m_ofn.Flags |= lFlags; CString strFilter; // append the "*.*" all files filter dlgFile.m_ofn.lpstrFilter = strFilter; BOOL bResult = dlgFile.DoModal() == IDOK ? TRUE : FALSE; 以上代码是从MFC原代码中完整的拷贝过来的,当中只有一行需要改:对话框的声明(当然,由于这是CFileDialog的子类,你可以有更多 的修改权),而且对于标准对话框来说,还应该有预览功能。AppendFilterSuffix函数是从DoPromptFileName中被调用的,原 代码可以从你的工程中获得。如果你想显示打开和保存对话框,你可以使用bOpenFileDialog参数,TRUE表示对话框是打开对话框,反之,亦 然。
//
{
DECLARE_DYNAMIC(CDocManagerEx)
public:
CDocManagerEx();
public:
public:
// helper for standard commdlg dialogs
virtual BOOL DoPromptFileName(CString& fileName, UINT nIDSTitle,
DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);
public:
virtual ~CDocManagerEx();
};
// DocManager.cpp : implementation file
//
#include "PreviewFileDlg.h"
#include "DocManager.h" // the header with the class declaration
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CDocTemplate* pTemplate, CString* pstrDefaultExt)
{
ASSERT_VALID(pTemplate);
ASSERT_KINDOF(CDocTemplate, pTemplate);
if (pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt) &&
!strFilterExt.IsEmpty() &&
pTemplate->GetDocString(strFilterName, CDocTemplate::filterName) &&
!strFilterName.IsEmpty())
{
// a file based document template - add to filter list
#ifndef _MAC
ASSERT(strFilterExt[0] == '.');
#endif
if (pstrDefaultExt != NULL)
{
// set the default extension
#ifndef _MAC
*pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1; // skip the '.'
#else
*pstrDefaultExt = strFilterExt;
#endif
ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt);
ofn.nFilterIndex = ofn.nMaxCustFilter + 1; // 1 based number
}
filter += strFilterName;
ASSERT(!filter.IsEmpty()); // must have a file type name
filter += (TCHAR)'\0'; // next string please
#ifndef _MAC
filter += (TCHAR)'*';
#endif
filter += strFilterExt;
filter += (TCHAR)'\0'; // next string please
ofn.nMaxCustFilter++;
}
}
// CDocManagerEx
{
}
{
}
{
CPreviewFileDlg dlgFile(bOpenFileDialog); // this is the only modified line!
VERIFY(title.LoadString(nIDSTitle));
CString strDefault;
if (pTemplate != NULL)
{
ASSERT_VALID(pTemplate);
AppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault);
}
else
{
// do for all doc template
POSITION pos = m_templateList.GetHeadPosition();
BOOL bFirst = TRUE;
while (pos != NULL)
{
CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);
AppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate,
bFirst ? &strDefault : NULL);
bFirst = FALSE;
}
}
CString allFilter;
VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));
strFilter += allFilter;
strFilter += (TCHAR)'\0'; // next string please
#ifndef _MAC
strFilter += _T("*.*");
#else
strFilter += _T("****");
#endif
strFilter += (TCHAR)'\0'; // last string
dlgFile.m_ofn.nMaxCustFilter++;
#ifndef _MAC
dlgFile.m_ofn.lpstrTitle = title;
#else
dlgFile.m_ofn.lpstrPrompt = title;
#endif
dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);
fileName.ReleaseBuffer();
return bResult;
}
当然我们也可以使用我们自己定义的CDocManagerEx类来代替原来的CDocManager 类,CWinApp是通过成员变量m_pDocManager来使用文档管理器,所以我们必须正确的初始化这个变量。有必要特别关注一下在 CWinApp::AddDocTemplate中CWinApp创建对象的原代码,这其中有一个很普通的函数调用,我们把它给忽略了,那就是 CWinApp::InitInstance函数。当m_pDocManager参数是NULL的时候,CWinApp::AddDocTemplate 函数只是创建CDocManager对象,那么一旦m_pDocManager指针被正确的初始化,CWinApp::AddDocTemplate函数 也就能够被正确的调用了。因此,这最后一步就是在调用CWinApp::AddDocTemplate之前就初始化成员变量m_pDocManager, 以达到我们想要的样子。(当然你也不一定得调用CWinApp::AddDocTemplate,而是直接调用 m_pDocManager->AddDocTemplate也行)
以下就是代码:
BOOL COurApp::InitInstance() #ifdef _AFXDLL // Change the registry key under which our settings are stored. LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register the application's document templates. Document templates CMultiDocTemplate* pDocTemplate; // or just AddDocTemplate(pDocTemplate); // Enable drag/drop open // Enable DDE Execute open // Parse command line for standard shell commands, DDE, file open // Dispatch commands specified on the command line // The main window has been initialized, so show and update it. return TRUE; |
评论