Windows API就是Windows系統的API函數簡稱(Application Program Interface
即
應用程序接口函數)
它是Windows操作系統提供給各種開發基於Windows平台應用軟件的開發語言的一些公用的函數
這些函數一般都比較底層
所以當各種開發語言使用自帶的函數或類庫已無法解決問題時
調用Windows API函數往往是一種非常直接
有效的解決方法
但由於在程序中調用Windows API函數一般都很復雜
所以對於程序員來說
是否能夠靈活的使用Windows API函數
往往也是其水平高低的一個重要標志
但自從微軟推出
Net框架以後
各種開發基於
Net平台下的程序語言
如Visual Basic
Net
Visual C#等卻很少使用Windows API函數
並且微軟公司也不像以前那樣
提倡在這些
Net開發語言中使用Windows API函數
其主要的原因如下
Net框架所附帶的類庫
Net FrameWork SDK是一個內容豐富
功能強大的軟件開發包
各種Windows API函數所實現的各種功能幾乎都可以在這個軟件開發包中找到與之對應的部分
微軟Visual Basic
Net
Visual C#等目的是編寫跨平台的應用程序
如果在Visual Basic
Net
Visual C#等中使用Windows API函數
這也就注定了編寫出的程序只能運行於Windows平台之下
而弱化了
NET的跨平台能力
這也就是為什麼微軟不提倡在
Net平台調用Windows API函數的原因
雖然微軟並不提倡在Visual Basic
Net
Visual C#中調用Windows API函數
但由於目前
Net 框架推出時間較短
Net FrameWork SDK中提供的類庫還並不足以完全替換Windows API函數的所有功能
所以在某些時候
Net開發語言還是必須要調用Windows API函數
一
平台調用
托管DLL
非托管DLL簡介
托管DLL就是能夠在公共語言運行庫(Common Language Runtime
簡稱CLR)中能夠直接引用的
並且擴展名為
DLL
的文件
具體所指就是封裝各種命名空間所在的DLL文件
如System
dll等
非托管DLL就是平常所的動態鏈接庫等
其中就包括了封裝所有Windows API函數的DLL文件
各種非托管DLL中的函數在公共語言運行庫中不能直接被調用
而需要經過
Net框架提供的
平台調用
服務後才可以
平台調用
是
Net框架為Visual Basic
Net
Visual 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句柄
這二個函數都位於
Shell
dll
文件中
並且函數的入口點都為
ExtractIcon
下面是在Visual Basic
Net中分別使用DllImport特征類和
Declare
語句申明這二個Windows API函數的具體方法
(
)
使用DllImport特征類來申明Windows API函數
下面是在Visual Basic
Net中使用DllImport特征類申明二個Windows API函數的具體示例
函數ExtractIcon
其功能是是從指定文件的指定位置導出圖標的Windows句柄
< System
Runtime
InteropServices
DllImport (
Shell
dll
EntryPoint :=
ExtractIcon
) > _
Public Function _
ExtractIcon ( ByVal src As System
IntPtr
ByVal strFileName As string
ByVal uiIconIndex As UInt
) As System
IntPtr
End Function
函數Icon_Num
其功能是獲得指定文件中的圖標數目
< System
Runtime
InteropServices
DllImport (
Shell
dll
EntryPoint :=
ExtractIcon
) > _
Public Function _
Icon_Num ( ByVal src As System
IntPtr
ByVal strFileName As string
ByVal uiIconIndex As Integer ) As Integer
End Function
在使用DllImport特征類申明Windows API函數時
如果申明的函數名稱和函數的入口點相同
則可以在申明Windows API函數時
省略定義函數入口點對應的代碼
即EntryPoint對象字段對應的代碼
這樣聲明ExtractIcon函數的代碼也可以簡化為如下所示
< System
Runtime
InteropServices
DllImport (
Shell
dll
) > _
Public Function _
ExtractIcon ( ByVal src As System
IntPtr
ByVal strFileName As string
ByVal uiIconIndex As UInt
) As System
IntPtr
End Function
(
)
使用
Declare
語句來申明Windows API函數
使用
Declare
語句的確比使用DllImport特征類要簡單了許多
下面是在Visual Basic
Net中使用
Declare
語句來聲明上述二個Windows API函數的具體方法
Declare Auto Function ExtractIcon Lib
Shell
dll
Alias
ExtractIcon
( ByVal src As System
IntPtr
ByVal strFileName As string
ByVal uiIconIndex As UInt
) As System
IntPtr
聲明ExtractIcon函數
Declare Auto Function Icon_Num Lib
Shell
dll
Alias
ExtractIcon
( ByVal src As System
IntPtr
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
Shell
dll
( ByVal src As System
IntPtr
ByVal strFileName As string
ByVal uiIconIndex As UInt
) As System
IntPtr
下面就結合一個示例的編寫過程來掌握的這二個Windows API函數的具體使用方法
這個示例的作用就是讀取指定文件中的圖標數目
並顯示文件中的圖標
三.本文中程序的編寫調試和運行環境 (
)
視窗
高級服務器版
(
)
Visual Studio
Net
企業結構設計版
Net FrameWork SDK版本號
四.Visual Basic Net讀取文件中的圖標的實現步驟 下面介紹的示例
其功能讀取指定文件中包含的圖標數目
並把這些圖標全部顯示出來
下面是這個示例的實現步驟
啟動Visual Studio
Net
選擇菜單【文件】|【新建】|【項目】後
彈出【新建項目】對話框
將【項目類型】設置為【Visual Basic項目】
將【模板】設置為【Windows應用程序】
在【名稱】文本框中輸入【Visual Basic
Net查看文件中的圖標】
在【位置】的文本框中輸入【E:\VS
NET項目】
然後單擊【確定】按鈕
這樣在【E:\VS
NET項目】目錄中就產生了名稱為【Visual Basic
Net查看文件中的圖標】文件夾
裡面存放著【Visual Basic
Net查看文件中的圖標】項目的所有文件
具體如圖
所示
圖
【Visual Basic
Net查看文件中的圖標】項目的【新建項目】對話框
選擇菜單【項目】|【添加新項】
在彈出的對話框中的【模板】設置為【模塊】
【名稱】文本框設置為【Module
vb】後
單擊【打開】按鈕
則在項目中增加了一個模板文件
名稱為【Module
vb】
把Visual Stuido
Net的當前窗口切換到Module
vb的代碼編輯窗口
並在其Module
的代碼區中添加下列代碼
下列代碼是用二種方式聲明二個Windows API函數
< System
Runtime
InteropServices
DllImport (
Shell
dll
) > _
Public Function _
ExtractIcon ( ByVal src As System
IntPtr
ByVal strFileName As String
ByVal uiIconIndex As UInt
) As System
IntPtr
End Function
聲明ExtractIcon函數
Declare Auto Function Icon_Num Lib
Shell
dll
Alias
ExtractIcon
( ByVal src As System
IntPtr
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
VB
NET查看文件中的圖標
Form
MaximizeBox
False
Form
MinimizeBox
False
Form
FormBorderStyle
FixedSingle
ListView
ListView
ImageList
LargeImageList
ListView
MultiSelect
False
ListView
Size
Size (
)
Button
Button
Text
選擇文件
Button
FlatStyle
Flat
ImageList
ImageList
Size
Size (
)
ImageList
TransparentColor
Color
Transparent
Label
Label
Text
文件名稱
Label
Text
圖標數目
Label
Text
Label
Text
表
【Visual Basic
Net查看文件中的圖標】項目窗體中各組件的主要屬性設定數值表
並按照圖
中各組件的位置
大小和排列方式來調整窗體中各個組件
圖
【Visual Basic
Net查看文件中的圖標】項目的設計界面
把Visual Studio
Net當前窗口切換到Form
vb的代碼編輯窗口
並用下列代碼替換Form
vb中的Button
組件的Click事件的處理代碼
下列代碼是在Button
組件的Click事件中處理查看文件中圖標的功能
具體如下
Private Sub Button
_Click ( ByVal sender As System
Object
ByVal e As System
EventArgs ) Handles Button
Click
If OpenFileDialog
ShowDialog ( ) = DialogResult
OK Then
清除組件中的所有項目
ListView
Items
Clear ( )
ImageList
Images
Clear ( )
Dim sfName As String = OpenFileDialog
FileName
Label
Text = sfName
Dim iIcon_Num As Integer = Icon_Num ( IntPtr
Zero
sfName
)
顯示文件中的圖標數目
Label
Text = iIcon_Num
ToString ( )
Dim i As Integer
For i =
To iIcon_Num
Step
強制實現int到uint類型轉換
Dim j As UInt
j = System
Convert
ToUInt
( i )
Dim hIcon As System
IntPtr = ExtractIcon ( IntPtr
Zero
sfName
j )
在imageList
組件中加入當然提取的圖標
ImageList
Images
Add ( Icon
FromHandle ( hIcon )
ToBitmap ( ) )
在ListView組件中加入一個項目
ListView
Items
Add (
第
+ ( i +
)
ToString ( ) +
個圖標
)
把加入項目的圖象索引指向剛才加入圖標在imagList
組件中的索引
從而顯示圖標
ListView
Items ( 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函數的組成部分
From:http://tw.wingwit.com/Article/program/net/201311/12511.html