一种比“ini配置文件”和“注册表”更好用的
保存“初始化信息”的方法
在编写程序时,经常需要将一些初始化信息写入到一个ini配置文件中,当程序启动时从这个配置文件中读取这些初始化信息,当程序关闭时保存当前的设置参数,从而保证用户每次启动程序时的设置都是上一次的设置,方便用户的使用。早期的程序都是将这些初始化信息写入到ini文件中。现在大部分软件都将这些信息写入到注册表中,然后在软件启动时从注册表中读取这些初始化信息。本文介绍一种比以上两种方法更简捷的保存初始化信息的方法——采用CArchive类。用CArchive类来保存初始化信息有简单方便的特点。
一、ini配置文件对初始化信息的读写
(1) 在程序中,如果想向ini配置文件中写入初始化信息,可以使用WritePrivateProfileString()函数来实现。该函数的作用是将一个字符串复制到ini文件的指定段中。WritePrivateProfileString()函数的原型声明为:
BOOL WritePrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpString,
LPCTSTR lpFileName
);
其中各参数的意义
LPCTSTR lpAppName 是INI文件中的一个字段名;
LPCTSTR lpKeyName 是lpAppName下的一个键名,通俗讲就是变量名;
LPCTSTR lpString 是键值,也就是变量的值,不过必须为LPCTSTR型或CString型的;
LPCTSTR lpFileName 是完整的INI文件名。
以保存数据波形显示控件Graph的初始化信息为例,介绍WritePrivateProfileString()函数的用法。
CString str;
str.Format("%f",fScale);
::WritePrivateProfileString("fScale","刻度",str,"设置.ini");
::WritePrivateProfileString("Y_Current","Y轴当前单位",strYCurrent,"设置.ini");
代码分析:以上代码实现的功能是保存数据波形显示控件Graph的显示刻度和Y轴当前单位,其中显示刻度为float类型,Y轴当前单位为CString类型。初始化信息保存在"配置.ini"文件中。显示刻度是float类型,需要首先将其转换成CString类型,然后再通过WritePrivateProfileString()写入到"配置.ini"文件中。而Y轴当前单位作为CString类型,可以直接写入到"配置.ini"文件中。
(2) ini文件的读取,可以通过Win32 API提供的GetPrivateProfileString()函数来实现。
GetPrivateProfileString()函数的原型声明为:
DWORD GetPrivateProfileString(
LPCTSTR lpAppName, //配置文件的section名
LPCTSTR lpKeyName, //配置文件的key名
LPCTSTR lpDefault,
LPTSTR lpReturnedString,
DWORD nSize,
LPCTSTR lpFileName
);
其中各参数的意义:
前二个参数与 WritePrivateProfileString中的意义一样.
lpDefault : 如果INI文件中没有前两个参数指定的字段名或键名,则将此值赋给变量.
lpReturnedString : 接收INI文件中的值的CString对象,即目的缓存器.
nSize : 目的缓存器的大小.
lpFileName : 是完整的INI文件名.
以读取数据波形显示控件Graph的初始化信息为例,介绍GetPrivateProfileString()函数的用法。
CString str;
::GetPrivateProfileString("fScale","刻度","1",str.GetBuffer(64),64,"设置.ini");
fScale=float(atof(str));
::GetPrivateProfileString("Y_Current","Y轴当前单位","",strYCurrent.GetBuffer(64),64,"设置.ini");
代码分析:以上代码实现的功能是读取数据波形显示控件Graph的显示刻度和Y轴当前单位,其中显示刻度为float类型,Y轴当前单位为CString类型。初始化信息保存在"配置.ini"文件中。显示刻度是float类型,通过GetPrivateProfileString()读取到的为CString类型,需要通过atof()函数将其转换成float类型。而Y轴当前单位作为CString类型,不必进行转换。
二、注册表对初始化信息的读写
注册表方式是目前采用较多的保存初始化信息的方法。写入注册表可以通过RegCreateKey()和RegSetValue()函数来实现,读取注册表信息可以通过两次调用RegQueryValue()函数来实现。 关于RegCreateKey()、RegSetValue()及RegQueryValue()函数的原型声明可查看MSDN文件,下面举例介绍读取和写入注册表的方法。
(1) 往注册表写入信息
HKEY hKey;
DWORD dwAge=30;
RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\Yunit",&hKey);
RegSetValue(hKey,NULL,REG_SZ,"mV",strlen("mV"));
RegSetValueEx(hKey,"age",0,REG_DWORD,(CONST BYTE*)&dwAge,4);
RegCloseKey(hKey);
以上代码实现了往注册表中写入dwAge和字符串“mV”的方法。
(2) 读取注册表信息
HKEY hKey;
RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Yunit",&hKey);
DWORD dwType;
DWORD dwValue;
DWORD dwAge;
RegQueryValueEx(hKey,"age",0,&dwType,(LPBYTE)&dwAge,&dwValue);
CString str;
str.Format("age=%d",dwAge);
MessageBox(str);
以上代码从注册表中读取了dwAge并通过MessageBox()函数显示出来。
三、使用CArchive类来保存初始化信息
一个CArchive类是一种二进制流,且与一个文件相关,允许带缓冲机制的数据写入和读取。CArchive类能以一种有效、非冗余的格式处理二进制对象数据。在程序中使用CArchive对象时必须注意:1、在创建CArchive对象之前必须先创建一个CFile类或其派生类对象;2、必须确保这个CFile类对象的打开方式与该存档(archive)对象的加载/保存状态一致;3、一个文件只能与一个活动的存档对象相关联。
CArchive对象不仅可以处理基本类型的数据,还可以处理CObject类的派生类对象。CArchive类重载了提取(>>)和插入(<<)操作符,它们既支持基本类型,也支持CObject类的派生类,为用户提供了一种方便的对象存档编程接口。通过这些重载的函数,我们可以利用CArchive对象来保存和读取程序的初始化信息。
CArchive类的构造函数的原型声明如下:
CArchive(CFile* pFile, UNIT nMode, int nBufSize=4096, void* lpBuf=NULL);
参数pFile:指向文件对象的指针,该文件对象是持久数据的最终来源或目的地;
参数nMode:指定对象是用来被加载的,还是用来保存的标志;
参数nBufSize:指定内部文件缓冲区的大小,以字节为单位。默认的缓冲区大小是4096字节;
参数lpBuf:可选指针,指向用户提供的大小为nBufSize的缓冲区。如果未指定这个参数,则存档对象将从应用程序的局部堆中分配一块缓冲区,并且该对象销毁时将释放这块内存。 下面以数据波形显示控件Graph的初始化信息的保存和读取为例,来说明CArchive类的用法。
(1) 初始化信息的保存
CFile file(“Setting.txt”,CFile::modeWrite|CFile::modeCreate);
CArchive ar(&file,CArchive::store);
ar<
以上三行代码的功能是将数据波形显示控件Graph的显示范围、显示刻度、跟踪阈值、X轴当前单位、X轴单位转换系数、Y轴当前单位、Y轴单位转换系数、线宽、线条颜色、滚轮刻度信息保存在文件Setting.txt中。第一行代码中的|CFile::modeCreate指当文件Setting.txt不存在时,则先创建它。
(2) 初始化信息的读取
CFile file(“Setting.txt”,CFile::modeRead);
CArchive ar(&file,CArchive::load);
ar>>bShowRange>>fScale>>fTrack>>bShowMode>>strXCurrent
>>fXk>>strYCurrent>>fYk>>bLineWidth>>nLineColor>>fWheelScale; 以上三行代码实现的功能是从文件“Setting.txt”中依次读取出数据波形显示控件Graph的显示范围、显示刻度、跟踪阈值、X轴当前单位、X轴单位转换系数、Y轴当前单位、Y轴单位转换系数、线宽、线条颜色、滚轮刻度信息。
四、三种方式的对比
从第三节可以看出,使用CArchive类保存和读取数据波形显示控件Graph的显示范围、显示刻度、跟踪阈值、X轴当前单位、X轴单位转换系数、Y轴当前单位、Y轴单位转换系数、线宽、线条颜色、滚轮刻度信息只用了三行代码。若使用ini配置文件,则读取初始化信息的代码如下:
CString str;
::GetPrivateProfileString("bShowRange","显示方式","1",str.GetBuffer(64),64,"设置.ini");
bShowRange=BOOL(atoi(str));
::GetPrivateProfileString("fTrack","跟踪阈值","1",str.GetBuffer(64),64,"设置.ini");
fTrack=float(atof(str));
::GetPrivateProfileString("fScale","刻度","1",str.GetBuffer(64),64,"设置.ini");
fScale=float(atof(str));
::GetPrivateProfileString("bShowMode","显示模式","0",str.GetBuffer(64),64,"设置.ini");
bShowMode=BOOL(atoi(str));
nLineColor=::GetPrivateProfileInt("nLineColor","曲线颜色",2,"设置.ini");
::GetPrivateProfileString("X_Origin","X轴原单位","",strXOrigin.GetBuffer(64),64,"设置.ini");
::GetPrivateProfileString("Y_Origin","Y轴原单位","",strYOrigin.GetBuffer(64),64,"设置.ini");
::GetPrivateProfileString("X_Current","X轴当前单位","",strXCurrent.GetBuffer(64),64,"设置.ini");
::GetPrivateProfileString("Y_Current","Y轴当前单位","",strYCurrent.GetBuffer(64),64,"设置.ini");
::GetPrivateProfileString("Convert_XK","X轴转换系数","1",str.GetBuffer(64),64,"设置.ini");
fXk=float(atof(str));
::GetPrivateProfileString("Convert_YK","Y轴转换系数","1",str.GetBuffer(64),64,"设置.ini");
fYk=float(atof(str));
代码数量比采用CArchive类多了很多。采用注册表方法的代码量与采用ini配置文件的差不多。可以看出CArchive类保存初始化信息的优势,尤其是当初始化信息量很多的时候,这种优势更为明显。