📄 改变缺省的文件打开另存为对.htm
字号:
<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>New Page </title><meta name="Microsoft Theme" content="none"><meta name="Microsoft Border" content="none"></head><body><!-- FC HP BN1 START --><!-- Please do not remove the line above or the code within this section --><!-- Doing so may cause damage to your pages or insertion of multiple banners--><center><p><table border="0" cellspacing="0" cellpadding="0"><tr><td colspan="11"><img src="http://www.fortunecity.com/console2/newnav/top.gif" height="7" width="555"></td></tr><tr><td><img src="http://www.fortunecity.com/console2/newnav/left.gif" alt="FC Navigation Console" height="60" width="72" border="0" usemap="#fcleft"><map name="fcleft"><area shape="rect" coords="10,43,64,60" href="http://www2.fortunecity.com/cgi-bin/homepage/estate.pl?referer=navbar" target="_top"><area shape="rect" coords="9,21,61,36" href="http://www2.fortunecity.com/cgi-bin/showarea.pl?area=skyscraper&referer=navbar" target="_top"><area shape="rect" coords="8,0,62,15" href="http://www.fortunecity.com" target="_top"><area shape="rect" href="http://www.fortunecity.com" target="_top" coords="0,0,49,49"></map></td><td colspan="9"><A HREF="http://ad.doubleclick.net/jump/fc.us468/member/tech;s1=m;s3=tech;pos=1;tag=g;sz=468x60;mtile=1;num=26138?"><IMG SRC="http://ad.doubleclick.net/ad/fc.us468/member/tech;s1=m;s3=tech;pos=1;tag=g;sz=468x60;mtile=1;num=26138?" border=0 height="60" width="468"></A></td><td><img src="http://www.fortunecity.com/console2/newnav/right.gif" width="15" height="60"></td></tr><tr><td><img src="http://www.fortunecity.com/console2/newnav/left2.gif" height="31" width="72" target="_top"></td><td><img src="http://www.fortunecity.com/console2/newnav/gap1.gif" width="17" height="31"></td><td><a href="http://adex3.flycast.com/server/socket/127.0.0.1:2800/click/FortuneCitycom/NavBar1/26138" target="_top"><img src="http://adex3.flycast.com/server/socket/127.0.0.1:2800/ad/FortuneCitycom/NavBar1/26138" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap2.gif" width="24" height="31"></td><td><a href="http://adex3.flycast.com/server/socket/127.0.0.1:2800/click/FortuneCitycom/NavBar2/26138" target="_top"><img src="http://adex3.flycast.com/server/socket/127.0.0.1:2800/ad/FortuneCitycom/NavBar2/26138" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap3.gif" width="24" height="31"></td><td><a href="http://adex3.flycast.com/server/socket/127.0.0.1:2800/click/FortuneCitycom/NavBar3/26138" target="_top"><img src="http://adex3.flycast.com/server/socket/127.0.0.1:2800/ad/FortuneCitycom/NavBar3/26138" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap4.gif" width="19" height="31"></td><td><a href="http://www2.fortunecity.com/cgi-bin/homepage/navbarforward.cgi?from=nav4&referer=navbare" target="_top"><img src="http://www.fortunecity.com/console2/newnav/button4.gif" border="0" width="88" height="31"></a></td><td><img src="http://www.fortunecity.com/console2/newnav/gap5.gif" width="32" height="31"></td><td><img src="http://www.fortunecity.com/console2/newnav/right2.gif" width="15" height="31"></td></tr></table></p></center><!-- WARNING: under no circumstances remove the line below. Doing so may damage your page.--><!-- FC HP BN1 END --><h2><font color="#008080">改变缺省的文件打开/另存为对话框</font></h2><p>在我告诉你如何改变缺省行为前,让我们来看看MFC显示文件打开/另存为对话框的原理。</p><p>当你选择文件菜单下的OPEN选项时,命令消息就转向了CWinApp::OnFileOpen,该函数将通过它的成员m_pDocManager(一个指向CDocManager对象的指针)调用CDocManager::OnFileOpen。后者将调用CDocManager的虚函数DoPromptFileName,并且在成功返回后利用取得的文档路径调用CWinApp::OpenDocumentFile。文件打开对话框就是在虚函数DoPromptFileName中显示的。</p><p>当在保存时,文件保存(或另存为)命令消息将导向CDocument::OnFileSave(或是CDocument::OnFileSaveAs)。在两种情况下CDocument::DoSave都将被调用,它或者使用文件名作为参数(我们正保存一个打开的文档),或者使用NULL作为参数(新文件或另存为)。最后,如果文件名是NULL,CDocument::DoSave调用CWinApp::DoPromptFileName,这将验证m_pDocManager成员并调用CDocManager::DoPromptFileName去显示另存为对话框。</p><p>正如我们所见,CDocManager::DoPromptFileName函数(它是虚的!)担负着显示正常的打开和另存为对话框(一个布尔参数将确定具体显示哪一个)的任务。 </p><p>看起来好像很琐碎,要改变缺省行为,你就得重载CDocManager类中的DoPromptFileName函数,然后告诉应用程序类去使用你自己修改后的CDocManager,而不要使用原来的类。以下的代码演示了一个定制的CDocManager,它将显示一个对话框,该对话框是从CFileDialog繁衍而来:</p><font color="#990000"><tt><pre>// CDocManager class declaration//class CDocManagerEx : public CDocManager{ DECLARE_DYNAMIC(CDocManagerEx)// Constructionpublic: CDocManagerEx();// Attributespublic:// Operationspublic:// Overrides // helper for standard commdlg dialogs virtual BOOL DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate);// Implementationpublic: virtual ~CDocManagerEx();};// DocManager.cpp : implementation file//#include "stdafx.h"#include "PreviewFileDlg.h"#include "DocManager.h" // the header with the class declaration#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifstatic void AppendFilterSuffix(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()) { // 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 } // add to filter 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++; }}/////////////////////////////////////////////////////////////////////////////// CDocManagerExIMPLEMENT_DYNAMIC(CDocManagerEx, CDocManager)CDocManagerEx::CDocManagerEx(){}CDocManagerEx::~CDocManagerEx(){}BOOL CDocManagerEx::DoPromptFileName(CString& fileName, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate){ CPreviewFileDlg dlgFile(bOpenFileDialog); // this is the only modified line! CString title; VERIFY(title.LoadString(nIDSTitle)); dlgFile.m_ofn.Flags |= lFlags; CString strFilter; 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; } } // append the "*.*" all files filter 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++; dlgFile.m_ofn.lpstrFilter = strFilter;#ifndef _MAC dlgFile.m_ofn.lpstrTitle = title;#else dlgFile.m_ofn.lpstrPrompt = title;#endif dlgFile.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH); BOOL bResult = dlgFile.DoModal() == IDOK ? TRUE : FALSE; fileName.ReleaseBuffer(); return bResult;}</tt></font></pre><p>该代码完全从MFC而来,只有一行不得不修改:对话框的声明(当然,这是因为样例对话框是CFileDialog的后代,否则你可能要做更多的修改)。它针对一个在基本功能之上添加了预览功能的对话框。</p><p>AppendFilterSuffix函数将被我们的DoPromptFileName函数调用,并且被逐字地从MFC源程序中拷贝而来。</p><p>关于该类,只有一点还需要说明:如果你想要在打开和存储时使用不同的对话框,你就必须利用bOpenFileDialog这个参数,当它为TRUE时是打开。 </p><p>我们仍然不得不让我们的应用程序使用新的CDocManagerEx,而不是使用缺省的CDocManager类。CWinApp通过它的成员m_pDocManager来使用文档管理器,因此我们需要做的就是正确地初始化这个成员。更近地观察MFC代码显示出CWinApp仅仅在CWinApp::AddDocTemplate中创建该成员所指向的对象,而CWinApp::AddDocTemplate函数仅仅在我们重载的CWinApp::InitInstance函数中被调用。CWinApp::AddDocTemplate仅仅在m_pDocManager成员是NULL时才创建CDocManager对象,因此一旦m_pDocManager指针被正确地初始化了,CWinApp::AddDocTemplate函数就可以安全地被调用了。</p><p>于是,最后的步骤就是在InitInstance函数中,在调用CWinApp::AddDocTemplate函数之前初始化m_pDocManager成员(你甚至可以根本不调用CWinApp::AddDocTemplate而是直接调用m_pDocManager->AddDocTemplate)。</p><p>下面就是这样做的代码:</p><font color="#990000"><tt><pre>BOOL COurApp::InitInstance(){ // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need.#ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL#else Enable3dControlsStatic(); // Call this when linking to MFC statically#endif // Change the registry key under which our settings are stored. // You should modify this string to be something appropriate // such as the name of your company or organization. SetRegistryKey(_T("Local AppWizard-Generated Applications")); LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_DIBTYPE, RUNTIME_CLASS(COurDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(COurView)); ASSERT(m_pDocManager == NULL); m_pDocManager = new CDocManagerEx; m_pDocManager->AddDocTemplate(pDocTemplate); // or just AddDocTemplate(pDocTemplate); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; // Enable drag/drop open m_pMainWnd->DragAcceptFiles(); // Enable DDE Execute open EnableShellOpen(); RegisterShellFileTypes(TRUE); // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line if (!ProcessShellCommand(cmdInfo)) return FALSE; // The main window has been initialized, so show and update it. pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); return TRUE;}</tt></font></pre><p>It was all we needed to change the default file open and file save dialogs. </p><p>这就是我们要改变缺省的文件打开/另存为对话框需要做的所有工作。</p></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -