编程高手之路—跟我学VB—Windows 的登录资料库(2)

2018-12-17 11:19

Function GetValue(ByVal hKey As Long, ByVal ValueName As String, Value() As Byte, vType As ValueType) As Boolean

请注意此一函数没有 Subkey 参数, 所以呼叫之前必须先取得 Subkey Handle,举例来说, 欲读取 \EY_CLASSES_ROOT\\.txt\Subkey 之下名称为 \Type\的 Value, 呼叫的过程如下: Dim bArr() As Byte, vType As Long, hKey As Long

' 先呼叫 RegOpenKey 取得 \的 Subkey Handle ret = RegOpenKey(HKEY_CLASSES_ROOT, \hKey) ret = GetValue(hKey, \Type\bArr, vType)

除了先取得 Subkey Handle 之外, GetValue 与 GetDefaultValue 另一个最大的不同在於:GetDefaultValue 所读取的资料一定是字串型别, 而 GetValue 所读取的资料除了字串之外, 还可能是其他类型的资料,在实务上, 笔者利用 bArr 及 vType 两种参数来接受 GetValue 所读回来的不同类型资料,呼叫之前, bArr 为一个空的 Byte 阵列(利用 Dim bArr() As Byte 产生), 若呼叫成功, bArr 将成为一个含有读取资料的 Byte 阵列(不再是空的 Byte 阵列), 而 vType 则等於所读取资料的类型, 它可能有以下几种类型:

资料类型 设定值 意义 字串 可展开式字串 多重字串 REG_SZ REG_EXPAND_SZ REG_MULTI_SZ REG_BINARY REG_DWORD REG_DWORD_BIG_ENDIAN 1 2 7 3 4 5 Binary 资料 长整数 Big Endian 长整数 您可能觉得奇怪, vType 含有以上几种类型, 为什麽读取的资料一律放在 Byte 阵列中(bArr 参数), 这是因为 Windows API 的设计使然, 为了将 Byte 阵列转换成不同型别的资料,笔者又撰写了以下的几个函数:

资料类型 ByteArrayToString ByteArrayToMultiString ByteArrayToLong 意义 将 将 将 Byte 阵列转换成字串 Byte 阵列转换成多重字串 Byte 阵列转换成长整数 使用以上的转换函数以前, 让笔者先说明 vType 几种资料类型的意义:

(1) REG_SZ:一般的字串, 若 vType 等於此一类型, 则呼叫 ByteArrayToString 进行转换。

(2) REG_EXPAND_SZ:也是呼叫 ByteArrayToString 进行转换, 但此类字串中含有 %WinDir% 之类的字串(注:%WinDir% 表示 Windows 的所在目录), 遇到此类字串,应该再呼叫 ExpandEnvironmentStrings API 函数将字串展开, 举例来说, 假设 Windows 的所在目录是 \, 则 \%WINDIR%\\Command\\DOSKey\经过 ExpandEnvironmentStrings API 的转换之後, 将成为 \C:Windows\\Command\\DOSKey\。(特别说明:有些程式虽然写入字串资料到登录资料库时,所设定的资料类型为 REG_SZ, 但字串中仍然含有 %WinDir% 之类的字串, 因此若不能确定读取的字串中是否含有 %WinDir% 之类的字串, 则一律呼叫 ExpandEnvironmentStrings 是比较保险的)

(3) REG_MULTI_SZ:多重字串, 其结构如图-4, 此类资料, 若呼叫 ByteArrayToString 进行转换, 则得到如图-4 的字串, 为了转换此类字串, 笔者提供的副程式是 ByteArrayToMultiString, 呼叫前只要宣告一个空的字串阵列, 例如 Dim S() As String, 则转换之後, S 就等於含有多个字串的阵列了

图-4 多重字串(REG_MULTI_SZ) 的意义

(4) REG_DWORD:表示含有 4 个字元的数值, 可呼叫 ByteArrayToLong 进行转换。

(5) REG_DWORD_BIG_ENDIAN:不同 CPU 对於数值的安排方式并不相同,所谓 Big Endian 指的是高位元组放在前面的安排方式(注:Intel 的 CPU 是低位元组放在前面,另外请注意 Windows NT 可能在非 Intel 的 CPU 底下执行), 虽然此一类型的位元组安排顺序有点不同,但是对程式而言, 欲取得正确的长整数, 也是呼叫 ByteArrayToLong 进行转换。

(6) REG_BINARY:Binary 资料, 使用 Byte Array 表示最为恰当,所以不必转换。 假设我们利用 GetValue 读取 Value 之後, 想将它显示出来, 则以下是参考范例: ret = GetValue(hKey, Name, bArr, vType)

Debug.Print ValueOutput( bArr, vType ) ' 将读取的资料显示出来 Function ValueOutput(bArr() As Byte, ByVal vType As Long) As String Dim S As String, S2 As String, length As Integer, L As Long Dim i As Integer, sArr() As String Select Case vType

Case REG_SZ, REG_EXPAND_SZ ByteArrayToString bArr, S

' 呼叫 ExpandEnvironmentStrings S2 = String(Len(S) + 256, Chr(0))

length = ExpandEnvironmentStrings(S, S2, Len(S2)) S = Left(S2, length - 1)

ValueOutput = \Data=\& S Case REG_MULTI_SZ

ByteArrayToMultiString bArr, sArr ValueOutput = \Data=\ For i = LBound(sArr) To UBound(sArr) ValueOutput = ValueOutput & sArr(i) & \\Next i

Case REG_DWORD, REG_DWORD_BIG_ENDIAN ByteArrayToLong bArr, L

ValueOutput = \Data=\& L Case REG_BINARY

ValueOutput = \Array, Data=\For i = LBound(bArr) To UBound(bArr)

ValueOutput = ValueOutput + Format(Hex(bArr(i)), \Next i End Select End Function

◆ GetValueByIndex 函数:读取任意Value

GetDefaultValue 可读取 Default Value, GetValue 可读取特定名称的 Value,但如果我们不知道 Value 的名称而想读取某一 Key(或 Subkey) 的所有 Value(包含 Default Value), 则必须使用 GetValueByIndex。

GetValueByIndex 的函数定义是:

Function GetValueByIndex(ByVal hKey As Long, ByVal Index As Long, Name As String, Value() As Byte, vType As Long) As Boolean

与 GetValue 不同的是:GetValue 需传入 ValueName 参数, 而 GetValueByIndex 则是传入 Index, Index 的值是 0~N, 若要读取所有的 Value, 则程式大致如下: Index = 0 Do

ret = GetValueByIndex( hKey, Index, Name, bArr, vType ) Index = Index + 1 Loop Until Not ret

也就是从 0、1、2…开始读取 Value 的内容, 直到 GetValueByIndex 传回 False 时, 即表示读取了所有的 Value。

就像 GetValue 会传回 Byte 阵列(Value() As Byte 参数) 及资料类型(vType As Long 参数)一样, GetValueByIndex 也会传回 Byte 阵列及资料类型, 但重要的是 GetValueByIndex 还会传回 Value 的名称(Name 参数), 而为了区分 GetValueByIndex 所读取的是 Default Value 还是特定名称的 Value(注:Default Value 的 Index 不一定等於 0), 程式必须判断读回的 Name 参数, 若 Name 参数等於 \,则表示此一 Index 为 Default Value。以下是利用 GetValueByIndex 读取某一 Key(或 Subkey) 所有 Value 并且加以显示的范例程式:

Dim hKey As Long, Index As Long, Name As String Dim bArr() As Byte, vType As Long, ret As Boolean Index = 0 Do

ret = GetValueByIndex( hKey, Index, Name, bArr, vType ) If ret Then

If Name = \Then Name = \预设值)\

Debug.Print \& Name & \\& ValueOutput( bArr, vType ) Index = Index + 1

End If

Loop Until Not ret

◆ SetDefaultValue 函数:写入Default Value

SetDefaultValue 是与 GetDefaultValue 相对应的函数, 前者用来写入资料,後者则是读取资料, 两者除了读取与写入的差别之外, 使用方法与参数定义则完全相同。

比较值得注意的事情是, 当我们想写入某一个 Subkey 的 Default Value 时,若此一 Subkey 不存在, 则 Windows 会自动建立此一 Subkey, 然後才写入 Default Value, 假设 \OFTWARE\\kj\\Registry\Subkey 并不存在, 则以下叙述:

ret = SetDefaultValue(HKEY_LOCAL_MACHINE, \\Registry Master\会先建立以下两个 Subkey:(HKEY_LOCAL_MACHINE\\SOFTWARE 为已存在的 Subkey) HKEY_LOCAL_MACHINE\\SOFTWARE\\kj HKEY_LOCAL_MACHINE\\SOFTWARE\\kj\\Registry

然後才写入 \Registry Master\到 \Subkey 的 Default Value。

◆ SetValue 函数:写入特定Value

SetDefaultValue 用来写入 Default Value, 而 SetValue 则用来写入特定名称的 Value, 它的函数定义如下:

Function SetValue(ByVal hKey As Long, ByVal ValueName As String, ByVal vType As Long, Value As Variant, Optional ByVal lenValue As Integer) As Boolean

比较特别的参数是 Value 及 lenValue, 其中 Value 参数所定义的型别是 Variant(不定型),表示可以接受任何型别的资料, 而 lenValue 参数则以 Optional 的方式来宣告,表示可以省略。在使用上, 如果呼叫 SetValue 时所设定的是长整数或字串资料,则 lenValue 参数可以省略, 因为长整数与字串都可以由程式自己取得长度(长整数的长度是 4, 字串的长度则是利用 Len(字串) 来取得), 因此只有设定 REG_BINARY 类型的资料时,才需要设定 lenValue 参数, 以下是几种典型的呼叫方式: ' REG_SZ 类型资料, Value 参数传入字串

ret = SetValue(hKey, \REG_SZ, \Data\' REG_DWORD 类型资料, Value 参数传入长整数 ret = SetValue(hKey, \REG_DWORD, 99999)


编程高手之路—跟我学VB—Windows 的登录资料库(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:开题报告 营销新思路—星巴克成功的启示

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: