尽管 Visual Basic 在 Win32api.txt 中提供了大量的预定义声明,但还是需要知道如何亲自编写声明。例如,有时希望访问用其它语言编写的 DLL 中的过程,或者改写 Visual Basic 的预定义声明,以满足特殊需要。
要声明一个 API 过程,需要在代码窗口的“声明”部分增加一个 Declare 语句。如果该过程返回一个值,应将其声明为 Function:
Declare Function publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]])] As Type
如果过程没有返回值,可将其声明为 Sub:
Declare Sub publicname Lib "libname" [Alias "alias"] [([[ByVal] variable [As type] [,[ByVal] variable [As type]]])]
缺省情况下,在标准模块中声明的 API 过程是公有的,可以在应用程序的任何地方调用它。在其它类型的模块中定义的 API 过程是模块私有的,必须在它们前面声明 Private 关键字,以示区分。
一.指定库
Declare 语句中的 Lib 子句用来告诉 Visual Basic 如何找到包含过程的 .API 文件。如果引用的过程属于 Windows 核心库(User32、Kernel32 或 GDI32),则可以不包含文件扩展名:
Declare Function GetTickCount Lib "kernel32" Alias _
"GetTickCount" () As Long
对于其它 DLL,Lib 子句指定文件的路径:
Declare Function lzCopy Lib "c:\windows\lzexpand.API" _
(ByVal S As Integer, ByVal D As Integer) As Long
如果未指定 libname 的路径,Visual Basic 将按照下列顺序查找该文件:
.exe 文件所在的目录
当前目录
Windows 位系统目录(通常为 \Windows\System)
Windows 目录(不一定是 \Windows)
Path 环境变量中的目录
下表中列出了通常的操作系统环境库文件。
动态链接库 描述
Advapi32.API 高级 API 服务,支持大量的 API(其中包括许多安全与注册方面的调用)
Comdlg32.API 通用对话框 API 库
Gdi32.API 图形设备接口 API 库
Kernel32.API Windows 32 位核心的 API 支持
Lz32.API 32 位压缩例程
Mpr.API 多接口路由器库
Netapi32.API 32 位网络 API 库
Shell32.API 32 位 Shell API 库
User32.API 用户接口例程库
Version.API 版本库
Winmm.API Windows 多媒体库
Winspool.drv 后台打印接口,包含后台打印 API 调用。
二.处理使用字符串的 Windows API 过程
如果调用的 Windows API 过程要使用字符串,那么声明语句中必须增加一个 Alias 子句,以指定正确的字符集。包含字符串的 Windows API 函数实际有两种格式:ANSI 和 Unicode。因此,在 Windows 头文件中,每个包含字符串的函数都同时有 ANSI 版本和 Unicode 版本。
例如,下面是 SetWindowText 函数的两种 C 语言描述。可以看到,第一个描述将函数定义为 SetWindowTextA,尾部的“A”表明它是一个 ANSI 函数:
WINUSERAPI
BOOL
WINAPI
SetWindowTextA(
HWND hWnd,
LPCSTR lpString);
第二个描述将它定义为 SetWindowTextW,尾部的“W”表明它是一个 Unicode 函数:
WINUSERAPI
BOOL
WINAPI
SetWindowTextW(
HWND hWnd,
LPCWSTR lpString);
因为两个函数实际的名称都不是“SetWindowText”,要引用正确的函数就必须增加一个 Alias 子句:
Private Declare Function SetWindowText Lib "user32" _
Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal _
lpString As String) As Lon