整理:xiyangshanlu
来源:网络
关键字:Declare,Windows API,Declare Auto,Lib 与 Alias,DllImport
Windows API调用过去曾是Visual Basic编程中很重要的一部分,但在 Visual Basic .NET 几乎不必要了。只要有可能,应该使用 .NET Framework 中的托管代码而不是Windows API 调用来执行任务。本演练提供有关那些一定要使用Windows API 的场合的信息。
[使Declare 的API 调用]
调用 Windows API 最常用的方法是通过使用 Declare 语句。
声明 DLL 过程:
确定要调用的函数的名称及其参数、参数类型和返回值,以及包含该函数的DLL的名称和位置。
注意:有关Windows API 的完整信息,请参见 Platform SDK Windows API中的Win32 SDK文档。有关 Windows API 使用的常数的更多信息,请检查包含在 Platform SDK 中的头文件,如 Windows.h。
[例子]
通过在“文件”菜单上单击“新建”,然后单击“项目”,打开一个新的“Windows应用程序”项目。将出现“新建项目”对话框。 从Visual Basic项目模板的列表中选择“Windows应用程序”。将显示新项目。
将以下Declare 函数添加到项目启动窗体的声明部分,或是添加到要使用 DLL 的类或模块的声明部分中:
Declare 语句的各个部分
Declare 语句包括以下元素。
Auto 修饰符
Auto 修饰符指导运行库根据公共语言运行库规则(或已指定的别名)转换基于方法名的字符串。
Lib 与 Alias 关键字
紧跟 Function 关键字之后的名称就是您的程序用来访问导入函数的名称。它可以与正在调用的函数的实名相同,或者可以使用任何有效的过程名,然后使用Alias 关键字来指定正在调用的函数的实名。
指定Lib 关键字,这个关键字后面紧跟包含正在调用的函数的 DLL的名称和位置。不必为位于 Windows 系统目录下的文件指定路径。
如果正在调用的函数的名称不是一个有效的 Visual Basic 过程名,或与应用程序中其他项的名称冲突,请使用 Alias关键字。Alias 指示正在调用的函数的实名。
参数和数据类型声明
声明参数及其数据类型。这一部分可能具有挑战性,因为 Windows 使用的数据类型与 Visual Studio 数据类型不对应。通过将参数转换为可兼容的数据类型(称为“封送处理”的过程),Visual Basic 帮您做了大量工作。通过使用在 System.Runtime.InteropServices 命名空间中定义的 MarshalAs 属性,可以显式地控制参数封送的方式。
注意:Visual Basic 的早期版本允许声明参数 As Any,这意味着可以使用任意数据类型的数据。Visual Basic .NET 要求所有声明语句使用特定的数据类型。
Windows API 常数
有些参数是多个常数的组合。例如,本演练中所示的 MessageBox API 接受一个称为 Typ 的整型参数,它控制消息框的显示方式。通过检查 WinUser.h 文件中的 #define 语句,可以确定这些常数的数值。这些数值通常以十六进制表示,因此可能需要使用计算器来将这些数值相加,然后转换为十进制。例如,若要组合感叹号样式 MB_ICONEXCLAMATION 0x00000030 和“是/否”样式 MB_YESNO 0x00000004 的常数,可以将这些数字相加并得到结果 0x00000034(十进制数 52)。尽管可以直接使用十进制结果,最好还是在应用程序中将这些值声明为常数,并使用 Or 运算符将其组合。
为Windows API 调用声明常数
可在文档中查找正在调用的 Windows 函数,并确定该函数使用的常数的名称以及包含有这些常数数值的 .h 文件的名称。
使用一个文本编辑器(如“记事本”)查看 .h 文件的内容,并查找与正在使用的常数相关的值。例如,MessageBox API 使用常数 MB_ICONQUESTION 在消息框中显示问号。MB_ICONQUESTION 的定义在 WinUser.h 中,形式如下所示:
#define MB_ICONQUESTION 0x00000020L
将等效的 Const 语句添加到类或模块的声明部分,以使这些常数可用于您的应用程序。例如:
Const MB_ICONQUESTION = &H20L
Const MB_YESNO = &H4
Const IDYES = 6
Const IDNO = 7
调用 DLL 过程
将一个名为 Button1 的按钮添加到项目的启动窗体,然后双击它查看其代码。将显示该按钮的事件处理程序。 将代码添加到已添加按钮的Click 事件处理程序中来调用该过程,并提供适当的参数:
Private Sub Button1_Click(ByVal sender As System.Object,_ |
通过按 F5 键运行项目。将显示带有“是”和“否”响应按钮的消息框。单击任何意一个按钮。
数据封送处理
Visual Basic .NET 自动转换参数的数据类型,并为 Windows API 调用返回值,但是可以使用 MarshalAs 属性显式指定 API 要求的非托管数据类型。有关互操作封送处理程序的更多信息,请参见 Interop 封送处理
在 API 调用中使用 Declare 和 MarshalAs
确定要调用的函数的名称、函数的参数、数据类型以及返回值。
若要简化对 MarshalAs 属性的访问,请向类或模块的代码顶部添加一条 Imports 语句,如下例所示:
Imports System.Runtime.InteropServices
将导入函数的函数原型添加到您正在使用的类或模块的声明部分,并将 MarshalAs 属性应用到参数或返回值。在以下示例中,要求类型为 Void* 的 API 调用可作为 UnmanagedType.AsAny 封送:
Declare Sub SetData Lib "..\LIB\UnmgdLib.dll " (ByVal x As Short,_
<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal o As Object)
[使用 DllImport 的 API 调用]
DllImport 属性提供了在没有类型库的 DLL 中调用函数第二种方法。DllImport 大致等效于使用 Declare 语句,但它在如何调用函数方面提供了更多的控制。
可以将大多数Windows API调用与 DllImport 一起使用,只要该调用引用的是共享(有时称为“静态”)方法就可以。不能使用需要类实例的方法。与 Declare 语句不同,DllImport 调用不能使用 MarshalAs 属性。
使用 DllImport 属性调用 Windows API
[例子]
通过在“文件”菜单上单击“新建”,然后单击“项目”,打开一个新的“Windows 应用程序”项目。将出现“新建项目”对话框。从 Visual Basic 项目模板的列表中选择“Windows 应用程序”。将显示新项目。
将一个名为 Button2 的按钮添加到启动窗体上。
双击 Button2 打开窗体的代码视图。
要简化对 DllImport 的访问,请向启动窗口类的代码顶部添加一条 Imports 语句:
Imports System.Runtime.InteropServices
在 End Class 语句之前为窗体声明一个空函数,并将函数命名为 MoveFile。
将 Public 和 Shared 修饰符应用到函数声明中,并基于 Windows API 函数使用的参数来设置 MoveFile 的参数:
Public Shared Function _ |
函数可以有任意一个有效的过程名;DllImport 属性指定DLL 中的名称。它还为参数和返回值处理互操作封送处理,因此可以选择与API 使用的数据类型相似的 Visual Studio .NET 数据类型。
将 DllImport 属性应用到空函数中。第一个参数是包含要调用的函数的 DLL 的名称和位置。不必为位于 Windows 系统目录下的文件指定路径。第二个参数是一个命名参数,指定Windows API 中的函数名称:
<DllImport( "KERNEL32.DLL ",EntryPoint:= "MoveFileW ",SetLastError:=True,_ |
将代码添加到 Button2_Click 事件处理程序以调用函数:
Private Sub Button2_Click(ByVal sender As System.Object,_ |
创建名为 Test.Txt 的文件并将其放在您硬盘的 C:\Tmp 目录下。如果有必要,可创建 Tmp 目录。
按 F5 键启动该应用程序。将显示主窗体。 单击 Button2。若文件可以移动,则显示“The file was moved successfully”。