VB.NET 调用Windows API 使用方法

 整理: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   Auto   Function   MBox   Lib   "user32.dll "   _
Alias   "MessageBox "   (ByVal   hWnd   As   Integer,   _
      ByVal   txt   As   String,   ByVal   caption   As   String,   _
      ByVal   Typ   As   Integer)   As   Integer

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,   _
                                 ByVal   e   As   System.EventArgs)  Handles   Button1.Click
      Dim   RetVal   As   Integer   '   Stores   the   return   value.
      RetVal   =   MBox(0,   "Declare   DLL   Test ",   "Windows   API   MessageBox ",   _
                                  MB_ICONQUESTION   Or   MB_YESNO)
'   Check   the   return   value.
      If   RetVal   =   IDYES   Then
            MsgBox( "You   chose   Yes ")
      Else
            MsgBox( "You   chose   No ")
      End   If
End   Sub

通过按   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,   _
              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   _  
MoveFile(ByVal   src   As   String,   ByVal   dst   As   String)   As   Boolean
      '   Leave   the   body   of   the   function   empty.
End   Sub

函数可以有任意一个有效的过程名;DllImport  属性指定DLL 中的名称。它还为参数和返回值处理互操作封送处理,因此可以选择与API 使用的数据类型相似的 Visual Studio .NET 数据类型。  

将   DllImport   属性应用到空函数中。第一个参数是包含要调用的函数的   DLL   的名称和位置。不必为位于 Windows 系统目录下的文件指定路径。第二个参数是一个命名参数,指定Windows API 中的函数名称:  

CharSet:=CharSet.Unicode,   ExactSpelling:=True,   _
CallingConvention:=CallingConvention.StdCall)>   _
Public   Shared   Function   _
MoveFile(ByVal   src   As   String,   ByVal   dst   As   String)   As   Boolean
      '   This   function   copies   a   file   from   the   path   src   to   the   path   dst.
      '   Leave   function   empty   -   DllImport   attribute   forces   calls  
      '   to   MoveFile   to   be   forwarded   to   MoveFileW   in   KERNEL32.DLL.
End   Function

将代码添加到   Button2_Click   事件处理程序以调用函数:

 

 

Private   Sub   Button2_Click(ByVal   sender   As   System.Object,   _
                                                    ByVal   e   As   System.EventArgs)   _
                                                    Handles   Button2.Click
      Dim   RetVal   As   Boolean
      RetVal   =   MoveFile( "c:\tmp\Test.txt ",   "c:\Test.txt ")
      If   RetVal   =   True   Then
            MsgBox( "The   file   was   moved   successfully. ")
      Else
            MsgBox( "The   file   could   not   be   moved. ")
      End   If
End   Sub

创建名为  Test.Txt 的文件并将其放在您硬盘的   C:\Tmp   目录下。如果有必要,可创建   Tmp   目录。  

按   F5   键启动该应用程序。将显示主窗体。  
单击   Button2。若文件可以移动,则显示“The   file   was   moved   successfully”。

你可能感兴趣的:(Dev/Windows)