VC中有关最近文件列表的相关操作

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;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值