我的最近文件这个菜单项总是不起作用,并不显示最近打开的文件。我已经在C...APP里面打开了MFC的MRU功能。在APP类里面重载的OpenDocumentFile这个函数
急哦,搞了几天了,就是不显示出来

解决方案 »

  1.   

    有文参考:   
      http://www.fmdstudio.net/articles/mfcsrc/01912235946.htm   
        
      MFC框架中对最近文件列表的支持   
        
      MFC建立的标准框架程序中有记录最近操作文件的能力,这些最近文件的路径被记录到注册表,在程序运行时,又将添加到文件菜单中。     
        
      在CWinApp中有个   CRecentFileList*   m_pRecentFileList;指针管理这些信息。     
        
      以下对此过程进行分析,采用类似的方法,可以保存其他一些固定条数的最近数据。     
        
        
      1.CRecentFileList对象的建立,记录读入、记录保存、对象销毁。     
        
      ①建立与记录的读入     
        
      如果在CWinApp派生类中InitInstance()中调用了LoadStdProfileSettings,则CRecentFileList被建立,时程序具有管理最近文件列表的能力。     
        
      同时,从注册表中读入以前的记录。     
        
      void   CWinApp::LoadStdProfileSettings(UINT   nMaxMRU)   //缺省为4   
      {   
      ...   
      if   (nMaxMRU   !=   0)   
      {   
      //建立CRecentFileList对象,初始化为管理nMaxMRU条文件信息   
      m_pRecentFileList   =   new   CRecentFileList(0,   _afxFileSection,   _afxFileEntry,nMaxMRU);   
      //读入记录   
      m_pRecentFileList->   ReadList();   
      }   
      ...   
      }   
        
      CRecentFileList对象中的主要数据成员     
        
      CRecentFileList包含一个CString指针   CString*   m_arrNames;   ,它用来指向一个CString对象数组,正是这个数组记录了最近的文件名。     
        
      另外,成员   int   m_nSize   指出了记录的个数。     
        
      在对象创建时,构造函数完成初始化,包括CString数组的建立等。     
        
      ②记录的保存、CRecentFileList的销毁。     
        
      ExitInstance()中将调用SaveStdProfileSettings(),SaveStdProfileSettings()中有m_pRecentFileList->WriteList();操作,完成记录的保存。     
        
      在CWinApp析构时将delete   m_pRecentFileList;销毁对象。     
        
      CRecentFileList::CRecentFileList(UINT   nStart,   LPCTSTR   lpszSection,   
      LPCTSTR   lpszEntryFormat,   int   nSize,   int   nMaxDispLen)   
      {   
      ASSERT(nSize   !=   0);   
      m_arrNames   =   new   CString[nSize];   //建立CString数组。   
      m_nSize   =   nSize;   
        
      m_nStart   =   nStart;   
      m_strSectionName   =   lpszSection;   
      m_strEntryFormat   =   lpszEntryFormat;   
      m_nMaxDisplayLength   =   nMaxDispLen;   
      }   
        
      3.记录的添加     
        
      文档保存时,将调用SetPathName(..),SetPathName(..)中将调用应用程序类中的AddToRecentFileList     
        
      AddToRecentFileList中执行m_pRecentFileList->Add(lpszPathName)将文件名添加到字符串数组     
        
      void   CRecentFileList::Add(LPCTSTR   lpszPathName)   
      {   
      ASSERT(m_arrNames   !=   NULL);   
      ASSERT(lpszPathName   !=   NULL);   
      ASSERT(AfxIsValidString(lpszPathName));   
        
      //   fully   qualify   the   path   name   
      TCHAR   szTemp[_MAX_PATH];   
      AfxFullPath(szTemp,   lpszPathName);     //得到文件全路径   
        
      //   查找,看是否已经有此文件名   
      for   (int   iMRU   =   0;   iMRU   <   m_nSize-1;   iMRU++)   
      {   
      if   (AfxComparePath(m_arrNames[iMRU],   szTemp))   
      break;             //   iMRU   will   point   to   matching   entry   
      }   
      //   其前面的各项后移   
      for   (;   iMRU   >   0;   iMRU--)   
      {   
      ASSERT(iMRU   >   0);   
      ASSERT(iMRU   <   m_nSize);   
      m_arrNames[iMRU]   =   m_arrNames[iMRU-1];   
      }   
      //添加到起始位置   
      m_arrNames[0]   =   szTemp;   
      }   
        
      4.记录的删除     
        
      如果用户从菜单中选择打开某记录对应的文件,单该文件已经不存在,则将删除该无效记录。     
        
      void   CRecentFileList::Remove(int   nIndex)   
      {   
      ASSERT(nIndex   >=   0);   
      ASSERT(nIndex   <   m_nSize);   
        
      m_arrNames[nIndex].Empty();   
      for   (int   iMRU   =   nIndex;   iMRU   <   m_nSize-1;   iMRU++)   
      m_arrNames[iMRU]   =   m_arrNames[iMRU+1];   //其后各项前移   
        
      ASSERT(iMRU   <   m_nSize);   
      m_arrNames[iMRU].Empty();   
      }   
        
      5.记录数据的保存     
      void   CRecentFileList::WriteList()   
      {   
      ASSERT(m_arrNames   !=   NULL);   
      ASSERT(!m_strSectionName.IsEmpty());     //   m_strSectionName   :   _T("Recent   File   List")   
      ASSERT(!m_strEntryFormat.IsEmpty());     //   m_strEntryFormat   :   _T("File%d")       
      LPTSTR   pszEntry   =   new   TCHAR[m_strEntryFormat.GetLength()+5];   
      CWinApp*   pApp   =   AfxGetApp();   
      pApp->   WriteProfileString(m_strSectionName,   NULL,   NULL);   //写入Recent   File   List键   
      for   (int   iMRU   =   0;   iMRU   <   m_nSize;   iMRU++)   
      {   
      wsprintf(pszEntry,   m_strEntryFormat,   iMRU   +   1);     //得到号吗字符串   
      if   (!m_arrNames[iMRU].IsEmpty())   
      {   
      pApp->   WriteProfileString(m_strSectionName,   pszEntry,       //在写值名pszEntry,对应值为文件名。   
      m_arrNames[iMRU]);   
      }   
      }   
      delete[]   pszEntry;   
      }   
        
      6.记录数据的读取     
        
      void   CRecentFileList::ReadList()   
      {   
      ASSERT(m_arrNames   !=   NULL);   
      ASSERT(!m_strSectionName.IsEmpty());   
      ASSERT(!m_strEntryFormat.IsEmpty());   
      LPTSTR   pszEntry   =   new   TCHAR[m_strEntryFormat.GetLength()+5];   
      CWinApp*   pApp   =   AfxGetApp();   
      for   (int   iMRU   =   0;   iMRU   <   m_nSize;   iMRU++)   
      {   
      wsprintf(pszEntry,   m_strEntryFormat,   iMRU   +   1);     //得到值名字符串   
      m_arrNames[iMRU]   =   pApp->   GetProfileString( //取值名下的值,此即个记录,若值不存在,则为NULL   
      m_strSectionName,   pszEntry,   &afxChNil);   
      }   
      delete[]   pszEntry;   
      }   
        
        
      7.将记录添加到菜单项     
        
      菜单资源中文件菜单下有ID为ID_FILE_MRU_FILE1的菜单项,用于在此处添加最近文件菜单项。     
        
      命令更新机制根据ON_UPDATE_COMMAND_UI(ID_FILE_MRU_FILE1,   OnUpdateRecentFileMenu)将经常调用到   
        
      CWinApp::OnUpdateRecentFileMenu(..)     
        
      OnUpdateRecentFileMenu中调用void   CRecentFileList::UpdateMenu(CCmdUI*   pCmdUI)     
        
      void   CRecentFileList::UpdateMenu(CCmdUI*   pCmdUI)   
      {   
      ASSERT(m_arrNames   !=   NULL);   
        
      CMenu*   pMenu   =   pCmdUI->   m_pMenu;   //由pCmdUI直接找到菜单   
      if   (m_strOriginal.IsEmpty()   &&   pMenu   !=   NULL)   
      pMenu->   GetMenuString(pCmdUI->   m_nID,   m_strOriginal,   MF_BYCOMMAND);   
        
      if   (m_arrNames[0].IsEmpty())   
      {   
      //   no   MRU   files   
      if   (!m_strOriginal.IsEmpty())   
      pCmdUI->   SetText(m_strOriginal);   
      pCmdUI->   Enable(FALSE);   
      return;   
      }   
        
      if   (pCmdUI->   m_pMenu   ==   NULL)   
      return;   
        
      for   (int   iMRU   =   0;   iMRU   <   m_nSize;   iMRU++)       //删除所有最新文件菜单项   
      pCmdUI->   m_pMenu->   DeleteMenu(pCmdUI->   m_nID   +   iMRU,   MF_BYCOMMAND);   
        
      TCHAR   szCurDir[_MAX_PATH];   
      GetCurrentDirectory(_MAX_PATH,   szCurDir);   
      int   nCurDir   =   lstrlen(szCurDir);   
      ASSERT(nCurDir   >=   0);   
      szCurDir[nCurDir]   =   '\\';   
      szCurDir[++nCurDir]   =   '\0';   
        
      CString   strName;   
      CString   strTemp;   
      for   (iMRU   =   0;   iMRU   <   m_nSize;   iMRU++)   
      {   
      if   (!GetDisplayName(strName,   iMRU,   szCurDir,   nCurDir))   
      break;   
        
      //   double   up   any   '&'   characters   so   they   are   not   underlined   
      LPCTSTR   lpszSrc   =   strName;   
      LPTSTR   lpszDest   =   strTemp.GetBuffer(strName.GetLength()*2);   
      while   (*lpszSrc   !=   0)   
      {   
      if   (*lpszSrc   ==   '&')   
      *lpszDest++   =   '&';   
      if   (_istlead(*lpszSrc))   
      *lpszDest++   =   *lpszSrc++;   
      *lpszDest++   =   *lpszSrc++;   
      }   
      *lpszDest   =   0;   
      strTemp.ReleaseBuffer();   
        
      //   insert   mnemonic   +   the   file   name   
      TCHAR   buf[10];   
      wsprintf(buf,   _T("&%d   "),   (iMRU+1+m_nStart)   %   10);   
      pCmdUI->   m_pMenu->   InsertMenu(pCmdUI->   m_nIndex++,   
      MF_STRING   |   MF_BYPOSITION,   pCmdUI->   m_nID++,   
      CString(buf)   +   strTemp);     //添加菜单项   
      }   
        
      //   update   end   menu   count   
      pCmdUI->   m_nIndex--;   //   point   to   last   menu   added   
      pCmdUI->   m_nIndexMax   =   pCmdUI->   m_pMenu->   GetMenuItemCount();   
        
      pCmdUI->   m_bEnableChanged   =   TRUE;         //   all   the   added   items   are   enabled   
      }   
        
      8.对最近文件菜单项的相应     
        
      系统通过消息映射   ON_COMMAND_EX_RANGE(ID_FILE_MRU_FILE1,   ID_FILE_MRU_FILE16,   OnOpenRecentFile)     
        
      调用OnOpenRecentFile,命令ID作为参数传入     
        
      BOOL   CWinApp::OnOpenRecentFile(UINT   nID)   
      {   
      ASSERT_VALID(this);   
      ASSERT(m_pRecentFileList   !=   NULL);   
        
      ASSERT(nID   >=   ID_FILE_MRU_FILE1);   
      ASSERT(nID   <   ID_FILE_MRU_FILE1   +   (UINT)m_pRecentFileList->   GetSize());   
      int   nIndex   =   nID   -   ID_FILE_MRU_FILE1;   
      ASSERT((*m_pRecentFileList)[nIndex].GetLength()   !=   0);   
        
      TRACE2("MRU:   open   file   (%d)   '%s'.\n",   (nIndex)   +   1,   
      (LPCTSTR)(*m_pRecentFileList)[nIndex]);   
        
      if   (OpenDocumentFile((*m_pRecentFileList)[nIndex])   ==   NULL)   
      m_pRecentFileList->   Remove(nIndex);   
        
      return   TRUE;