vb.net

位置:IT落伍者 >> vb.net >> 浏览文章

VB.NET编程中调用Windows API


发布日期:2021年02月24日
 
VB.NET编程中调用Windows API
Windows API就是Windows系统的API函数简称(Application Program Interface应用程序接口函数)它是Windows操作系统提供给各种开发基于Windows平台应用软件的开发语言的一些公用的函数这些函数一般都比较底层所以当各种开发语言使用自带的函数或类库已无法解决问题时调用Windows API函数往往是一种非常直接有效的解决方法但由于在程序中调用Windows API函数一般都很复杂所以对于程序员来说是否能够灵活的使用Windows API函数往往也是其水平高低的一个重要标志但自从微软推出Net框架以后各种开发基于Net平台下的程序语言如Visual Basic NetVisual C#等却很少使用Windows API函数并且微软公司也不像以前那样提倡在这些Net开发语言中使用Windows API函数其主要的原因如下

Net框架所附带的类库Net FrameWork SDK是一个内容丰富功能强大的软件开发包各种Windows API函数所实现的各种功能几乎都可以在这个软件开发包中找到与之对应的部分

微软Visual Basic NetVisual C#等目的是编写跨平台的应用程序如果在Visual Basic NetVisual C#等中使用Windows API函数这也就注定了编写出的程序只能运行于Windows平台之下而弱化了NET的跨平台能力这也就是为什么微软不提倡在Net平台调用Windows API函数的原因

虽然微软并不提倡在Visual Basic NetVisual C#中调用Windows API函数但由于目前Net 框架推出时间较短Net FrameWork SDK中提供的类库还并不足以完全替换Windows API函数的所有功能所以在某些时候Net开发语言还是必须要调用Windows API函数

平台调用托管DLL非托管DLL简介

托管DLL就是能够在公共语言运行库(Common Language Runtime简称CLR)中能够直接引用的并且扩展名为DLL的文件具体所指就是封装各种命名空间所在的DLL文件如Systemdll等非托管DLL就是平常所的动态链接库等其中就包括了封装所有Windows API函数的DLL文件各种非托管DLL中的函数在公共语言运行库中不能直接被调用而需要经过Net框架提供的平台调用服务后才可以

平台调用Net框架为Visual Basic NetVisual C#等Net开发语言提供的一种服务用以在托管代码中引入各种非托管DLL中封装的函数(其中包括Windows API函数)平台调用依赖于元数据在运行时查找导出函数并封装其参数公共语言运行库利用平台服务调用非托管DLL中的函数的流程图

平台服务的调用非托管函数的流程图

在托管代码中使用平台调用服务调用非托管DLL中封装的函数时平台服务将依次执行以下操作

. 查找包含该函数所在的DLL文件

. 如果找到则将该DLL文件 加载到内存中

. 查找函数在内存中的地址并将其参数推到堆栈上并封送所需的数据

. 将控制权转移给非托管函数 这样整个函数调用完成

在Visual Basic Net中使用平台调用服务申明Windows API函数主要有二种具体的实现方法

. 使用DllImport特征类来申明Windows API函数

. 使用Declare语句来申明Windows API函数

这二种方法虽有异曲同工之效但在繁简上却有很大差异第一种方法申明过程比较复杂很容易在申明Windows API函数时出错所以并不提倡而第二种方法相对简单并且又保存了以前Visual Basic中的很多语法所以在平常时大都使用这种方法来申明Windows API函数

二.VBNet查看文件中图标的函数及申明Windows API的方法

Visual Basic Net要实现查看文件中的图标目前只使用Net FrameWork SDK是无法实现这种功能的正如前面所说主要是由于Net FrameWork SDK推出的时间较短其功能还不可能面面俱到解决问题的关键是正确使用Windows API函数其中所涉及到的Windows API函数主要有二个其一是获得指定文件中的图标数目其二是从指定文件的指定位置导出图标的Windows句柄这二个函数都位于Shelldll文件中并且函数的入口点都为ExtractIcon下面是在Visual Basic Net中分别使用DllImport特征类和Declare语句申明这二个Windows API函数的具体方法

使用DllImport特征类来申明Windows API函数

下面是在Visual Basic Net中使用DllImport特征类申明二个Windows API函数的具体示例

函数ExtractIcon其功能是是从指定文件的指定位置导出图标的Windows句柄

< SystemRuntimeInteropServicesDllImport ( Shelldll EntryPoint := ExtractIcon ) > _

Public Function _

ExtractIcon ( ByVal src As SystemIntPtr ByVal strFileName As string ByVal uiIconIndex As UInt ) As SystemIntPtr

End Function

函数Icon_Num其功能是获得指定文件中的图标数目

< SystemRuntimeInteropServicesDllImport ( Shelldll EntryPoint := ExtractIcon ) > _

Public Function _

Icon_Num ( ByVal src As SystemIntPtr ByVal strFileName As string ByVal uiIconIndex As Integer ) As Integer

End Function

在使用DllImport特征类申明Windows API函数时如果申明的函数名称和函数的入口点相同则可以在申明Windows API函数时省略定义函数入口点对应的代码即EntryPoint对象字段对应的代码这样声明ExtractIcon函数的代码也可以简化为如下所示

< SystemRuntimeInteropServicesDllImport ( Shelldll ) > _

Public Function _

ExtractIcon ( ByVal src As SystemIntPtr ByVal strFileName As string ByVal uiIconIndex As UInt ) As SystemIntPtr

End Function

使用Declare语句来申明Windows API函数

使用Declare语句的确比使用DllImport特征类要简单了许多下面是在Visual Basic Net中使用Declare语句来声明上述二个Windows API函数的具体方法

Declare Auto Function ExtractIcon Lib Shelldll Alias ExtractIcon ( ByVal src As SystemIntPtr ByVal strFileName As string ByVal uiIconIndex As UInt ) As SystemIntPtr

声明ExtractIcon函数

Declare Auto Function Icon_Num Lib Shelldll Alias ExtractIcon ( ByVal src As SystemIntPtr ByVal strFileName As string ByVal uiIconIndex As Integer ) As Integer

声明Icon_Num函数

在Visual Basic Net中声明Windows API函数时Declare语句中Alias关键字的作用相当于使用DllImport特征类中的EntryPoint对象字段同样在使用Declare语句声明Windows API函数时如果声明的函数和函数的入口点相同也可以省略Alias关键字对应的代码所以ExtractIcon函数也可以简化为如下

Declare Auto Function ExtractIcon Lib Shelldll ( ByVal src As SystemIntPtr ByVal strFileName As string ByVal uiIconIndex As UInt ) As SystemIntPtr

下面就结合一个示例的编写过程来掌握的这二个Windows API函数的具体使用方法这个示例的作用就是读取指定文件中的图标数目并显示文件中的图标

三.本文中程序的编写调试和运行环境

视窗高级服务器版

Visual Studio Net 企业结构设计版Net FrameWork SDK版本号

四.Visual Basic Net读取文件中的图标的实现步骤

下面介绍的示例其功能读取指定文件中包含的图标数目并把这些图标全部显示出来下面是这个示例的实现步骤

启动Visual Studio Net

选择菜单【文件】|【新建】|【项目】后弹出【新建项目】对话框

将【项目类型】设置为【Visual Basic项目】

将【模板】设置为【Windows应用程序】

在【名称】文本框中输入【Visual Basic Net查看文件中的图标】

在【位置】的文本框中输入【E:\VSNET项目】然后单击【确定】按钮这样在【E:\VSNET项目】目录中就产生了名称为【Visual Basic Net查看文件中的图标】文件夹里面存放着【Visual Basic Net查看文件中的图标】项目的所有文件具体如图所示

【Visual Basic Net查看文件中的图标】项目的【新建项目】对话框

选择菜单【项目】|【添加新项】在弹出的对话框中的【模板】设置为【模块】【名称】文本框设置为【Modulevb】后单击【打开】按钮则在项目中增加了一个模板文件名称为【Modulevb】

把Visual Stuido Net的当前窗口切换到Modulevb的代码编辑窗口并在其Module的代码区中添加下列代码下列代码是用二种方式声明二个Windows API函数

< SystemRuntimeInteropServicesDllImport ( Shelldll ) > _

Public Function _

