首页 > 编程资源分享区 > C/C++源代码共享 > 从注册表中存取字符形值
2006
09-14

从注册表中存取字符形值

/ 读取注册表中的键值:字符型
// ———————————————————— — //
CString GetRegValue( HKEY hKey,
LPCTSTR sKey,
LPCTSTR sChildKey,
LPCTSTR sDefault = (LPCTSTR)_T(“”),
DWORD dwBufferSize = 255 );

//////////////////////////////////////////////////////////// //////////////
//
// 读取注册表中的键值:字符型(1998年12月24日调试通过)
//
// 最后修改时间(1998年12月23日晚)
//
// 为了更加易用, 本函数只是简单的把读出的数据作为函数的返回值, 但在易
// 用性上的妥协使程序有这样一个缺点:当返回空字符串时, 无法判断是由指定键
// 值的数据本身就是空串还是在函数运行过程中出现了异常情况导致读取失败。
// 有两种改进方法, 一种方法是将读出的数据作为函数的参数返回, 函数的返
// 回值判断程序运行情况,我不喜欢这种方法;另一种方法是使用 C++ 异常。
CString GetRegValue( HKEY hKey,
LPCTSTR sKey,
LPCTSTR sChildKey,
LPCTSTR sDefault /*= (LPCTSTR)_T(“”)*/,
DWORD dwBufferSize /*= 255*/ )
{
// 大于 2048 字节的值应存作文件, 并将文件名保存在注册表中。
ASSERT( dwBufferSize * sizeof(BYTE) <= 2048 );

CString strResult;
HKEY hOpenKey = NULL;
// 芝麻开门!
if ( ERROR_SUCCESS != ::RegOpenKeyEx( hKey,
sKey,
0 ,
KEY_READ,
&hOpenKey ) )
{
return (CString)sDefault;
}

BYTE * szBuff;
szBuff = new BYTE[ dwBufferSize ];
// 字符串缓冲区分配错误
if ( NULL == szBuff )
{
::RegCloseKey( hOpenKey );
return (CString)sDefault;
}

// 查询指定的值
::memset(szBuff, 0, dwBufferSize);
if ( ERROR_SUCCESS != ::RegQueryValueEx( hOpenKey,
sChildKey,0,0,
&szBuff[0],
&dwBufferSize) )
{
strResult = (CString)sDefault;
}
else
{
strResult = (CString)szBuff;
}
delete szBuff;
// 芝麻关门!
::RegCloseKey(hOpenKey);
return strResult;
}


//////////////////////////////////////////////////////////// ////////
// SetRegValue() 函数
// ———————————————————— — //
// 这三个参数对不了解注册表的人来说可能不好懂, 要弄懂它,首先
// 要明白什么是<主键>、<子键>、<键值>及键值中的<数据>。
// 其实这几个词也是我凭自已对注册表的理解及印象起的名,可能叫
// 法不是十分准确。下面用我自己的话对几个词分析如下:
// <主键> —- Windows 系统预定义的几个 HKEY 型的数据:
// HKEY_LOCAL_MACHINE 该键是注册表中的物理键, 实际上它就是 SYSTEM.DAT
// HKEY_USERS 该键是注册表中的物理键, 实际上它就是 USER.DAT
// HKEY_CURRENT_USER 该键是虚拟的
// HKEY_CLASS_ROOT 该键是虚拟的
// HKEY_CURRENT_CONFIG 虚拟键
// HKEY_DYN_DATA 虚拟键
// <子键> —- 能在 RegEdit 中左边窗口显示出来的,除了几个主键外都
// 叫子键。
// <键值> —- RegEdit 中右边窗口是分两列显示数据的,其中左边那列
// 叫做键值。
// <数据> —- 接着 <键值> 说, 右边那列就叫作数据。
// ———————————————————— — //
// 关于 nFlag 参数的注释就像绕口令,连我自己好像都眼花:
enum {
// 置此位时,当注册表中子键不存在时建立子键;不置此位,
// 如子键不存在则不建立子键。
SRV_CREATEKEY = 0×03, // 00000011
// 置此位时,如果注册表键值没有建立,则建立键值;不置此
// 位,如果键值没有建立,则不建立键值。
SRV_CREATEVALUE = 0x0c, // 00001100
// 置此位时,覆盖注册表键值中已有的数据;不置此位,如键
// 值中已有数据,则不覆盖(对字符型数据: 键值数据为空串时,
// 认为该键值中没有数据, 操作结果与置此位时的结果相同)。
SRV_OVERWRITEVALUE = 0×30, // 00110000
};
// ———————————————————— — //
// 设置注册表中的键值:字符型 ( 我自己认为,该函数功能很强大 )
BOOL SetRegValue( HKEY hKey,
LPCTSTR sKey,
LPCTSTR sChildKey,
LPCTSTR sChildKeyValue,
INT nFlag = SRV_CREATEKEY|SRV_OVERWRITEVALUE|SRV_CREATEVALUE,
DWORD dwBufferSize = 255 );

//////////////////////////////////////////////////////////// ////////////
//
// 修改注册表中的键值:字符型(1998年12月25日调试通过)
//
// 最后一次修改时间(1998年12月25日)
//
// 当函数实际往注册表里写数据了, 则返回真值;否则返回假值。用户可以
// 根据调用此函数时指定的 nFlag 值和函数返回值判断函数运行过程中是否出现
// 了异常情况。
//
BOOL SetRegValue( HKEY hKey,
LPCTSTR sKey,
LPCTSTR sChildKey,
LPCTSTR sChildKeyValue,
INT nFlag /*= SRV_CREATEKEY|SRV_OVERWRITEVALUE|SRV_CREATEVALUE*/,
DWORD dwBufferSize /* = 255 */ )
{
// 大于 2048 字节的值项应存作文件, 并将文件名保存在注册表中。
ASSERT( dwBufferSize * sizeof(BYTE) <= 2048 );

HKEY hChildKey = 0;
DWORD dwDisposition;

//////////////////////////////////////////////////////////// ////////
// 判断打开注册表的方式
if ( nFlag & SRV_CREATEKEY )
{
// 如果 strKey 键存在则打开;如果不存在则建立该键。(注意:不是键值)
if ( ERROR_SUCCESS != ::RegCreateKeyEx( hKey,
sKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_CREATE_SUB_KEY | KEY_QUERY_VALUE | KEY_SET_VALUE,
NULL,
& hChildKey,
& dwDisposition ) )
{
return FALSE;
}
}
else // 如果 strKey 键不存在, 不建立
{
if ( ERROR_SUCCESS != ::RegOpenKeyEx(
hKey,
sKey,
0,
KEY_QUERY_VALUE | KEY_SET_VALUE,
&hChildKey) )
{
return FALSE;
}
} // if ( nFlag & SRV_CREATEKEY ) 判断打开注册表的方式
//////////////////////////////////////////////////////////// ////////
// 读入键值数据, 看看是不是空串
BYTE * szBuff;
szBuff = new BYTE[ dwBufferSize ];
// 字符串缓冲区分配错误
if ( NULL == szBuff )
{
::RegCloseKey( hChildKey );
return FALSE;
}

::memset(szBuff, 0 , dwBufferSize);
LONG lResult = ::RegQueryValueEx(
hChildKey,
sChildKey,
0, 0,
&szBuff[0],
&dwBufferSize);

// 如果用户不允许建立键值, 而且该键不存在,那就 return 好了
if ( ( (!(nFlag & SRV_CREATEVALUE)) && (ERROR_FILE_NOT_FOUND == lResult) ) ||
// 如果用户不允许覆盖已有的键值, 读入的数据又不是空串, 那就 return 呗!
( (!(nFlag & SRV_OVERWRITEVALUE)) && (szBuff[0] != 0) ) ||
// 读取注册表数据时出错
( ERROR_SUCCESS != lResult && ERROR_FILE_NOT_FOUND != lResult ) )
{
delete szBuff;
::RegCloseKey(hChildKey);
return FALSE;
}
//////////////////////////////////////////////////////////// ////////
delete szBuff ;
// 给指定的键赋值
lResult = ::RegSetValueEx(
hChildKey,
sChildKey,
0,
REG_SZ,
(const BYTE *)sChildKeyValue,
(DWORD)((CString)sChildKeyValue).GetLength() );
::RegCloseKey(hChildKey);

if ( ERROR_SUCCESS == lResult )

return TRUE;
else
return FALSE;
}


留下一个回复