MFC 多文档中同时打开多个文档

MFC多文档中的打开继承自CWinAppEx中的函数OnFileOpen(),这一点在CXXX.cpp中可以看到。比如如下:

[cpp]  view plain  copy
  1. // CCVMFCApp  
  2.   
  3. BEGIN_MESSAGE_MAP(CCVMFCApp, CWinAppEx)  
  4.     ON_COMMAND(ID_APP_ABOUT, &CCVMFCApp::OnAppAbout)  
  5.     // 基于文件的标准文档命令  
  6.     ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)  
  7.     ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)  
  8.     // 标准打印设置命令  
  9.     ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinAppEx::OnFilePrintSetup)  
  10. END_MESSAGE_MAP()  

中的 ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)

它默认的只能打开一个文档,那如果想打开多个文档肿么办呢?

这里给一个辅助类MutiOpenDocManager,代码如下:

MutiOpenDocManager.h:

[cpp]  view plain  copy
  1. // MutiOpenDocManager.h: interface for the CMutiOpenDocManager class.  
  2. //  
  3. //  
  4.   
  5. #if !defined(AFX_MUTIOPENDOCMANAGER_H__8E7F5957_C207_4C9E_BA92_979203C32025__INCLUDED_)  
  6. #define AFX_MUTIOPENDOCMANAGER_H__8E7F5957_C207_4C9E_BA92_979203C32025__INCLUDED_  
  7.   
  8. #if _MSC_VER > 1000  
  9. #pragma once  
  10. #endif // _MSC_VER > 1000  
  11.   
  12. class CMutiOpenDocManager : public CDocManager    
  13. {  
  14. public:  
  15.     virtual BOOL DoPromptFileNames(CStringList& fileNames,UINT nIDSTitle,DWORD lFlags,BOOL bOpenFileDialog,CDocTemplate* pTemplate);  
  16.     virtual void OnFileOpen();  
  17.     CMutiOpenDocManager();  
  18.     virtual ~CMutiOpenDocManager();  
  19.     void AppendFilterSuffix(CString &filter, OPENFILENAME &ofn, CDocTemplate *pTemplate, CString *pstrDefaultExt);  
  20.   
  21. };  
  22.   
  23. #endif // !defined(AFX_MUTIOPENDOCMANAGER_H__8E7F5957_C207_4C9E_BA92_979203C32025__INCLUDED_)  

MutiOpenDocManager.cpp:

