不會這個API,不過提醒下,.net的API聲明類型都為Integer,不是Long
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:主機域名、網(wǎng)站空間、營銷軟件、網(wǎng)站建設(shè)、肇慶網(wǎng)站維護、網(wǎng)站推廣。
Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long)
LoadImage
就是函數(shù)!
ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long
hInst
un1
n1
n2
un2
就是參數(shù)!
現(xiàn)在我用我所知道的為樓主介紹VB.NET的API調(diào)用,請樓主瀏覽一下,看看行不行。
Windows API就是Windows系統(tǒng)的API函數(shù)簡稱(Application Program Interface,即:應用程序接口函數(shù)),它是Windows操作系統(tǒng)提供給各種開發(fā)基于Windows平臺應用軟件的開發(fā)語言的一些公用的函數(shù),這些函數(shù)一般都比較底層,所以當各種開發(fā)語言使用自帶的函數(shù)或類庫已無法解決問題時,調(diào)用Windows API函數(shù)往往是一種非常直接、有效的解決方法。但由于在程序中調(diào)用Windows API函數(shù)一般都很復雜,所以對于程序員來說,是否能夠靈活的使用Windows API函數(shù),往往也是其水平高低的一個重要標志。但自從微軟推出.Net框架以后,各種開發(fā)基于.Net平臺下的程序語言,如Visual Basic .Net、Visual C#等卻很少使用Windows API函數(shù),并且微軟公司也不像以前那樣,提倡在這些.Net開發(fā)語言中使用Windows API函數(shù),其主要的原因如下:
1. .Net框架所附帶的類庫.Net FrameWork SDK是一個內(nèi)容豐富、功能強大的軟件開發(fā)包,各種Windows API函數(shù)所實現(xiàn)的各種功能幾乎都可以在這個軟件開發(fā)包中找到與之對應的部分。
2. 微軟Visual Basic .Net、Visual C#等目的是編寫跨平臺的應用程序,如果在Visual Basic .Net、Visual C#等中使用Windows API函數(shù),這也就注定了編寫出的程序只能運行于Windows平臺之下,而弱化了.NET的跨平臺能力。這也就是為什么微軟不提倡在.Net平臺調(diào)用Windows API函數(shù)的原因。
雖然微軟并不提倡在Visual Basic .Net、Visual C#中調(diào)用Windows API函數(shù),但由于目前.Net 框架推出時間較短,.Net FrameWork SDK中提供的類庫還并不足以完全替換Windows API函數(shù)的所有功能,所以在某些時候,.Net開發(fā)語言還是必須要調(diào)用Windows API函數(shù)。
一.平臺調(diào)用、托管DLL、非托管DLL簡介:
托管DLL就是能夠在公共語言運行庫(Common Language Runtime,簡稱CLR)中能夠直接引用的,并且擴展名為“DLL”的文件。具體所指就是封裝各種命名空間所在的DLL文件,如System.dll等。非托管DLL就是平常所的動態(tài)鏈接庫等,其中就包括了封裝所有Windows API函數(shù)的DLL文件。各種非托管DLL中的函數(shù)在公共語言運行庫中不能直接被調(diào)用,而需要經(jīng)過.Net框架提供的“平臺調(diào)用”服務(wù)后才可以。
“平臺調(diào)用”是.Net框架為Visual Basic .Net、Visual C#等.Net開發(fā)語言提供的一種服務(wù),用以在托管代碼中引入各種非托管DLL中封裝的函數(shù)(其中包括Windows API函數(shù))?!捌脚_調(diào)用”依賴于元數(shù)據(jù)在運行時查找導出函數(shù)并封裝其參數(shù)。圖01公共語言運行庫利用“平臺服務(wù)”調(diào)用非托管DLL中的函數(shù)的流程圖:
圖01:“平臺服務(wù)”的調(diào)用非托管函數(shù)的流程圖
在托管代碼中使用“平臺調(diào)用”服務(wù)調(diào)用非托管DLL中封裝的函數(shù)時,“平臺服務(wù)”將依次執(zhí)行以下操作:
1. 查找包含該函數(shù)所在的DLL文件。
2. 如果找到,則將該DLL文件 加載到內(nèi)存中。
3. 查找函數(shù)在內(nèi)存中的地址并將其參數(shù)推到堆棧上,并封送所需的數(shù)據(jù)。
4. 將控制權(quán)轉(zhuǎn)移給非托管函數(shù)。 這樣整個函數(shù)調(diào)用完成。
在Visual Basic .Net中使用“平臺調(diào)用”服務(wù),申明Windows API函數(shù)主要有二種具體的實現(xiàn)方法:
1. 使用DllImport特征類來申明Windows API函數(shù)。
2. 使用“Declare”語句來申明Windows API函數(shù)。
這二種方法雖有異曲同工之效,但在繁簡上卻有很大差異,第一種方法申明過程比較復雜,很容易在申明Windows API函數(shù)時出錯,所以并不提倡。而第二種方法相對簡單,并且又保存了以前Visual Basic中的很多語法,所以在平常時大都使用這種方法來申明Windows API函數(shù)。
二.VB.Net查看文件中圖標的函數(shù)及申明Windows API的方法:
Visual Basic .Net要實現(xiàn)查看文件中的圖標,目前只使用.Net FrameWork SDK是無法實現(xiàn)這種功能的,正如前面所說,主要是由于.Net FrameWork SDK推出的時間較短,其功能還不可能面面俱到。解決問題的關(guān)鍵是正確使用Windows API函數(shù),其中所涉及到的Windows API函數(shù)主要有二個:其一是獲得指定文件中的圖標數(shù)目;其二是從指定文件的指定位置導出圖標的Windows句柄。這二個函數(shù)都位于“Shell32.dll”文件中,并且函數(shù)的入口點都為“ExtractIcon”。下面是在Visual Basic .Net中分別使用DllImport特征類和“Declare”語句申明這二個Windows API函數(shù)的具體方法。
(1).使用DllImport特征類來申明Windows API函數(shù):
下面是在Visual Basic .Net中使用DllImport特征類申明二個Windows API函數(shù)的具體示例:
'函數(shù)ExtractIcon,其功能是是從指定文件的指定位置導出圖標的Windows句柄。
< System.Runtime.InteropServices.DllImport ( "Shell32.dll" , EntryPoint := "ExtractIcon" ) > _
Public Function _
ExtractIcon ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr
End Function
'函數(shù)Icon_Num,其功能是獲得指定文件中的圖標數(shù)目
< System.Runtime.InteropServices.DllImport ( "Shell32.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函數(shù)時,如果申明的函數(shù)名稱和函數(shù)的入口點相同,則可以在申明Windows API函數(shù)時,省略定義函數(shù)入口點對應的代碼,即EntryPoint對象字段對應的代碼,這樣聲明ExtractIcon函數(shù)的代碼也可以簡化為如下所示:
< System.Runtime.InteropServices.DllImport ( "Shell32.dll" ) > _
Public Function _
ExtractIcon ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr
End Function
(2).使用“Declare”語句來申明Windows API函數(shù):
使用“Declare”語句的確比使用DllImport特征類要簡單了許多,下面是在Visual Basic .Net中使用“Declare”語句來聲明上述二個Windows API函數(shù)的具體方法:
Declare Auto Function ExtractIcon Lib "Shell32.dll" Alias "ExtractIcon" ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr
'聲明ExtractIcon函數(shù)
Declare Auto Function Icon_Num Lib "Shell32.dll" Alias "ExtractIcon" ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As Integer ) As Integer
'聲明Icon_Num函數(shù)
在Visual Basic .Net中聲明Windows API函數(shù)時,“Declare”語句中Alias關(guān)鍵字的作用相當于使用DllImport特征類中的EntryPoint對象字段。同樣在使用“Declare”語句聲明Windows API函數(shù)時,如果聲明的函數(shù)和函數(shù)的入口點相同,也可以省略Alias關(guān)鍵字對應的代碼,所以ExtractIcon函數(shù)也可以簡化為如下:
Declare Auto Function ExtractIcon Lib "Shell32.dll" ( ByVal src As System.IntPtr , ByVal strFileName As string , ByVal uiIconIndex As UInt32 ) As System.IntPtr
下面就結(jié)合一個示例的編寫過程來掌握的這二個Windows API函數(shù)的具體使用方法,這個示例的作用就是讀取指定文件中的圖標數(shù)目,并顯示文件中的圖標。
三.本文中程序的編寫、調(diào)試和運行環(huán)境:
(1).視窗2000高級服務(wù)器版。
(2).Visual Studio .Net 2003企業(yè)結(jié)構(gòu)設(shè)計版,.Net FrameWork SDK版本號4322。
四.Visual Basic .Net讀取文件中的圖標的實現(xiàn)步驟:
下面介紹的示例,其功能讀取指定文件中包含的圖標數(shù)目,并把這些圖標全部顯示出來。下面是這個示例的實現(xiàn)步驟:
1. 啟動Visual Studio .Net。
2. 選擇菜單【文件】|【新建】|【項目】后,彈出【新建項目】對話框。
3. 將【項目類型】設(shè)置為【Visual Basic項目】。
4. 將【模板】設(shè)置為【W(wǎng)indows應用程序】。
5. 在【名稱】文本框中輸入【Visual Basic .Net查看文件中的圖標】。
6. 在【位置】的文本框中輸入【E:\VS.NET項目】,然后單擊【確定】按鈕,這樣在【E:\VS.NET項目】目錄中就產(chǎn)生了名稱為【Visual Basic .Net查看文件中的圖標】文件夾,里面存放著【Visual Basic .Net查看文件中的圖標】項目的所有文件。具體如圖02所示:
圖02:【Visual Basic .Net查看文件中的圖標】項目的【新建項目】對話框
7. 選擇菜單【項目】|【添加新項】,在彈出的對話框中的【模板】設(shè)置為【模塊】,【名稱】文本框設(shè)置為【Module1.vb】后。單擊【打開】按鈕,則在項目中增加了一個模板文件,名稱為【Module1.vb】。
8. 把Visual Stuido .Net的當前窗口切換到Module1.vb的代碼編輯窗口,并在其Module1的代碼區(qū)中添加下列代碼,下列代碼是用二種方式聲明二個Windows API函數(shù):
< System.Runtime.InteropServices.DllImport ( "Shell32.dll" ) > _
Public Function _
ExtractIcon ( ByVal src As System.IntPtr , ByVal strFileName As String , ByVal uiIconIndex As UInt32 ) As System.IntPtr
End Function
'聲明ExtractIcon函數(shù)
Declare Auto Function Icon_Num Lib "Shell32.dll" Alias "ExtractIcon" ( ByVal src As System.IntPtr , ByVal strFileName As String , ByVal uiIconIndex As Integer ) As Integer
9. 把Visual Studio .Net的當前窗口切換到Form1窗體的設(shè)計查看,并從【工具箱】中的【W(wǎng)indows窗體】選項卡中拖入下列組件到Form1窗體:
四個Label組件,其中二個用以顯示提示信息,另外二個分別用以顯示選擇的文件名稱和這個文件中包含的圖標數(shù)目。
一個ListView組件,利用其顯示大圖標的屬性用以顯示選定文件中的圖標。
一個OpenFileDialog組件,用以選擇要查看圖標的文件名稱。
一個ImageList組件,它起的是橋梁的作用,首先把從文件中導出的圖標存放到這里,然后再提供ListView組件顯示出來。
一個Button組件。
10. 按照表01中數(shù)值來設(shè)定設(shè)定組件的主要屬性:
組件類型 組件名稱 屬性 設(shè)置結(jié)果
Form Form1 Text VB.NET查看文件中的圖標
Form1 MaximizeBox False
Form1 MinimizeBox False
Form1 FormBorderStyle FixedSingle
ListView ListView1 ImageList1 LargeImageList
ListView1 MultiSelect False
ListView1 Size Size ( 380 , 208 )
Button Button1 Text 選擇文件
Button1 FlatStyle Flat
ImageList ImageList1 Size Size ( 32 , 32 )
ImageList1 TransparentColor Color.Transparent
Label Label1 Text 文件名稱:
Label2 Text 圖標數(shù)目:
Label3 Text ""
Label4 Text "0"
表01:【Visual Basic .Net查看文件中的圖標】項目窗體中各組件的主要屬性設(shè)定數(shù)值表
并按照圖02中各組件的位置、大小和排列方式來調(diào)整窗體中各個組件:
圖02:【Visual Basic .Net查看文件中的圖標】項目的設(shè)計界面
11. 把Visual Studio .Net當前窗口切換到Form.vb的代碼編輯窗口,并用下列代碼替換Form1.vb中的Button1組件的Click事件的處理代碼,下列代碼是在Button1組件的Click事件中處理查看文件中圖標的功能,具體如下:
Private Sub Button1_Click ( ByVal sender As System.Object , ByVal e As System.EventArgs ) Handles Button1.Click
If OpenFileDialog1.ShowDialog ( ) = DialogResult.OK Then
'清除組件中的所有項目
ListView1.Items.Clear ( )
ImageList1.Images.Clear ( )
Dim sfName As String = OpenFileDialog1.FileName
Label3.Text = sfName
Dim iIcon_Num As Integer = Icon_Num ( IntPtr.Zero , sfName , -1 )
'顯示文件中的圖標數(shù)目
Label4.Text = iIcon_Num.ToString ( )
Dim i As Integer
For i = 0 To iIcon_Num - 1 Step 1
'強制實現(xiàn)int到uint類型轉(zhuǎn)換
Dim j As UInt32
j = System.Convert.ToUInt32 ( i )
Dim hIcon As System.IntPtr = ExtractIcon ( IntPtr.Zero , sfName , j )
'在imageList1組件中加入當然提取的圖標
ImageList1.Images.Add ( Icon.FromHandle ( hIcon ).ToBitmap ( ) )
'在ListView組件中加入一個項目
ListView1.Items.Add ( "第" + ( i + 1 ).ToString ( ) + "個圖標" )
'把加入項目的圖象索引指向剛才加入圖標在imagList1組件中的索引,從而顯示圖標
ListView1.Items ( i ).ImageIndex = i
Next i
End If
End Sub
12. 至此,在上述步驟都正確執(zhí)行后,【Visual Basic .Net查看文件中的圖標】項目的全部工作就完成了。單擊快捷鍵F5就可以運行程序,此時單擊【選擇文件】按鈕選擇文件后,程序就能夠讀取這個文件中的圖標及其數(shù)目,并顯示出來了。具體如圖03所示:
圖03:【Visual Basic .Net查看文件中的圖標】項目的運行界面
五.總結(jié):
解決Visual Basic .Net查看文件中的圖標的關(guān)鍵并非是使用.Net框架中提供的類庫,而是使用Windows的API函數(shù)。雖然這與利用Visual Basic .Net開發(fā)跨平臺程序的初衷相違背,但的確不失為一種解決問題的方法。有些時候通過Windows API函數(shù)能夠快捷、方便的解決實際問題,而這往往是只使用.Net FrameWork SDK所望塵莫及的,但隨著.Net FrameWork SDK內(nèi)容的不斷豐富,各種新的組成部分和新的功能不斷加入,可以預見的是,在未來的.Net FrameWork SDK中必將擁有可以替換本文中介紹的二個Windows API函數(shù)的組成部分。
我寫了個API?Tools,已上傳到CSDN上,你搜索一下。類似于API查詢器,但是功能更強大,支持生成4種語言的API代碼,支持查詢API函數(shù)、API相關(guān)的結(jié)構(gòu)體、API相關(guān)的常量數(shù)值及錯誤代碼,詳見說明。
API(Advanced Programmers Interface,高級程序員接口)(注:API實際是指Application Programming Interface,應用程序編程接口;此處疑為原文錯誤,不過在VB中也可以這么說吧!)是一套用來控制Windows的各個部件(從桌面的外觀到位一個新進程分配的內(nèi)存)的外觀和行為的一套預先定義的Windows函數(shù).用戶的每個動作都會引發(fā)一個或幾個函數(shù)的運行以Windows告訴發(fā)生了什么.
這在某種程度上很象Windows的天然代碼.其他的語言只是提供一種能自動而且更容易的訪問API的方法.VB在這方面作了很多工作.它完全隱藏了API并且提供了在Windows環(huán)境下編程的一種完全不同的方法.
這也就是說,你用VB寫出的每行代碼都會被VB轉(zhuǎn)換為API函數(shù)傳遞給Windows.例如,Form1.Print...VB 將會以一定的參數(shù)(你的代碼中提供的,或是默認參數(shù))調(diào)用TextOut 這個API函數(shù).
同樣,當你點擊窗體上的一個按鈕時,Windows會發(fā)送一個消息給窗體(這對于你來說是隱藏的),VB獲取這個調(diào)用并經(jīng)過分析后生成一個特定事件(Button_Click).
API函數(shù)包含在Windows系統(tǒng)目錄下的動態(tài)連接庫文件中(如User32.dll,GDI32.dll,Shell32.dll...).
API 聲明
正如在"什么是API"中所說,API函數(shù)包含在位于系統(tǒng)目錄下的DLL文件中.你可以自己輸入API函數(shù)的聲明,但VB提供了一種更簡單的方法,即使用API Text Viewer.
要想在你的工程中聲明API函數(shù),只需運行API Text Viewer,打開Win32api.txt(或.MDB如果你已經(jīng)把它轉(zhuǎn)換成了數(shù)據(jù)庫的話,這樣可以加快速度.注:微軟的這個文件有很多的不足,你可以試一下本站提供下載的api32.txt),選擇"聲明",找到所需函數(shù),點擊"添加(Add)"并"復制(Copy)",然后粘貼(Paste)到你的工程里.使用預定義的常量和類型也是同樣的方法.
你將會遇到一些問題:
假設(shè)你想在你的窗體模塊中聲明一個函數(shù).粘貼然后運行,VB會告訴你:編譯錯誤...Declare 語句不允許作為類或?qū)ο竽K中的 Public 成員...看起來很糟糕,其實你需要做的只是在聲明前面添加一個Private(如 Private Declare Function...).--不要忘了,可是這將使該函數(shù)只在該窗體模塊可用.
在有些情況下,你會得到"不明確的名稱"這樣的提示,這是因為函數(shù).常量或其他的什么東西共用了一個名稱.由于絕大多數(shù)的函數(shù)(也可能是全部,我沒有驗證過)都進行了別名化,亦即意味著你可以通過Alias子句使用其它的而不是他們原有的名稱,你只需簡單地改變一下函數(shù)名稱而它仍然可以正常運行.
你可以通過查看VB的Declare語句幫助主題來獲取有關(guān)Alias的詳細說明.