VC++的MFC对最近文件进行了包装,它使用户无需编写任何代码就可实现最近文件菜单。但这种方法也有缺陷:①用户程序必须使用文档、视图结构,只能利用它提供的文档打开和保存文件,如果你使用自己编写的函数打开和保存文件,绕过了它的文档,则最近文件将无法使用。
②这种最近文件保存在注册表中,不易清除,容易形成注册表中垃圾,也没有提供用户清除最近文件的权利,不利于用户隐私的保护。
用ini文件实现最近文件可以解决上述问题,而且用编程控制MRU更灵活,可以提供更多功能。
一、ini文件的结构和访问方法
ini文件是纯文本文件,我们可以编程访问它,也可用任一种文本编辑软件打开它。如某RAV.ini文件打开后如下:
[INSTALLED] FWBASE2K=1 FWBASENT=1 ToInstall= CodePage=936 Closed=
[Setup] ShowBgBmp=0
[Skin] Current=1 Path=D:\ProgramFiles\Rising\Rav\Skin\Skin1\Skin.xml
[RAVMON] MONSTATUS=255 |
其中[]括起的称为段,段下面的各部分称为项,访问时用(段名,项名)可访问指定项的值。我们可利用API函数直接读写ini文件。
㈠ 读ini文件中的项值
① 读整数值:
UINT GetPrivateProfileInt(LPCTSTR lpAppName,LPCTSTR lpKeyName,INT nDefault,LPCSTR lpFileName); |
lpAppName为段名,lpKeyName为项名,nDefault为找不到该项时返回的默认值,lpFileName为ini文件名
返回值:若成功,返回指定项后的整数值,若该项不存在,返回nDefault的值
如:读取RAV.ini文件中[INSTALLED]段的FWBASE2K项的值
int FwbBase2K = ::GetPrivateProfileInt("INSTALLED", "FWBASE2K", 0, "RAV.ini"); |
如果[INSTALLED]段的FWBASE2K项存在,则FwbBase2K的值为读出的值,若不存在,则为函数调用中指定的0。
② 读字符串:
DWORD GetPrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpDefault,LPTSTR lpReturnedString,DWORD nSize,LPCTSTR lpFileName); |
lpAppName为段名,lpKeyName为项名,lpDefault为找不到该项时返回的默认值,lpReturnedString指向接收结果的字符串缓冲区,nSize为缓冲区长度,lpFileName为ini文件名
执行结果:若成功,lpReturnedString指示的串中为读出的项值,若该项不存在,lpReturnedString中为lpDefault的值
如:读取RAV.ini文件中[Skin]段的Path项的值
CString PathName;//接收串的变量
::GetPrivateProfileString("Skin", "Path", "", PathName.GetBuffer(MAX_PATH), MAX_PATH, "RAV.ini");
PathName.ReleaseBuffer();//释放多余空间
|
MAX_PATH为系统预定义的常数,其值可能是255。
㈡ 把数据写入ini文件
写入时没有写入整数的函数,只有写入字符串的函数
BOOL WritePrivateProfileString(LPCTSTR lpAppName,LPCTSTR lpKeyName,LPCTSTR lpString,LPCTSTR lpFileName); |
lpAppName为段名,lpKeyName为项名,lpString为写入的字符串,lpFileName为ini文件名
返回值:若成功,返回true,否则返回false
若写入时,该ini文件不存在,则这个函数会自动建立这个文件,并建立相应的段和项。
如:把RAV.ini文件中[INSTALLED]段的FWBASE2K项的值设置为2,由于这是整数,应先转换为字符串后再写入
CString str;
str.Format("%d", 2);//把写入的整数转换为字符串
::WritePrivateProfileString( "INSTALLED", "FWBASE2K", str, "RAV.ini" );//写入ini文件
|
注意:实际应用中,ini文件名应采用绝对路径名,否则可能找不到要读写的ini文件。
二、用ini文件实现最近文件MRU
我设计了一个ini文件MruFile.ini保存最近文件,它的结构如下:
[MruFile] FileNum=当前文件数 1=路径名1 2=路径名2 3=路径名3 4=路径名4 |
[Mru File]为段名,项FileNum为当前Mru文件数,项1、2、3、4放置各Mru文件名。这里只设计了4个最近文件,应用时可根据需要添加。
用ClassWizard添加一个没有基类的新类,名字起为CMruFile,作为MRU文件管理类,在它的头文件中有如下定义:
#defineMAXNUM4//最大MRU文件数
CStringm_IniFileName;//ini文件名 CStringm_PathName[MAXNUM];//MRU文件路径名 intm_CurNum;//当前最近文件数
|
在MruFile.cpp中定义下列函数:
①读取ini文件中的最近文件
voidCMruFile::ReadMru() { m_CurNum=::GetPrivateProfileInt("MruFile","FileNum",0,m_IniFileName);//读取当前文件数 CStringno; for(inti=0;i<m_CurNum;i++) { no.Format("%d",i+1);//求项名 ::GetPrivateProfileString("MruFile",no,"",m_PathName[i].GetBuffer(MAX_PATH), MAX_PATH,m_IniFileName);//读取路径名 m_PathName[i].ReleaseBuffer(); } SetMruMenu();//修改MRU菜单 } |
这个函数在程序一开始就执行,用来把ini文件中的最近文件名读入字符串数组m_PathName中,然后修改最近文件菜单,使它们可以由最近文件菜单选择打开。
②最近文件写入ini文件
voidCMruFile::WriteMru() { CStringno; no.Format("%d",m_CurNum); ::WritePrivateProfileString("MruFile","FileNum",no,m_IniFileName);//写当前文件数 for(inti=0;i<MAXNUM;i++) { no.Format("%d",i+1); ::WritePrivateProfileString("MruFile",no,m_PathName[i],m_IniFileName);//写路径名 } } |
这个函数在用户打开一个文件时执行,用来更新ini文件中的Mru列表。
③添加最近文件
设计思路:当打开的文件名nPathName在m_PathName[]列表中已存在,就把它提升到表头;若它不存在,则添加到表头,如果表已满(本例中最多可添加4个文件名),删除表尾的元素。
voidCMruFile::AddMru(CStringnPathName) { inti; CStringstr1,str2; if(m_CurNum) { if(nPathName.CompareNoCase(m_PathName[0])==0)//如果nPathName已在表头,结束 return; } str1=nPathName; i=0; while(i<m_CurNum&&nPathName.CompareNoCase(m_PathName[i])!=0)//在表中查找,不相等的元素下移 { str2=m_PathName[i]; m_PathName[i]=str1; str1=str2; i++; } if(i<m_CurNum) m_PathName[i]=str1;//nPathName已存在 elseif(m_CurNum<MAXNUM) { m_PathName[m_CurNum]=str1;//表未满 m_CurNum++; }
SetMruMenu();//修改MRU菜单 WriteMru();//最近文件写入ini文件 } |
这个函数也是在用户打开一个文件时执行,并且在WriteMru()函数之前进行,用于更新用数组m_PathName[]保存的Mru列表。
④清除最近文件
voidCMruFile::ClearMru() { m_CurNum=0;//清除最近文件数 for(inti=0;i<MAXNUM;i++) m_PathName[i].Empty();//清空Mru列表 SetMruMenu();//清空Mru菜单 WriteMru();//清空ini文件中的Mru列表 } |
在Mru菜单中有一个“清除最近文件”选项,当用户单击这个菜单项时,执行本函数。这有利于保护用户隐私。
⑤修改最近文件菜单
voidCMruFile::SetMruMenu() { CMenu*pMenu=AfxGetMainWnd()->GetMenu();//主菜单指针 CMenu*pFileMenu=pMenu->GetSubMenu(0);//“文件”菜单指针 CMenu*pMruMenu=pFileMenu->GetSubMenu(5);//“最近文件”菜单指针(5为最近文件菜单项在文件菜单中的位置) pMruMenu->RemoveMenu(ID_MRU1,MF_BYCOMMAND);//删除各菜单项 pMruMenu->RemoveMenu(ID_MRU2,MF_BYCOMMAND); pMruMenu->RemoveMenu(ID_MRU3,MF_BYCOMMAND); pMruMenu->RemoveMenu(ID_MRU4,MF_BYCOMMAND); if(m_CurNum>0)//重新插入各菜单项 pMruMenu->InsertMenu(ID_MRU_CLR,MF_BYCOMMAND, ID_MRU1,m_PathName[0]); if(m_CurNum>1) pMruMenu->InsertMenu(ID_MRU_CLR,MF_BYCOMMAND, ID_MRU2,m_PathName[1]); if(m_CurNum>2) pMruMenu->InsertMenu(ID_MRU_CLR,MF_BYCOMMAND, ID_MRU3,m_PathName[2]); if(m_CurNum>3) pMruMenu->InsertMenu(ID_MRU_CLR,MF_BYCOMMAND, ID_MRU4,m_PathName[3]); } |
当Mru文件列表发生变化时调用此函数。Mru菜单是一个可以修改的动态菜单,它的菜单项数目随着Mru文件数的变化而变化,菜单内容也随着Mru列表的内容变化而变化。
在这里ID_MRU1~ID_MRU4和ID_MRU_CLR是各菜单项的ID号,它们需事先在资源的字符串表中进行定义。
这样,一个用ini文件管理的最近文件类就做好了。使用时,在程序的打开文件OnFileOpen()函数和另存为OnFileSaveAs()函数调用这个类的相关函数就可以管理最近文件了。
详细用法可参考示例程序。
示例程序界面:
本文所用MFC函数和API函数速查:
CMenu::GetSubMenu
CMenu::InsertMenu
CMenu::RemoveMenu
CString::CompareNoCase
CString::Empty
CString::Format
CString::GetBuffer
CString::ReleaseBuffer
CWnd::GetMenu
::GetPrivateProfileInt
::GetPrivateProfileString
::WritePrivateProfileString
http://221.199.150.103/jsj/Html/vc/wen/vcwen04.htm
分享到:
相关推荐
VC 的MFC对最近文件进行了包装,它使用户无需编写任何代码就可实现最近文件菜单。但这种方法也有缺陷: ... 用ini文件实现最近文件可以解决上述问题,而且用编程控制MRU更灵活,可以提供更多功能。
内容索引:VC/C++源码,文件操作,ini,记忆菜单 VC++的MFC对最近文件进行了包装,它使用户无需编写任何代码就可实现最近文件... 用ini文件实现最近文件可以解决上述问题,而且用编程控制MRU更灵活,可以提供更多功能。
MRU-caches:最近使用的缓存实现
MRU 一种cache的算法 MRU 一种cache的算法 MRU 一种cache的算法
VisualStudio MRU管理工具,可以查看和删除最近使用的文件和项目. VSRecentExplorer1.0(带C# 源代码VS2008编译)
ctrlp.vim, 模糊文件缓冲区mru 标签等查找器 这个项目不维护你应该使用这个 fork 。 ctrlp.vim全路径模糊 file,mru,mru,tag 。 Vim的查找器。用于 MacVim,gVim和 Vim 7.0 的纯 Vimscript 。完全支持vim作为搜
关于乙二醇再生及回收系统(MRU)的几点思考,关于乙二醇再生及回收系统(MRU)的几点思考课件,关于乙二醇再生及回收系统(MRU)的几点思考PPT
实施WPF / MVVM控件库(带有后端),该库管理最近使用的文件列表。
MRU Manual.pdf
工具桌面 Linux MRU 取证工具MRUTools 是一个基于插件的桌面 Linux 工具(kde、gnome 等)。 每个插件从某些应用程序或桌面中提取 MRU 信息。 该应用程序尚处于(早期)积极开发阶段。 可用功能: 编写的三个实际...
vim文件MRU文件通过quickfix,fzf.vim和vim-clap支持Vim / NeoVim。
Another MRU retreive.
我喜欢FZF模糊搜索算法和CtrlP Mru跟踪-我经常使用它在两个文件之间跳转(是的,我知道<c> )。 fzf-vim的:History工作方式对我而言不是最佳的解决方案,这就是为什么我决定创建此插件的原因。 它需要fzf 。 安装...
C#中.NET 2.0的最近使用的文件类
MMR 5000 MRU 子系统软件概要设计
在最近使用的订单中的选项卡之间切换,窗口上的Chrome允许您将Ctrl +选项卡设置为快捷方式 'Ctrl + Tab MRU'允许按顺序切换通过选项卡以前访问过。默认情况下,通过按Ctrl + Y按时间返回到时间和其他方式回归+ y。**...
它能彻底删除您在线和脱机活动的隐私记录(例如 internet 临时文件、历史记录、cookie、自动完成的表格和密码、交换文件、最近打开的文档列表、Explorer MRU、临时文件等等),追溯 200 多个第三方应用程序,并释放...
MRUFiles Version 1.14 (August 16, 2003) This component can be used to hold a list of the most recently used files (or other items) and show them on a menu.
LRU(最近最少使用算法) and MRU(最近最常使用算法)所谓的LRU(Least recently used)算法的基本概念是:当内存的剩余的可用空间不够时,缓冲区尽可能的先保留使用者最常使用的数据,换句话说就是优先清除”较不常使用的...