ExtractIcon ( ByVal src As SystemIntPtr ByVal strFileName As String ByVal uiIconIndex As UInt ) As SystemIntPtr

End Function

声明ExtractIcon函数

Declare Auto Function Icon_Num Lib Shelldll Alias ExtractIcon ( ByVal src As SystemIntPtr ByVal strFileName As String ByVal uiIconIndex As Integer ) As Integer

把Visual Studio Net的当前窗口切换到Form窗体的设计查看并从【工具箱】中的【Windows窗体】选项卡中拖入下列组件到Form窗体

四个Label组件其中二个用以显示提示信息另外二个分别用以显示选择的文件名称和这个文件中包含的图标数目

一个ListView组件利用其显示大图标的属性用以显示选定文件中的图标

一个OpenFileDialog组件用以选择要查看图标的文件名称

一个ImageList组件它起的是桥梁的作用首先把从文件中导出的图标存放到这里然后再提供ListView组件显示出来

一个Button组件

按照表中数值来设定设定组件的主要属性

组件类型 组件名称 属性 设置结果Form Form Text VBNET查看文件中的图标Form MaximizeBox FalseForm MinimizeBox FalseForm FormBorderStyle FixedSingleListView ListView ImageList LargeImageListListView MultiSelect FalseListView Size Size ( )Button Button Text 选择文件Button FlatStyle FlatImageList ImageList Size Size ( )ImageList TransparentColor ColorTransparentLabel Label Text 文件名称Label Text 图标数目Label Text LabelText 【Visual Basic Net查看文件中的图标】项目窗体中各组件的主要属性设定数值表

并按照图中各组件的位置大小和排列方式来调整窗体中各个组件

【Visual Basic Net查看文件中的图标】项目的设计界面

把Visual Studio Net当前窗口切换到Formvb的代码编辑窗口并用下列代码替换Formvb中的Button组件的Click事件的处理代码下列代码是在Button组件的Click事件中处理查看文件中图标的功能具体如下

Private Sub Button_Click ( ByVal sender As SystemObject ByVal e As SystemEventArgs ) Handles ButtonClick

If OpenFileDialogShowDialog ( ) = DialogResultOK Then

清除组件中的所有项目

ListViewItemsClear ( )

ImageListImagesClear ( )

Dim sfName As String = OpenFileDialogFileName

LabelText = sfName

Dim iIcon_Num As Integer = Icon_Num ( IntPtrZero sfName )

显示文件中的图标数目

LabelText = iIcon_NumToString ( )

Dim i As Integer

For i = To iIcon_Num Step

强制实现int到uint类型转换

Dim j As UInt

j = SystemConvertToUInt ( i )

Dim hIcon As SystemIntPtr = ExtractIcon ( IntPtrZero sfName j )

在imageList组件中加入当然提取的图标

ImageListImagesAdd ( IconFromHandle ( hIcon )ToBitmap ( ) )

在ListView组件中加入一个项目

ListViewItemsAdd ( + ( i + )ToString ( ) + 个图标 )

把加入项目的图象索引指向刚才加入图标在imagList组件中的索引从而显示图标

ListViewItems ( i )ImageIndex = i

Next i

End If

End Sub

至此在上述步骤都正确执行后【Visual Basic Net查看文件中的图标】项目的全部工作就完成了单击快捷键F就可以运行程序此时单击【选择文件】按钮选择文件后程序就能够读取这个文件中的图标及其数目并显示出来了具体如图所示

【Visual Basic Net查看文件中的图标】项目的运行界面

五.总结

解决Visual Basic Net查看文件中的图标的关键并非是使用Net框架中提供的类库而是使用Windows的API函数虽然这与利用Visual Basic Net开发跨平台程序的初衷相违背但的确不失为一种解决问题的方法有些时候通过Windows API函数能够快捷方便的解决实际问题而这往往是只使用Net FrameWork SDK所望尘莫及的但随着Net FrameWork SDK内容的不断丰富各种新的组成部分和新的功能不断加入可以预见的是在未来的Net FrameWork SDK中必将拥有可以替换本文中介绍的二个Windows API函数的组成部分

上一篇:在VB.NET编程中使用数组

下一篇:VB.NET中常量与枚举基础知识了解