在MFC(Microsoft Foundation Classes)应用程序中,实现一个文档模板(CDocTemplate)来管理文档的创建、打开和保存是常见的做法。而最近使用(MRU)文件列表功能,允许用户快速访问最近打开过的文件。本文将介绍如何在MFC应用程序中为每种文档类型实现独立的MRU列表。
文档模板是MFC中用于创建和管理文档的类。它负责将文档类、视图类和框架窗口类联系起来。MRU列表则是一种方便用户快速访问最近打开过的文件的功能。在标准的MFC应用程序中,通常只有一个全局的MRU列表。但是,有时候可能需要为不同类型的文档实现独立的MRU列表。
实现独立的MRU列表需要对文档模板类进行扩展。以下是实现步骤的详细说明:
首先,需要创建一个继承自CDocTemplate的类,称之为CDocTemplateEx。这个类将包含MRU列表的功能。
// DocTemplateEx.h
class CDocTemplateEx : public CDocTemplate
{
public:
CDocTemplateEx(UINT nIDResource, CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass);
virtual ~CDocTemplateEx();
// 其他成员函数和数据成员...
};
在这个类中,需要添加成员变量来存储MRU列表的ID和最大文件数。
在MFC中,消息路由机制用于将命令消息分发到适当的处理函数。为了支持独立的MRU列表,需要修改CDocTemplateEx类的消息路由函数OnCmdMsg。
BOOL CDocTemplateEx::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// 消息处理代码...
}
在这个函数中,需要根据消息的ID来决定是否处理MRU列表的命令。
MRU列表需要在程序启动和关闭时保存和加载。这通常通过覆盖CDocTemplate的Serialize函数来实现。
void CDocTemplateEx::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// 保存MRU列表...
}
else
{
// 加载MRU列表...
}
}
在这个函数中,可以使用注册表或文件来存储MRU列表。
为了支持MRU列表,需要修改文档类,使其在打开和保存文件时更新MRU列表。
void CMyDoc::SetPathName(LPCTSTR lpszPathName, BOOL bAddToMRU)
{
CDocument::SetPathName(lpszPathName, FALSE);
CDocTemplateEx* pDocTemplate = (CDocTemplateEx*)GetDocTemplate();
pDocTemplate->AddToRecentFileList(lpszPathName);
}
在这个函数中,调用文档模板的AddToRecentFileList函数来更新MRU列表。
在应用程序类中,需要修改OnCmdMsg函数,以确保即使没有打开的文档,也能处理MRU列表的命令。
BOOL CMyApp::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
BOOL bResult = CWinApp::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
if (bResult)
return TRUE;
// 处理MRU列表命令...
return bResult;
}
在这个函数中,需要遍历所有的文档模板,检查是否有模板可以处理当前的命令ID。
在资源编辑器中,需要为每种文档类型创建MRU列表的菜单项。同时,需要在字符串表中添加对应的字符串资源。
例如,如果有一个文档类型的ID是ID_FILE_DOC1_MRU1,那么它的字符串资源可能是"打开此文件"。
为了禁用默认的MRU处理,需要在应用程序的InitInstance函数中调用CWinApp::LoadStdProfileSettings,传入0作为参数。同时,需要从资源菜单中删除默认的MRU菜单项。
BOOL CMyApp::InitInstance()
{
// 禁用默认的MRU处理...
return CWinApp::InitInstance();
}