MFC最近文件列表的使用[转]

mac2022-06-30  65

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;

转载于:https://www.cnblogs.com/Dennis-mi/articles/3385878.html

相关资源:MFC 包括菜单栏,工具栏,配置文件书写,注册表书写及读取
最新回复(0)