Chinaunix首页 | 论坛 | 博客
  • 博客访问: 639914
  • 博文数量: 263
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 2555
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-26 11:20
文章分类

全部博文(263)

文章存档

2011年(10)

2010年(19)

2009年(170)

2008年(64)

我的朋友

分类: WINDOWS

2009-11-15 20:01:52

MFC已经在doc/view这样的框架结构程序中封装好MRU功能了,我们只需在程序中稍作修改即可实现菜单“最近文件”的功能。

第一步:

stdafx.h中添加

#include

原因:

CWinApp中已定义了变量:CRecentFileList* m_pRecentFileList;

要用到CRecentFileList就必须声明#include

我们自己就不需再去为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软件中的效果。

再对照比较一下UltraEditMRU文件列表吧:


可见UltraEdit在这个细节上还是多花了一点工夫的哦,呵呵,有兴趣的话再研究一下它的实现吧。

我们再深究一下这些文件名到底存在哪里吧,到注册表中

HKEY_CURRENT_USER\Software\Local AppWizard-Generated Applications\ Your App Name\Recent File List下就可看到这4个文件路径名啦~

在基于Dialog的应用程序中,如果想实现类似的菜单功能,就没这么幸运了,貌似得好好研究MFC中关于recent files文件名列表管理(CRecentFileList)的源代码了,以之为参考自己实现recent菜单。

另可参考:

Adding Most Recently Used (MRU) Files to an SDI/MDI Application  

阅读(1216) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~