[cpp]  view plain  copy
  1. // MutiOpenDocManager.cpp: implementation of the CMutiOpenDocManager class.  
  2. //  
  3. //  
  4.   
  5. #include "stdafx.h"  
  6. #include "MutiOpenDocManager.h"  
  7.   
  8. #ifdef _DEBUG  
  9. #undef THIS_FILE  
  10. static char THIS_FILE[]=__FILE__;  
  11. #define new DEBUG_NEW  
  12. #endif  
  13.   
  14. //  
  15. // Construction/Destruction  
  16. //  
  17.   
  18. CMutiOpenDocManager::CMutiOpenDocManager()  
  19. {  
  20.   
  21. }  
  22.   
  23. CMutiOpenDocManager::~CMutiOpenDocManager()  
  24. {  
  25.   
  26. }  
  27.   
  28. void CMutiOpenDocManager::OnFileOpen()  
  29. {  
  30.     CStringList newNames;  
  31.     if(!DoPromptFileNames(newNames,AFX_IDS_OPENFILE,OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT,TRUE,NULL))  
  32.         return;  
  33.     POSITION pos=newNames.GetHeadPosition();  
  34.     while(pos)  
  35.     {  
  36.         CString newName=newNames.GetNext(pos);  
  37.         AfxGetApp()->OpenDocumentFile(newName);  
  38.     }  
  39.   
  40. }  
  41.   
  42. BOOL CMutiOpenDocManager::DoPromptFileNames(CStringList& fileNames, UINT nIDSTitle, DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate *pTemplate)  
  43. {  
  44.     CFileDialog dlgFile(bOpenFileDialog);  
  45.   
  46.     CString title;  
  47.     VERIFY(title.LoadString(nIDSTitle));  
  48.   
  49.     dlgFile.m_ofn.Flags |= lFlags;  
  50.   
  51.     CString strFilter;  
  52.     CString strDefault;  
  53.     if (pTemplate != NULL)  
  54.     {  
  55.         ASSERT_VALID(pTemplate);  
  56.         AppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate, &strDefault);  
  57.     }  
  58.     else  
  59.     {  
  60.         // do for all doc template  
  61.         POSITION pos = m_templateList.GetHeadPosition();  
  62.         BOOL bFirst = TRUE;  
  63.         while (pos != NULL)  
  64.         {  
  65.             CDocTemplate* pTemplate = (CDocTemplate*)m_templateList.GetNext(pos);  
  66.             AppendFilterSuffix(strFilter, dlgFile.m_ofn, pTemplate,  
  67.                 bFirst ? &strDefault : NULL);  
  68.             bFirst = FALSE;  
  69.         }  
  70.     }  
  71.   
  72.     // append the "*.*" all files filter  
  73.     CString allFilter;  
  74.     VERIFY(allFilter.LoadString(AFX_IDS_ALLFILTER));  
  75.     strFilter += allFilter;  
  76.     strFilter += (TCHAR)'\0';   // next string please  
  77.     #ifndef _MAC  
  78.     strFilter += _T("*.*");  
  79.     #else  
  80.     strFilter += _T("****");  
  81.     #endif  
  82.     strFilter += (TCHAR)'\0';   // last string  
  83.     dlgFile.m_ofn.nMaxCustFilter++;  
  84.     dlgFile.m_ofn.lpstrFilter = strFilter;  
  85.   
  86.     #ifndef _MAC  
  87.     dlgFile.m_ofn.lpstrTitle = title;  
  88.     #else  
  89.     dlgFile.m_ofn.lpstrPrompt = title;  
  90.     #endif  
  91.   
  92.     CString strFileNames;  
  93.     dlgFile.m_ofn.lpstrFile=strFileNames.GetBuffer(2048);  
  94.     dlgFile.m_ofn.nMaxFile=2048;  
  95.     BOOL bResult=dlgFile.DoModal()==IDOK?TRUE:FALSE;  
  96.     strFileNames.ReleaseBuffer();  
  97.     if(!bResult)  
  98.         return FALSE;//取消打开文件操作  
  99.     //将文件名拷贝到一个字符串列表中  
  100.     POSITION pos=dlgFile.GetStartPosition();  
  101.     while(pos)  
  102.     {  
  103.         fileNames.AddTail(dlgFile.GetNextPathName(pos));  
  104.     }  
  105.     return  
  106.         TRUE;  
  107. }  
  108.   
  109. //下面的函数是DoPromptFileNames函数中需要调用的模块函数  
  110. void CMutiOpenDocManager::AppendFilterSuffix(CString &filter, OPENFILENAME &ofn, CDocTemplate *pTemplate, CString *pstrDefaultExt)  
  111. {  
  112.     ASSERT_VALID(pTemplate);  
  113.     ASSERT_KINDOF(CDocTemplate, pTemplate);  
  114.   
  115.     CString strFilterExt, strFilterName;  
  116.     if (pTemplate->GetDocString(strFilterExt, CDocTemplate::filterExt) &&  
  117.      !strFilterExt.IsEmpty() &&  
  118.      pTemplate->GetDocString(strFilterName, CDocTemplate::filterName) &&  
  119.      !strFilterName.IsEmpty())  
  120.     {  
  121.         // a file based document template - add to filter list  
  122.         ASSERT(strFilterExt[0] == '.');  
  123.         if (pstrDefaultExt != NULL)  
  124.         {  
  125.             // set the default extension  
  126.             *pstrDefaultExt = ((LPCTSTR)strFilterExt) + 1;  // skip the '.'  
  127.             ofn.lpstrDefExt = (LPTSTR)(LPCTSTR)(*pstrDefaultExt);  
  128.             ofn.nFilterIndex = ofn.nMaxCustFilter + 1;  // 1 based number  
  129.         }  
  130.   
  131.         // add to filter  
  132.         filter += strFilterName;  
  133.         ASSERT(!filter.IsEmpty());  // must have a file type name  
  134.         filter += (TCHAR)'\0';  // next string please  
  135.         filter += (TCHAR)'*';  
  136.         filter += strFilterExt;  
  137.         filter += (TCHAR)'\0';  // next string please  
  138.         ofn.nMaxCustFilter++;  
  139.     }  
  140. }  

然后再在CXXX.cpp的一个位置插入一句话!至关重要:

