在我告诉大家怎么样修改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表示对话框是打开对话框,反之,亦 然。
当然我们也可以使用我们自己定义的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; // 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; |