您的位置:首页 > 其它

实现菜单“最近文件”的功能

2008-09-16 14:43 246 查看
2008-07-28 19:55
MFC已经在doc/view这样的框架结构程序中封装好MRU功能了,我们只需在程序中稍作修改即可实现菜单“最近文件”的功能。
第一步:
在stdafx.h中添加
#include <afxadv.h>
原因:
CWinApp中已定义了变量:CRecentFileList* m_pRecentFileList;
要用到CRecentFileList就必须声明#include <afxadv.h>。
我们自己就不需再去为CRecentFileList定义变量了,而可以直接使用m_pRecentFileList。

第二步:
由于MFC程序默认并不打开MRU List File功能。所以在此需打开该功能,即添加LoadStdProfileSettings();函数。
该函数原型为:
void LoadStdProfileSettings(UINT nMaxMRU = _AFX_MRU_COUNT);
系统中定义的 _AFX_MRU_COUNT 见下:
#define _AFX_MRU_COUNT 4 // default support for 4 entries in file MRU
大多数软件都是采用默认的显示4个文件名,所以此处也就用默认的数目吧。
BOOL CDrawingApp::InitInstance()
{
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
// To enable and load the list of MRU files and last preview state.
LoadStdProfileSettings();
}

第三步
程序中每成功打开文件后就把该文件路径名加至MRU files list
如我在CXXApp:: OnFileOpen ()中添加:
// Add (or move) to the top of the MRU list in the File menu.

AddToRecentFileList(strFilePathName );

再添加如下函数(可用ClassWizard产生):
void CXXApp::AddToRecentFileList(LPCTSTR lpszPathName)
{
// lpszPathName will be added to the top of the MRU list.
// If lpszPathName already exists in the MRU list, it will be moved to the top
if (m_pRecentFileList != NULL)
m_pRecentFileList->Add(lpszPathName);
}
当然了,如果打开文件的函数若没放在CXXApp中,如放在CXXDoc中,就得用如下语句了:
BOOL CXXDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;

// Add to MRU file list
((CXXApp*)AfxGetApp())->AddToRecentFileList(lpszPathName);

return TRUE;
}
BOOL CXXDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
// Add to MRU file list
((CXXApp*)AfxGetApp())->AddToRecentFileList(lpszPathName);

return CDocument::OnSaveDocument(lpszPathName);
}
第四步:
下面再添加菜单响应的代码:
在XXApp.h中(或MainFrm.h中)
//{{AFX_MSG(CDrawingApp)

afx_msg void OnFileMruFile( UINT nID );
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

在XXApp.cpp中(或MainFrm.cpp中)

BEGIN_MESSAGE_MAP(CDrawingApp, CWinApp)
//{{AFX_MSG_MAP(CDrawingApp)

ON_COMMAND_RANGE(ID_FILE_MRU_FILE1 , ID_FILE_MRU_FILE4, OnFileMruFile)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CXXApp::OnFileMruFile( UINT nID )
{
int nMRUIndex = 0;
switch (nID) {
case ID_FILE_MRU_FILE1:
nMRUIndex = 0;
break;
case ID_FILE_MRU_FILE2:
nMRUIndex = 1;
break;
case ID_FILE_MRU_FILE3:
nMRUIndex = 2;
break;
case ID_FILE_MRU_FILE4:
nMRUIndex = 3;
break;
}

CString sFilePathName;
sFilePathName = (*m_pRecentFileList)[nMRUIndex];
//上一句也可换为 sFilePathName = m_pRecentFileList->m_arrNames[nMRUIndex];
// 下面就可以添上自己的函数吧,比如打开文件
// OpenFile ( sFilePathName );
……
}

第五步:
检查你的工程资源文件中“文件”菜单栏中是否有“ID_FILE_MRU_FILE1”这个菜单项,若没有,就加上这个ID,并令其名称为“最近文件”,还得上下加个Separator哦,见下图:



好了,到此就完成添加菜单“最近文件”的功能。

下面是运行的结果示例图:



这种样式也就是Word软件中的效果。
再对照比较一下UltraEdit的MRU文件列表吧:



可见UltraEdit在这个细节上还是多花了一点工夫的哦,呵呵,有兴趣的话再研究一下它的实现吧。
我们再深究一下这些文件名到底存在哪里吧,到注册表中
HKEY_CURRENT_USER/Software/Local AppWizard-Generated Applications/ Your App Name/Recent File List下就可看到这4个文件路径名啦~
在基于Dialog的应用程序中,如果想实现类似的菜单功能,就没这么幸运了,貌似得好好研究MFC中关于recent files文件名列表管理(CRecentFileList)的源代码了,以之为参考自己实现recent菜单。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: