50.asp
来自「ASPWeb数据库范例总览」· ASP 代码 · 共 1,382 行 · 第 1/4 页
ASP
1,382 行
<P> </P>
</DIR>
<P>请注意此一函数没有 Subkey 参数, 所以呼叫之前必须先取得 Subkey Handle,
举例来说, 欲读取 "HKEY_CLASSES_ROOT\.txt" Subkey 之下名称为
"Content Type" 的 Value, 呼叫的过程如下:</P>
<P> </P>
<DIR>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Dim bArr() As Byte, vType As Long,
hKey As Long</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>' 先呼叫 RegOpenKey 取得 "HKEY_CLASSES_ROOT\.txt"
的 Subkey Handle</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>ret = RegOpenKey(HKEY_CLASSES_ROOT,
".txt", hKey)</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>ret = GetValue(hKey, "Content
Type", bArr, vType)</FONT></FONT></P>
<P> </P>
</DIR>
<P>除了先取得 Subkey Handle 之外, GetValue 与 GetDefaultValue 另一个最大的不同在於:GetDefaultValue
所读取的资料一定是字串型别, τ GetValue 所读取的资料除了字串之外, 还可能是其他类型的资料,
在实务上, 笔者利用 bArr 及 vType 两种参数来接受 GetValue 所读回来的不同类型资料,
呼叫之前, bArr 为一个空的 Byte 阵列(利用 Dim bArr() As Byte 产生), 若呼叫成功,
bArr 将成为一个含有读取资料的 Byte 阵列(不再是空的 Byte 阵列), 而 vType
则等於所读取资料的类型, 它可能有以下几种类型:</P>
<P> </P>
<CENTER><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3 >
<TR>
<TD WIDTH="51%" VALIGN="TOP" BGCOLOR="#ffff00">资料类型</TD>
<TD WIDTH="16%" VALIGN="TOP" BGCOLOR="#ffff00">
<CENTER><P>设定值</P></CENTER>
</TD>
<TD WIDTH="34%" VALIGN="TOP" BGCOLOR="#ffff00">意义</TD>
</TR>
<TR>
<TD WIDTH="51%" VALIGN="TOP"><FONT SIZE=+0>REG_SZ</FONT></TD>
<TD WIDTH="16%" VALIGN="TOP">
<CENTER><P><FONT SIZE=+0>1</FONT></P></CENTER>
</TD>
<TD WIDTH="34%" VALIGN="TOP">字串</TD>
</TR>
<TR>
<TD WIDTH="51%" VALIGN="TOP"><FONT SIZE=+0>REG_EXPAND_SZ</FONT></TD>
<TD WIDTH="16%" VALIGN="TOP">
<CENTER><P><FONT SIZE=+0>2</FONT></P></CENTER>
</TD>
<TD WIDTH="34%" VALIGN="TOP">可展开式字串</TD>
</TR>
<TR>
<TD WIDTH="51%" VALIGN="TOP"><FONT SIZE=+0>REG_MULTI_SZ</FONT></TD>
<TD WIDTH="16%" VALIGN="TOP">
<CENTER><P><FONT SIZE=+0>7</FONT></P></CENTER>
</TD>
<TD WIDTH="34%" VALIGN="TOP">多重字串</TD>
</TR>
<TR>
<TD WIDTH="51%" VALIGN="TOP"><FONT SIZE=+0>REG_BINARY</FONT></TD>
<TD WIDTH="16%" VALIGN="TOP">
<CENTER><P><FONT SIZE=+0>3</FONT></P></CENTER>
</TD>
<TD WIDTH="34%" VALIGN="TOP"><FONT SIZE=+0>Binary </FONT>资料</TD>
</TR>
<TR>
<TD WIDTH="51%" VALIGN="TOP"><FONT SIZE=+0>REG_DWORD</FONT></TD>
<TD WIDTH="16%" VALIGN="TOP">
<CENTER><P><FONT SIZE=+0>4</FONT></P></CENTER>
</TD>
<TD WIDTH="34%" VALIGN="TOP">长整数</TD>
</TR>
<TR>
<TD WIDTH="51%" VALIGN="TOP"><FONT SIZE=+0>REG_DWORD_BIG_ENDIAN</FONT></TD>
<TD WIDTH="16%" VALIGN="TOP">
<CENTER><P><FONT SIZE=+0>5</FONT></P></CENTER>
</TD>
<TD WIDTH="34%" VALIGN="TOP"><FONT SIZE=+0>Big Endian </FONT>长整数</TD>
</TR>
</TABLE></CENTER>
<P> </P>
<P>您可能觉得奇怪, vType 含有以上几种类型, 为什麼读取的资料一律放在 Byte
阵列中(bArr 参数), 这是因为 Windows API 的设计使然, 为了将 Byte 阵列转换成不同型别的资料,
笔者又撰写了以下的几个函数:</P>
<P> </P>
<CENTER><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=3 >
<TR>
<TD WIDTH="46%" VALIGN="TOP" BGCOLOR="#ffff00">资料类型</TD>
<TD WIDTH="54%" VALIGN="TOP" BGCOLOR="#ffff00">意义</TD>
</TR>
<TR>
<TD WIDTH="46%" VALIGN="TOP">ByteArrayToString</TD>
<TD WIDTH="54%" VALIGN="TOP">将<FONT SIZE=+0> Byte </FONT>阵列转换成字串</TD>
</TR>
<TR>
<TD WIDTH="46%" VALIGN="TOP">ByteArrayToMultiString</TD>
<TD WIDTH="54%" VALIGN="TOP">将<FONT SIZE=+0> Byte </FONT>阵列转换成多重字串</TD>
</TR>
<TR>
<TD WIDTH="46%" VALIGN="TOP">ByteArrayToLong</TD>
<TD WIDTH="54%" VALIGN="TOP">将<FONT SIZE=+0> Byte </FONT>阵列转换成长整数</TD>
</TR>
</TABLE></CENTER>
<P> </P>
<P>使用以上的转换函数以前, 让笔者先说明 vType 几种资料类型的意义:</P>
<P> </P>
<DIR>
<P>(1) <B>REG_SZ</B>:一般的字串, 若 vType 等於此一类型, 则呼叫 ByteArrayToString
进行转换。</P>
<P>(2) <B>REG_EXPAND_SZ</B>:也是呼叫 ByteArrayToString 进行转换, 但此类字串中含有
%WinDir% 之类的字串(注:%WinDir% 表示 Windows 的所在目录), 遇到此类字串,
应该再呼叫 ExpandEnvironmentStrings API 函数将字串展开, 举例来说, 假设
Windows 的所在目录是 "C:\Windows", 则 "LoadHigh %WINDIR%\Command\DOSKey"
经过 ExpandEnvironmentStrings API 的转换之後, 将成为 "LoadHigh C:Windows\Command\DOSKey"。(特别说明:有些程式虽然写入字串资料到登录资料库时,
所设定的资料类型为 REG_SZ, 但字串中仍然含有 %WinDir% 之类的字串, 因此若不能确定读取的字串中是否含有
%WinDir% 之类的字串, 则一律呼叫 ExpandEnvironmentStrings 是比较保险的)</P>
<P>(3) <B>REG_MULTI_SZ</B>:多重字串, 其结构如图-4, 此类资料, 若呼叫
ByteArrayToString 进行转换, 则得到如图-4 的字串, 为了转换此类字串, 笔者提供的副程式是
ByteArrayToMultiString, 呼叫前只要宣告一个空的字串阵列, 例如 Dim S()
As String, 则转换之後, S 就等於含有多个字串的阵列了。</P>
<P> </P>
<CENTER><P><A HREF="51-4.gif">图-4 多重字串(REG_MULTI_SZ) 的意义</A></P></CENTER>
<P> </P>
<P>(4) <B>REG_DWORD</B>:表示含有 4 个字元的数值, 可呼叫 ByteArrayToLong
进行转换。</P>
<P>(5) <B>REG_DWORD_BIG_ENDIAN</B>:不同 CPU 对於数值的安排方式并不相同,
所谓 Big Endian 指的是高位元组放在前面的安排方式(注:Intel 的 CPU 是低位元组放在前面,
另外请注意 Windows NT 可能在非 Intel 的 CPU 底下执行), 虽然此一类型的位元组安排顺序有点不同,
但是对程式而言, 欲取得正确的长整数, 也是呼叫 ByteArrayToLong 进行转换。</P>
<P>(6) <B>REG_BINARY</B>:Binary 资料, 使用 Byte Array 表示最为恰当,
所以不必转换。</P>
<P> </P>
</DIR>
<P>假设我们利用 GetValue 读取 Value 之後, 想将它显示出来, 则以下是参考范例:</P>
<P> </P>
<DIR>
<PRE><FONT SIZE=+1>r<FONT COLOR="#000080">et = GetValue(hKey, Name, bArr, vType)</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Debug.Print ValueOutput( bArr, vType ) ' 将读取的资料显示出来</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1> </FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Function ValueOutput(bArr() As Byte, ByVal vType As Long) As String</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Dim S As String, S2 As String, length As Integer, L As Long</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Dim i As Integer, sArr() As String</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Select Case vType</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Case REG_SZ, REG_EXPAND_SZ</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ByteArrayToString bArr, S</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>' 呼叫 ExpandEnvironmentStrings</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>S2 = String(Len(S) + 256, Chr(0))</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>length = ExpandEnvironmentStrings(S, S2, Len(S2))</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>S = Left(S2, length - 1)</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ValueOutput = "Type=String, Data=" & S</FONT></FONT></PRE>
</DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Case REG_MULTI_SZ</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ByteArrayToMultiString bArr, sArr</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ValueOutput = "Type=MultiString, Data="</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>For i = LBound(sArr) To UBound(sArr)</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ValueOutput = ValueOutput & sArr(i) & ", "</FONT></FONT></PRE>
</DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Next i</FONT></FONT></PRE>
</DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Case REG_DWORD, REG_DWORD_BIG_ENDIAN</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ByteArrayToLong bArr, L</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ValueOutput = "Type=Long, Data=" & L</FONT></FONT></PRE>
</DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Case REG_BINARY</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ValueOutput = "Type=Byte Array, Data="</FONT></FONT></PRE>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>For i = LBound(bArr) To UBound(bArr)</FONT></FONT></PRE>
<DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>ValueOutput = ValueOutput + Format(Hex(bArr(i)), "00")</FONT></FONT></PRE>
</DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>Next i</FONT></FONT></PRE>
</DIR>
</DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>End Select</FONT></FONT></PRE>
</DIR>
<PRE><FONT COLOR="#000080"><FONT SIZE=+1>End Function</FONT></FONT></PRE>
<P><B> </B></P>
</DIR>
<P>◆ GetValueByIndex 函数:读取任意Value</P>
<P> </P>
<P>GetDefaultValue 可读取 Default Value, GetValue 可读取特定名称的 Value,
但如果我们不知道 Value 的名称而想读取某一 Key(或 Subkey) 的所有 Value(包含
Default Value), 则必须使用 GetValueByIndex。</P>
<P> </P>
<P>GetValueByIndex 的函数定义是:</P>
<P> </P>
<DIR>
<P>Function GetValueByIndex(ByVal <B>hKey</B> As Long, ByVal <B>Index</B>
As Long, <B>Name</B> As String, <B>Value()</B> As Byte, <B>vType</B> As
Long) As Boolean</P>
<P> </P>
</DIR>
<P>与 GetValue 不同的是:GetValue 需传入 ValueName 参数, 而 GetValueByIndex
则是传入 Index, Index 的值是 0 ̄N, 若要读取所有的 Value, 则程式大致如下:</P>
<P> </P>
<DIR>
<P><FONT SIZE=-1>I<FONT COLOR="#000080">ndex = 0</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Do </FONT></FONT></P>
<DIR>
<P><FONT COLOR="#000080"><FONT SIZE=-1>ret = GetValueByIndex( hKey, Index,
Name, bArr, vType )</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Index = Index + 1</FONT></FONT></P>
</DIR>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Loop Until Not ret</FONT></FONT></P>
<P> </P>
</DIR>
<P>也就是从 0、1、2…开始读取 Value 的内容, 直到 GetValueByIndex 传回
False 时, 即表示读取了所有的 Value。</P>
<P> </P>
<P>就像 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 并且加以显示的范例程式:</P>
<P> </P>
<UL>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Dim hKey As Long, Index As Long,
Name As String</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Dim bArr() As Byte, vType As Long,
ret As Boolean</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Index = 0</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>Do </FONT></FONT></P>
<UL>
<P><FONT COLOR="#000080"><FONT SIZE=-1>ret = GetValueByIndex( hKey, Index,
Name, bArr, vType )</FONT></FONT></P>
<P><FONT COLOR="#000080"><FONT SIZE=-1>If ret Then</FONT></FONT></P>
<UL>
<P><FONT COLOR="#000080"><FONT SIZE=-1>If Name = "" Then Name
= "(</FONT>预设值<FONT SIZE=-1>)"</FONT></FONT></P>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?