📄 07.txt
字号:
对于更早版本的Visual Basic ,使用下列函数:
Function Engine32%()
'这是用于 VB1 - VB3的; 不支持#IF。
Engine32% = False
End Function
Declare方法解决方案的示例
下列代码演示了Declare方法解决方案(不包括Word ):
Declare Function GetTickCount32 Lib "Kernel32" Alias "GetTickCount" () As Long
Declare Function GetTickCount16 Lib "USER" Alias "GetTickCount" () As Long
Function GetTickCount() As Long
If Engine32() Then
GetTickCount = GetTickCount32()
Else
GetTickCount = GetTickCount16()
End If
End Function
Engine32函数可用来确定进行的API调用。Declare语句指示实际的API函数名的Alias(别名),以避免偶尔的大小写变化(32位API调用是区分大小写的),然后在函数后添加16或32以表明API函数的位数(是16位还是32位)。
这个代码可在除Word 外的所有Office 产品中复制和粘贴。WordBasic在其他Office 产品使用Basic之前已经存在,并与之不同。我们将在后面探讨Word 解决方案。
Declare方法解决方案的步骤
如果你正将解决方案转换为能在16位和32位产品上运行的解决方案,我建议你采用下列步骤:
创建一个名为APICalls的新模块;
在APICalls宏中创建Engine32函数;
定位解决方案中的所有Declare函数,并将它们移到APICalls中;
使用“Declare方法解决方案的示例”中的宏代码作为一个模板,为每个API创建函数;
自变量应与Windows 3.1 版API调用匹配;
结果应是Win32 API调用的结果(若需要,Visual Basic 将自动转换为Windows 3.1版);
添加16位API Declare行,在函数名后加上16;
添加32位API Declare行,在函数名后加上32;
进行任何数据处理;
添加一个IF行以调用相应的API;
RETURE返回变量(如果有);
测试函数。
这个过程使得在其他模块中现有的调用保持原样。一旦开发者定义并测试了APICalls模块,她或他可以将这个模块加入到其他解决方案中并可重复使用,这样可节省开发时间。这个模块的内容独立于解决方案,并且开发者可以重复使用这个模块。模块APICalls成为将来开发VBA中16位/32位解决方案的一个组成部分。
API包装的替代解决方案
我通常在API调用上加一层包装,而不是将API调用暴露在代码中。例如,我会将代码包装在GetProfileString上,以创建一个名为vbGetWinIni的函数,该函数采用相同的自变量,但返回的是字符串。我在“创建有用的内在Visual Basic和Microsoft Access函数”一文中论述了公用API包装到DLL的转换问题。
如果你以这种方式编写代码,你可能想要修改API包装函数以调用相应的API,而不是额外创建函数。
Word Declare方法解决方案示例
Word具有不同的Declare格式和句法。Word解决方案比较复杂,这是因为你不能将16位和32位Declare语句都放在相同的宏中。
解决方案将创建三个宏库:APICALL16、APICALL32(它们包含针对每个操作环境的Declare语句)以及一个具有16位/32位互操作性的宏APICALLS。这可能听起来很混乱,那么让我们一步一步讨论。
首先,我们创建一个名为APICALL16的宏库。这个宏包含所有16位API Decalre语句。
'这是APICALL16 -- 所有16位Declare语句都包含在此处。
Declare Function GetTickCount16 Lib "USER" Alias "GetTickCount"() As Long
Function GetTickCount
GetTickCount = GetTickCount16
End Function
其次,我们创建一个名为APICALL32的宏库。这个宏包含所有32位API Declare语句。
'这是 APICALL32 -- 所有32位 Declare 语句都包含在此处。
Declare Function GetTickCount32 Lib "KERNEL32"() Alias "GetTickCount" As Long
Function GetTickCount
GetTickCount = GetTickCount32
End Function
第三步,我们创建一个名为APICALLS的宏库。这个宏包含Engine32和你的解决方案代码所要调用的过程。
'这是APICALLS -- 这个宏中不包含任何Declare语句。
Function Engine32
Engine32 = 0
If Val(AppInfo$(2)) > 5 Then
OS$ = GetSystemInfo$(23)
If Val(OS$) > 6.3 Or Len(OS$) = 0 Then Engine32 = - 1
End If
End Function
Function GetTickCount
If Engine32 Then
GetTickCount = APICall32.GetTickCount
Else
GetTickCount = APICall16.GetTickCount
End If
End Function
'其他API函数调用包含在此处。
你现在可以从你的解决方案代码中调用这个函数。你必须以APICALLS开始你的调用,例如:
Sub MAIN
MsgBox Str$(APICalls.GetTickCount)
End Sub
Word Declare方法解决方案的步骤
如果你正将Word解决方案转换为能在16位和32位产品上运行的解决方案,我建议你采用下列步骤:
创建一个名为APICALLS的新模块;
在APICALLS中创建Engine32函数;
创建一个名为APICALL16的模块;
定位解决方案中的所有16位Declare语句,并将它们移到APICALL16中;
创建一个名为APICALL32的新模块;
创建相当的32位Declare语句,并将它们置于APICALL32中。
使用上述模板,为三个宏库中的每个API创建函数;
在调用所有API前,在你的解决方案代码中添加APICALLS;
测试每个函数。
这个过程使得在其他模块中现有的调用保持原样。一旦开发者定义和测试了这些宏,她或他可将这些宏添加到NORMAL.DOTMO模板中,并可在其他解决方案中重复使用这些宏,以节省时间。
类型库方法
进行API调用的类型库方法对于大多数开发者来说都是较新的内容。在Bruce McKinney的一本将由Microsoft出版的书《Visual Basic核心》中,包含了16位API调用(WIN16.TLB)的Windows API Functions函数类型库以及一个与32位API调用(WIN32.TLB)匹配的类型库。一旦这些类型库被注册,对于16位或32位版本的Office产品,相应的类型库将被装载。
一个类型库可提供Microsoft Excel 5.0或更高版、Microsoft Project 4.0或更高版、Visual Basic 4.0或更高版以及Microsoft Access 95或更高版产品的API调用的简易途径。所有这些Windows API调用变成了内在函数。(参阅我的“创建有用的内在Visual Basic和Microsoft Access函数”一文中的相关材料,它们仅适用于早期版本的Visual Basic和Microsoft Access)。由于对于我的读者来说,类型库方法是一种新的方法,我会详细逐步进行分析。
类型库的注册
下列步骤可完成在你注册中添加一个调用Windows API函数的类型库。这样,该类型库对于所有使用VBA的产品都可用,而不仅仅限于你进行该函数注册的产品。
打开任何VBA产品(例如,Microsoft Excel 5.0)。
为了创建一个模块,从“插入”菜单中选择“宏模块”。
从“工具”中选择“引用”。“引用”对话框的显示如图1。
图1:“引用”对话框
假设你未注册Windows API函数类型库,单击“浏览”按钮并定位到Win32.TLB,然后单击“确定”。对于WIN16.TLB,重复进行这个步骤。这样WIN16.TLB和WIN32.TLB都被注册。参见图2。
图2:选择类型库
在“浏览器”对话框关闭后,滚动到“引用”对话框的底部,你可以在列表中看到Windows API函数类型库(图3)。
图3:Windows API 函数的注册
关闭“引用”对话框。
从“视图”菜单中选择“对象浏览器”。
在“对象浏览”对话框上,在库/工作表下拉列表框中选择Win(Windows API 函数类型库)。所有可用的函数将显示在对象/模块和方法/属性列表框中(如图4)。
图4:Microsoft Excel 5.0“对象浏览器”显示Bruce McKinney的Windows API函数类型库中可用的对象和方法
在对象/模块列表框中,选择“Kernel”;然后在方法/属性列表框中选择“GetTickCount”。
单击“粘贴”按钮,GetTickCount出现在模块中。
下面示例列出的代码可实现在消息框中显示GetTickCount API调用的返回值。
Sub Demo()
MsgBox Str$(GetTickCount)
End Sub
不需要REGISTER命令和Declare语句。上面的代码就是你所需要的全部代码。
类型库方法解决方案的步骤
如果你正将解决方案转换为能在16位和32位产品上运行的解决方案,我建议你采用下列步骤--假设Windows API函数类型库已注册:
假设你仅使用标准的16位API调用,删除你的所有Declare语句;
检查“引用”对话框中的Wondows API函数检查框。
这就是全部步骤,你已经完成了移植。
类型库问题
类型库是一项发展中的技术,商业上可用的类型库还非常少。Bruce先生在使用Windows 3.1 API调用名设计16位和32位产品的类型库方面,作出了优异的工作。尽管如此,类型库仍存在一些问题留待解决。
Windows API函数类型库在VBA中添加了超过1000个的新保留词。所有包含在类型库中API调用变成了语言的保留词。如果你已经有一个名为ordShell的函数,你必须更改它的名称,这样才不会发生与类型库中定义的ordShell函数的冲突。
Windows API函数类型库不包括需要用户定义的类型(UDT)的API调用。这可能在下一版本中得到改善。
Windows API函数类型库方法在Microsoft Excel的speadsheet(电子数据表)中是不可用的。
这种技术是非常有希望的,并将在开发Office解决方案中简化API调用的使用。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -