12.6.1Win.ini文件的结构
现在大部分软件将信息写入注册表中,然后在软件启动时,从注册表中读取这些初始化信息。但是早期的一些程序都是将这些初始化信息写入Win.ini文件中,该文件位于系统安装根目录下的Wi目录下。
12.6.2Win.ini文件的写入
在程序中,如果想要向Win.ini文件写入一些初始化信息,可以使用WriteProfileString函数来实现。该函数的作用是将一个字符串复制到Win.ini文件指定段中。
BOOL WriteProfileString(
LPCTSTR lpAppName, // 段名的地址,如果段名存在就创建它
LPCTSTR lpKeyName, // 键名,如果这个键指定的段不存在就创建改键。如果为NULL,则段中所有项都要删除。
LPCTSTR lpString // 指向要写入的字符串,若为NULL,那么第二个参数指定的键将会删除。
);
然后在CFileApp类的InitInstance函数中,在SetRegistryKey函数之后调用WriteProfileString函数:
::WriteProfileString(“vc++”,“admin”,“zhangsan”);
12.6.3Win.ini文件的读取
要想获取Win.ini文件中保存的信息,可以利用Win32API提供的GetProFileString函数来实现。
DWORD GetProfileString(
LPCTSTR lpAppName, //指向段
LPCTSTR lpKeyName, //指向键
LPCTSTR lpDefault, //指向一个默认字符串
LPTSTR lpReturnedString, //指向缓冲区的指针
DWORD nSize //所指向缓冲区大小
);
将WriteProfileString函数调用注释起来,然后在其后添加如下代码:
CString str;
::GetProfileString(“vc++”,“admin”,“lisi”,str.GetBuffer(100),100);
AfxMessageBox(str);
运行结果如图。
调用AfxMessageBox(str);函数是因为CWinApp类不是有CWnd类派生而来的,没有Message函数。因此需要使用该全局函数。
CWinApp中也有GetProfileString和WriteProfileString函数,那么与Win32API中的函数有什么区别?
调用CWinApp类的函数之后,是将信息写入注册表中,而不是Win.ini文件中。
CWinApp类的WriteProfileString函数:
BOOL WriteProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszValue );
将之前的代码注释起来,然后在原处添加以下代码:
WriteProfileString(“vc++”,“admin”,“zhangsan”);
运行之后,注册表中结果如图。
CWinApp类的GetProfileString函数:
CString GetProfileString( LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszDefault = NULL );
有三个参数分别指定要读取的段名、项名和项的默认值。返回从注册表或者Win.ini文件中获得的字符串。
将之前的代码注释起来,然后添加:
CString str;
str=GetProfileString(“vc++”,“admin”);
AfxMessageBox(str);
12.7注册表的编程
12.7.1注册表API
1、创建键
RegCreateKey函数将创建指定注册表项,如果这个表项已经存在,则该函数将打开这个表项。
LONG RegCreateKey(
HKEY hKey, // 指向打开表项的句柄
LPCTSTR lpSubKey, // 指示打开或者创建表项的名字
PHKEY phkResult // 接收打开的表项的句柄
);
2、打开键
利用RegOpenKey函数打开指定注册表项:
LONG RegOpenKey(
HKEY hKey, // 指向打开表项的句柄
LPCTSTR lpSubKey, // 指示打开或者创建表项的名字
PHKEY phkResult // 接收打开的表项的句柄
);
3、写入注册表
RegSetValue函数可以设置指定注册表项的默认值或者未命名值的数据。在注册表中,对值来说,包含三个部分:值名称,值类型和值本身。
LONG RegSetValue(
HKEY hKey, // 指向打开表项的句柄
LPCTSTR lpSubKey, // 指示打开或者创建表项的名字
DWORD dwType, // 存储信息类型,必须是REG_SZ,也就是字符串类型。如果要存储其他类型,就要使用另一个函数RegSetValueEx。
LPCTSTR lpData, // 指定设置默认值的数据
DWORD cbData // 数据的大小
);
如果想要设置注册表项下不是默认值,即有名称值的数据和类型时,可以调用RegSetValueEx函数
LONG RegSetValueEx(
HKEY hKey,
LPCTSTR lpValueName, // 设置值的名称
DWORD Reserved, // reserve必须为0
DWORD dwType,
CONST BYTE *lpData,
DWORD cbData
);
4、从注册表中读数据
RegQueryValue函数获得指定注册表默认的值或未命名的值。
LONG RegQueryValue(
HKEY hKey,
LPCTSTR lpSubKey,
LPTSTR lpValue, // 指向获得的字符串
PLONG lpcbValue // 指向获得的字符串的长度
);
同样地如果想要读取的注册表项下不是默认值,得调用RegQueryValueEx:
LONG RegQueryValueEx(
HKEY hKey,
LPTSTR lpValueName, // 想要查询值的名称
LPDWORD lpReserved, // 必须为NULL
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
);
12.7.2注册表访问示例
为File程序再增加两个菜单项,并添加相应的命令消息响应函数:
Caption:写注册表和读注册表
ID:IDM_REG_WRITE、IDM_REG_READ
首先在OnRegWrite函数中:
void CFileView::OnRegWrite()
{
// TODO: Add your command handler code here
HKEY hKey; RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\vc++6.0\\admin",&hKey); RegSetValue(hKey,NULL,REG_SZ,"zhangsan",strlen("zhangsan"));
RegCloseKey(hKey);
}
注册表下写入软件信息一般在HKEY_LOCAL_MACHINE分支下,Software\vc++6.0\admin指定注册表项的子项,注册表项的值为zhangsan。
现在在OnRegRead函数中添加:
void CFileView::OnRegRead()
{
// TODO: Add your command handler code here
LONG lValue;
RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",NULL,&lValue);
char *pBuf=new char[lValue];
RegQueryValue(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",pBuf,&lValue);
MessageBox(pBuf)
}
第一次调用RegQueryValue主要获取读取数据的长度,这里包含了结尾的空字符。所以不用额外加一个字节。第二次得到所需的数据。
写入或者调用其他类型的数据:
在视类OnRegWrite函数RegCloseKey(hKey);之前添加:
DWORD dwAge=30;
RegSetValueEx(hKey,“age”,0,REG_DWORD,(CONST BYTE*)&dwAge,4);
在OnRegRead函数中将之前的代码注释起来,然后添加:
HKEY hKey;
RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\http://www.sunxin.org\\admin",&hKey);
DWORD dwType;
DWORD dwValue;
DWORD dwAge;
RegQueryValueEx(hKey,"age",0,&dwType,(LPBYTE)&dwAge,&dwValue);
CString str;
str.Format("age=%d",dwAge);
MessageBox(str);