[cpp]  view plain  copy
  1. BOOL CCVMFCApp::InitInstance()  
  2. {  
  3.     // 如果一个运行在 Windows XP 上的应用程序清单指定要  
  4.     // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,  
  5.     //则需要 InitCommonControlsEx()。否则,将无法创建窗口。  
  6.     INITCOMMONCONTROLSEX InitCtrls;  
  7.     InitCtrls.dwSize = sizeof(InitCtrls);  
  8.     // 将它设置为包括所有要在应用程序中使用的  
  9.     // 公共控件类。  
  10.     InitCtrls.dwICC = ICC_WIN95_CLASSES;  
  11.     InitCommonControlsEx(&InitCtrls);  
  12.   
  13.     CWinAppEx::InitInstance();  
  14.   
  15.     // 初始化 OLE 库  
  16.     if (!AfxOleInit())  
  17.     {  
  18.         AfxMessageBox(IDP_OLE_INIT_FAILED);  
  19.         return FALSE;  
  20.     }  
  21.     AfxEnableControlContainer();  
  22.     // 标准初始化  
  23.     // 如果未使用这些功能并希望减小  
  24.     // 最终可执行文件的大小,则应移除下列  
  25.     // 不需要的特定初始化例程  
  26.     // 更改用于存储设置的注册表项  
  27.     // TODO: 应适当修改该字符串,  
  28.     // 例如修改为公司或组织名  
  29.     SetRegistryKey(_T("应用程序向导生成的本地应用程序"));  
  30.     LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)  
  31.   
  32.     InitContextMenuManager();  
  33.   
  34.     InitKeyboardManager();  
  35.   
  36.     InitTooltipManager();  
  37.     CMFCToolTipInfo ttParams;  
  38.     ttParams.m_bVislManagerTheme = TRUE;  
  39.     theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,  
  40.         RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);  
  41.   
  42.     // 注册应用程序的文档模板。文档模板  
  43.     // 将用作文档、框架窗口和视图之间的连接  
  44.     CMultiDocTemplate* pDocTemplate;  
  45.     m_pDocManager = new CMutiOpenDocManager;//注意必须在此位置添加此句  
  46.   
  47.     pDocTemplate = new CMultiDocTemplate(IDR_CVMFCTYPE,  
  48.         RUNTIME_CLASS(CCVMFCDoc),  
  49.         RUNTIME_CLASS(CChildFrame), // 自定义 MDI 子框架  
  50.         RUNTIME_CLASS(CCVMFCView));  
  51.     if (!pDocTemplate)  
  52.         return FALSE;  
  53.     AddDocTemplate(pDocTemplate);  
  54.   
  55.     // 创建主 MDI 框架窗口  
  56.     CMainFrame* pMainFrame = new CMainFrame;  
  57.     if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))  
  58.     {  
  59.         delete pMainFrame;  
  60.         return FALSE;  
  61.     }  
  62.     m_pMainWnd = pMainFrame;  
  63.     // 仅当具有后缀时才调用 DragAcceptFiles  
  64.     //  在 MDI 应用程序中,这应在设置 m_pMainWnd 之后立即发生  
  65.   
  66.   
  67.     // 分析标准外壳命令、DDE、打开文件操作的命令行  
  68.     CCommandLineInfo cmdInfo;  
  69.     ParseCommandLine(cmdInfo);  
  70.   
  71.   
  72.     // 调度在命令行中指定的命令。如果  
  73.     // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。  
  74.     if (!ProcessShellCommand(cmdInfo))  
  75.         return FALSE;  
  76.     // 主窗口已初始化,因此显示它并对其进行更新  
  77.     pMainFrame->ShowWindow(m_nCmdShow);  
  78.     pMainFrame->UpdateWindow();  
  79.   
  80.     return TRUE;  
  81. }  

注意45行的那句话,这是因为在创建类实例的时候将文档类定义为MutiOpenDocManager类,就可以使用其中的打开函数了。



当然,如果工程是对话框就更好办了,直接把onopen函数写成这样即可打开多个文档:

[cpp]  view plain  copy
  1. void CCFileDialogST_demoDlg::OnOpen()   
  2. {  
  3.     CFileDialogST   dlg(TRUE, NULL, NULL, /*OFN_HIDEREADONLY | */OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT, _T("All files\0*.*\0"), this);  
  4.     CString         sPathName;  
  5.     int             nRetValue;  
  6.   
  7.     nRetValue = dlg.DoModal();  
  8.     if (nRetValue == IDOK)  
  9.     {  
  10.         POSITION    Pos;  
  11.   
  12.         Pos = dlg.GetStartPosition();  
  13.         while (Pos != NULL)  
  14.         {  
  15.             sPathName = dlg.GetNextPathName(Pos);  
  16.             MessageBox(sPathName, _T("GetNextPathName"), MB_ICONINFORMATION);  
  17.         }   
  18.     } // if  
  19. // End of OnOpen  
from: http://blog.csdn.net/abcjennifer/article/details/7441354
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在MFC文档文件视图添加鼠标点击文件打开功能,需要进行以下步骤: 1. 在资源编辑器打开主窗口的菜单资源,并添加一个菜单项,命名为“打开文件”(或者其他你喜欢的名称)。 2. 在主窗口的消息映射函数添加该菜单项的响应函数,以便用户点击该菜单项时能够打开文件对话框并选择要打开的文件。代码示例如下: ``` void CMainFrame::OnOpenFile() { CString filter = _T("文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*||"); CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, filter, this); if (dlg.DoModal() == IDOK) { CString filePath = dlg.GetPathName(); OpenDocumentFile(filePath); } } ``` 3. 在主窗口类的头文件声明该响应函数。 4. 在多文档应用程序的文档添加打开文件的函数,以便打开并显示所选文件。代码示例如下: ``` BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; CFile file; if (!file.Open(lpszPathName, CFile::modeRead | CFile::typeText)) return FALSE; CArchive ar(&file, CArchive::load); Serialize(ar); SetModifiedFlag(FALSE); return TRUE; } ``` 5. 最后,在多文档应用程序的视图类添加响应鼠标点击事件的函数。在该函数调用主窗口的打开文件响应函数,以便用户能够通过鼠标点击实现打开文件功能。代码示例如下: ``` void CMyView::OnLButtonDown(UINT nFlags, CPoint point) { CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd(); pMainFrame->OnOpenFile(); CView::OnLButtonDown(nFlags, point); } ``` 以上就是在MFC文档文件视图添加鼠标点击文件打开功能的完整步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值