日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

VB中的API詳解

 云中凌 2015-04-18

一、API是什么?

  這個我本來不想說的,不過也許你知道其它人不知道,這里為了照顧一下新手,不得不說些廢話,請大家諒解。

  Win32 API即為Microsoft 32位平臺的應(yīng)用程序編程接口(Application Programming Interface)。所有在Win32平臺上運行的應(yīng)用程序都可以調(diào)用這些函數(shù)。

  使用Win32 API,應(yīng)用程序可以充分挖掘Windows的32位操作系統(tǒng)的潛力。Mircrosoft的所有32位平臺都支持統(tǒng)一的API,包括函數(shù)、結(jié)構(gòu)、消息、宏及接口。使用 Win32 API不但可以開發(fā)出在各種平臺上都能成功運行的應(yīng)用程序,而且也可以充分利用每個平臺特有的功能和屬性。

  
  以上為API的相關(guān)介紹,不過有些新手看了以后可能還是不怎么明白API到底有什么用?這里請不要著急,如果你有足夠耐心的話,請慢慢往下看。

二、如何使用API?

  估計這才是大家真正關(guān)心的,那么如何使用API呢?在了解API之前,先打開你的VB書,翻到過程函數(shù)這章來,在搞清楚API之前應(yīng)該先搞懂過程函數(shù)是怎么一回事!如果你還不知道過程的工作方式,那么請先不要急著往下看,那樣容易走很多彎路。

  好了,當(dāng)你理解了過程函數(shù)時,也就是你可以使用API的時候了,別把API看得太難,你就像使用過程函數(shù)一樣使用API就可以了。首先,讓我們看看一個簡單的API,以下:

  Private Declare Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)

  以上這個API的呢是起一個延時作用。你如果是剛接觸API的話可能會感到API的書寫及其復(fù)雜,而且會感到很不適應(yīng)。其實這沒什么的,慢慢習(xí)慣就好了。至于API這些復(fù)雜的書寫你就不用操心了,在你安裝VB的時候微軟已經(jīng)幫我們帶上了API瀏覽器,這些全部都可以利用API瀏覽器幫我們自動生成。API瀏覽器的位置位于[開始菜單-程序-Microsoft Visual Basic 6.0 中文版-Microsoft Visual Basic 6.0 中文版工具-API 文本瀏覽器]。打開API瀏覽器,在最上面的一個文本框中輸入Sleep,這時下面列表框中就會自動顯示相應(yīng)的API函數(shù),然后點右邊添加按鈕即可,接著點擊復(fù)制按鈕,這時你就可以用Ctrl+V把聲明的API添加到VB代碼窗口中了。

  這里我要說一下,有些新手可能還弄不明白。API的聲明范圍一般有兩種模式,一種是Private(私有的),一種是Public(公用的)。一般Private是聲明在類模塊或窗體類中,Public聲明在模塊中。你在添加API的時候,添加按鈕下面就有API的聲明范圍,可以根據(jù)自己的需要進(jìn)行添加。這里我們一般選擇私有的(Private)就可以了。

  經(jīng)過上面,我們知道如何添加API,接著我們分析一下API聲明,這是你了解API必備的。首先看第一個單詞Private,很顯然,我上面剛剛講過,這是申明一個私有的API變量。再看第二個Declare,這個單詞幫我們告訴VB是在申明API函數(shù),一般申明外在的API函數(shù)時都必須帶上這個單詞。第三個Sub,別告訴我你不知道什么意思?這就是我叫你先學(xué)習(xí)VB中過程函數(shù)的意思,這個說白了就是沒有反回值,一般如果不是Sub而是Function都帶有反回值的。第四個Lib,這個是告訴VB我們要聲明哪一個DLL中的API函數(shù),也就是告訴VB我們要申明第五個單詞kernel32.dLL中的API,一般寫DLL名稱時都要用雙引號括起來,如"user32"、"shell32.dll"等,至于后面的.dll這個可以帶可不帶。再來看第六個Alias,這個也是需要同后面一個一起用的,我們應(yīng)該把第六個和第七個連起來一起看Alias "Sleep",這個意思表示將被調(diào)用的過程在DLL中還有另外的名稱,這個是可選的。最后括號里面的,也就是和過程函數(shù)一樣,你傳入相應(yīng)的值就可以了。

  上面我們分析完API函數(shù)聲明以后,接著我們就要自己動手寫代碼了。先把這個API復(fù)制到Form1代碼窗口中,然后寫如下代碼:

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Sub Form_Load()
    Sleep 2000
End Sub

  解釋一下,也就是在窗體啟動時使用Sleep API進(jìn)行延時2秒,后面的參數(shù)dwMilliseconds是表示你要延時的秒數(shù),基本上和設(shè)置Timer中的秒數(shù)一樣。你再看一下Sleep 2000的使用方式,是不是和使用VB過程函數(shù)一樣呢?好了,我們的第一個VB API程序?qū)懲炅?,可以看到使用API并不是一件很難的事。

三、如何才能提升你對API的學(xué)習(xí)興趣?

  API,我常把它看做成過程函數(shù),不過每人都有每人的見解和理解方式,自己的理解方式只要可以幫助自己更好的學(xué)習(xí)和掌握API,也沒必要一定要學(xué)習(xí)他人的。

  1,自己做MsgBox

  了解API參數(shù)的使用方法是很重要的,這里我們不用VB的MsgBox,直接使用API彈出MsgBox消息框。首先,打開API瀏覽器,選擇MessageBox,大家可以用這個API和VB內(nèi)置的MsgBox比較一下,其實MsgBox也就是MessageBox的縮寫,只不過一個是API,一個是VB內(nèi)置的,但兩者都是通過API進(jìn)行工作的。好了,選擇私有聲明方式,粘貼到VB代碼編輯窗口中,然后新建一個CommandButton,寫入以下代碼:

Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA"
(ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String,
ByVal wType As Long) As Long
Private Sub Command1_Click()
    MessageBox Me.hwnd, "這里是內(nèi)容", "標(biāo)題", 0
End Sub

  先讓我們來分析一下,首先看第一個參數(shù)Byval hWnd As Long,很顯然這是一個長整形變量,所以我們這里需要傳遞的是數(shù)字,你可能會發(fā)現(xiàn)我們傳遞的并不是數(shù)字啊,而是 Me.hwnd??很奇怪是嗎?如果你真的有此疑問說明你是真心想要學(xué)習(xí)好API的,現(xiàn)在就讓我們來看看Me.hwnd到底是什么東西?以下摘自VB幫助文檔:
  hWnd 屬性:返回窗體或控件的句柄。
  句 柄:是由操作環(huán)境定義的一個唯一的整數(shù)值,它被程序用來標(biāo)識或者切換到對象,如窗體或控件等。

  現(xiàn)在估計你差不多就已經(jīng)明白了,我們調(diào)用的hwnd其實是一個句柄整數(shù)值,你可以用 Msgbox Me.hwnd 看一下就知道了。至于Me這是一個關(guān)鍵字,代表當(dāng)前Form窗體對象。如:Me.Caption="標(biāo)題"、Me.BackColor=vbRed等。

  接上面的,首先我們傳入了Me.hwnd,表示是當(dāng)前窗口調(diào)用MessageBox,這里告訴大家一個技巧,也就是以后凡是看到Byval hwnd As Long,一般都是需要傳入句柄的,至于傳入哪個對象句柄,那就要看你是怎么實現(xiàn)的了。
  ByVal lpText As String,這個是字符串變量,標(biāo)識著叫我們需要傳入字符串進(jìn)去,可以看里面的變量字符lpText,屬于文本的意思,也就是說是用來顯示MsgBox中的消息文本的。
  ByVal lpCaption As String,也是字符串變量,還是傳入字符串進(jìn)去。在看里面的變量字符lpCaption,其實就是顯示MsgBox標(biāo)題的。
  ByVal wType As Long,這是一個整形變量,需要傳遞整形數(shù)字,還是看里面的變量字符wType,標(biāo)識著顯示MsgBox類型,這里可以像VB的MsgBox一樣使用,如這里可以傳入:vbYesNo,vbOkCancel等,如果忽略那就傳入0即可。

  好了,按F5啟動程序,點擊Command1,接著就會彈出一個消息框,這里我們制作以及分析MsgBox已經(jīng)完成了。希望你能在這段學(xué)習(xí)到一些知識。

  2,來點實用的吧

  就拿隱藏Windows任務(wù)管理器來說吧,這里只能隱藏任務(wù)管理器中的窗口,不能隱藏進(jìn)程。(問:有沒有隱藏進(jìn)程的?答:你想干什么?),當(dāng)程序運行后你無法從任務(wù)管理器的窗口中關(guān)閉程序,只能從進(jìn)程中進(jìn)行終止。好了,還是老規(guī)矩,打開API瀏覽器,輸入GetWindow和ShowWindow兩個API,聲明范圍還是私有的,復(fù)制粘貼到Form代碼窗口中,嗯,好了?別急,還是API瀏覽器,選擇Combox中的常數(shù),輸入GW_OWNER和SW_HIDE這兩個API常數(shù),然后粘貼到代碼窗口中,問我這兩個是干什么的?那就接著往下看吧。寫入以下代碼:

Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long,
ByVal wCmd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long,
ByVal nCmdShow As Long) As Long
Private Const GW_OWNER = 4
Private Const SW_HIDE = 0
Private Sub Form_Load()
    Dim lphWnd As Long
    lphWnd = GetWindow(Me.hwnd, GW_OWNER)
    ShowWindow lphWnd, SW_HIDE
End Sub

  又到了分析的時候了,這對剛?cè)腴T的新手可謂是最激動的時候了。好了,還是老子,看看兩個API的表面意思和傳遞值變量。

  先看GetWindow,表面意思:獲取窗口。傳遞值變量:hWnd整形句柄,wCmd整形命令值。
  再看ShowWindow,表面意思:顯示窗口。傳遞值變量:hWnd整形句柄,nCmdShow整形命令值。

  然后是使用代碼,先看lphWnd = GetWindow(Me.hwnd, GW_OWNER)這句,這句意思是獲取當(dāng)前窗口的所有者窗口句柄,可以看到GetWindow是Function過程函數(shù),執(zhí)行以后會返回相應(yīng)的窗口句柄值,這個值為Long整形(同句柄)。接著調(diào)用ShowWindow lphWnd, SW_HIDE,這句意思是顯示lphwnd這個句柄的窗口,關(guān)鍵一句是最后的SW_HIDE,這是API函數(shù)的常量。通過設(shè)置常量能讓系統(tǒng)知道API到底應(yīng)該怎么執(zhí)行顯示窗口,是顯示?還是隱藏?Hide當(dāng)然是隱藏的意思。好了,編譯成Exe,運行后打開任務(wù)管理器,查看程序窗口,還有嗎?

  我又要說一下了,有些人可能不懂為什么要用GW_OWNER這些常量,這些到底有什么用?還有就是我怎么知道哪些API對應(yīng)哪些的常量?其實這些常量你只要稍微注意一下就知道它們是怎么回事了,如在GetWindow中我使用GW_OWNER,在ShowWindow中我使用SW_HIDE這些常量都有一個共同的特點,就是他們都是以API的單詞第一個字母為標(biāo)準(zhǔn)。如GetWindow相對應(yīng)的常量就是Get(G)Window(W)=GW,ShowWindow相對應(yīng)的常就是Show(S)Window(W)=SW,這些常量可以自己在VB的API瀏覽器中找找看。

  3,繼續(xù)往下學(xué)吧。。

    上面兩個我們講到了一般API的使用方法,和一些API常量的使用方法,接著我們來看看API類型的使用方法,在了解這一小節(jié)前請先搞懂VB中的自定義類型(Type)這章,否則你可能會稀里糊涂的,到時別怪我沒提醒你哦!

    這次讓我們來獲取一下鼠標(biāo)指針的位置。這里教大家一個技巧,當(dāng)你想用API去實現(xiàn)某一特定的功能時,卻又不知道該用哪個API,這時你可以就表面的意思到API瀏覽器找找,有70%以上的機(jī)率可以找到哦!現(xiàn)在就拿這個API開刀,那我們應(yīng)該如何找?別著急,往下看:

    如我們現(xiàn)在要獲取鼠標(biāo)指針位置,可以這樣翻譯一下:Get(獲取)Cursor(指針)Pos(位置),組合起來:GetCursorPos,呵呵,一條API就這樣出來了,到API瀏覽器輸入這個組合單詞,呵,有吧?見以下:

Private Declare Function GetCursorPos Lib "user32" Alias "GetCursorPos" (lpPoint As POINTAPI) As Long

    好了好了,高興一下就算了,現(xiàn)在讓我們分析一下這個API,看其它的沒啥不同的,其中只有一個參數(shù),就是最后一個變量有些不懂?在VB中好像沒有見過這個變量?不明白么?那就再繼續(xù)往下看。

    lpPoint As POINTAPI,POINTAPI?很顯然,在VB中并沒有此類型,一般都是String、Integer、Long、Byte等變量類型,那么這個也就理所當(dāng)然的是自定義類型(問:什么是自定義類型?答:不知道,自已不會看書啊)。既然是自定義類型,那么我們?nèi)绾尾拍苤浪侨绾味x的呢?這里也就不用你操心啦,還是API瀏覽器,在最上面的Combox中選擇類型,這時下面List中也就自然的把API的相關(guān)類型顯示出來了,現(xiàn)在我們開始在Text文本框中輸入我們需要的自定義類型,POINTAPI,點擊添加,出來了吧?如下:

Private Type POINTAPI
        x As Long
        y As Long
End Type

    好了,現(xiàn)在開始寫代碼,添加一個Timer控件,設(shè)置屬性見以下:

    Interval = 100
    Enabled  = True

    雙擊Timer控件,轉(zhuǎn)到代碼環(huán)境中寫入以下代碼:

Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Type POINTAPI
        x As Long
        y As Long
End Type
Private Sub Timer1_Timer()
    Dim lpPoint As POINTAPI
   
    GetCursorPos lpPoint
   
    Me.Caption = "X = " & lpPoint.x & " Y = " & lpPoint.y
End Sub

    好了,分析開始,緊張不?別緊張,沒啥值得緊張的!見以下:

    Dim lpPoint As POINTAPI,申明一個POINTAPI類型變量,我們學(xué)過自定義類型的朋友都知道,一般使用自定義類型時都需要先申明一個相關(guān)的類型變量方可使用。

    GetCursorPos lpPoint,這一步我不說你都知道,調(diào)用API唄。通過這個API獲取鼠標(biāo)指針的相關(guān)信息。這里我們使用了自己聲明的lpPoint變量,那為啥要使用這個變量呢?這里我們回過頭來就前兩節(jié)我們所分析的那樣進(jìn)行分析,可以看到GetCursorPos所需要傳遞的值,如果是Long,我們就傳入整形數(shù)字,如果是String,我們就傳入字符串,這里是POINTAPI,所以理所當(dāng)然是要傳入POINTAPI類型,但是!VB中的自定義類型不可以直接使用,所以我們需要先聲明一個相同類型的變量。不知道說了這么多你懂了沒?

 
    Me.Caption = "X = " & lpPoint.x & " Y = " & lpPoint.y,最后一句,也就是用來顯示當(dāng)前鼠標(biāo)的坐標(biāo)值的,我們通過聲明的lpPoint變量來獲取相應(yīng)的鼠標(biāo)坐標(biāo)值,如果你不懂,那就請你先把VB自定義類型這章學(xué)完再說。

    這里關(guān)于API的一些使用方法及范例就先介紹到這里,如果你還有耐心往下看下去的話,那我們就接著往下聊!

四、如何慢慢提升自己的API功力?

    何為API功力?其實沒必要搞那么清楚,首先需要搞明白的就是,你應(yīng)該知道在什么環(huán)境下使用什么API,實現(xiàn)哪些功能應(yīng)該使用哪些API!這才是我們需要的。

1,試著自己從小程序開始寫起。

    寫小程序?對!在你寫小程序時應(yīng)該揀你最感興趣的程序?qū)?,否則有可能你寫到一半以后會覺得自己這個程序?qū)懙煤翢o價值,簡直是在浪費時間,最后到頭來還是功虧一簣。這里我拿什么當(dāng)題材呢?我在這里也想了很久,最后還是決定選擇一個注銷Windows程序來做題材(其實這是我當(dāng)初學(xué)API最想實現(xiàn)的功能)。

    注銷Windows也就是退出Windows(重啟,關(guān)機(jī)等都一樣,不都是退出的意思嗎?),根據(jù)表面意思在API瀏覽器中輸入Exit(退出)Windows,看看有沒有這個API?這里提醒一下,你在查找這個API的時候還會看到ExitWindowsEX這個API,其實這兩個API實現(xiàn)的功能一樣,前者是用在16位操作系統(tǒng)上,只不過在Win32位操作系統(tǒng)上一般都使用ExitWindowsEX。所以這里就使用后者。API見以下:

 
  Private Declare Function ExitWindowsEx Lib "user32" Alias "ExitWindowsEx" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long

    看看里面的兩個參數(shù),ByVal uFlags As Long?這里我們需要傳入一個整形數(shù)字,可是應(yīng)該傳入什么數(shù)字呢?這里說下,API中的參數(shù)可以傳入不同的值,不同的值從而導(dǎo)致產(chǎn)生不同的結(jié)果。分析API中參數(shù)應(yīng)該傳遞哪些值其實是有技巧的,以后大家只要是看到參數(shù)字符中包函Flags字符的話那就說明該參數(shù)可以被傳入一個或多個標(biāo)志,并且大部分都是傳入API常數(shù)(什么是API常數(shù)就不用我說了吧)。說白話點,就是我們可以傳入多個API常量,并且可以在API瀏覽器中找到,當(dāng)然,不一定所有的API常數(shù)都可以在API瀏覽器中找到,不過大部分都可以。

 
    在API瀏覽器查API常量時我前面就教過大家技巧,現(xiàn)在該是我們實踐的時候了,分析如下:

 
  Exit  :頭一個大寫字符 E
  Windows:頭一個大寫字符 W
  Ex    :頭一個大寫字符 E
  組合  :EWE_
 

    好了,現(xiàn)在在API瀏覽器的中常數(shù)中找找,咦?發(fā)現(xiàn)好像沒有以EWE開頭的常數(shù)??只發(fā)現(xiàn)以EWX開頭的?現(xiàn)在先別著急,咱們回過頭來再分析下,咱們是失敗在最后一步Ex上,這里我不得不否決我前面教過大家的技巧,但是又不能完全否決,出現(xiàn)這種情況時就需要大家靈活運用API常數(shù)的分析法,可以看到EWX最后一個X是以Ex的X作結(jié)尾的,以這種方法做API常數(shù)開頭的不止這一個,所以這里我特意留了一個陷阱,希望給大家?guī)硪恍┙?jīng)驗將來能夠靈活運用?,F(xiàn)在我把關(guān)機(jī)uFlags所能用到的相關(guān)常數(shù)發(fā)上來,如下:

 
  Private Const EWX_FORCE = 4
  Private Const EWX_LOGOFF = 0
  Private Const EWX_REBOOT = 2
  Private Const EWX_SHUTDOWN = 1

    怎么樣?看得懂吧?英語稍微好一點基本上沒問題。不過這里我還是要解釋一番,照顧新手嘛!

 
    EWX_FORCE 前面的 EWX_ 我就不說了,關(guān)鍵是看 _ 符號后面的,Force 單詞翻譯:強(qiáng)制,強(qiáng)迫。人工在翻譯一下(我英文不好,翻譯錯了請別見怪,呵呵 ^_^ ),意思是說:強(qiáng)制執(zhí)行ExitWindowsEx API關(guān)機(jī)函數(shù)。不知道這樣解釋你能不能明白。那到底這個常數(shù)有什么用呢?這里我們先回憶一下以前關(guān)機(jī)的時候,當(dāng)Windows無法關(guān)閉某些窗口的時候就停止繼續(xù)關(guān)機(jī)了,最后還得把無法關(guān)閉的窗口手動關(guān)閉方可,現(xiàn)在,如果我們使用這個常數(shù)進(jìn)行關(guān)機(jī),那Windows不管你窗口能不能關(guān)閉,直接強(qiáng)制關(guān)閉。希望你懂了。
 
  EWX_LOGOFF 這個嘛,貌似組合單詞,不可直接翻譯,那樣就不是那個意思了。Logout Off,是這樣寫嗎?注銷的意思。
 
  EWX_REBOOT 不浪費時間了,直接說明意思:重新啟動。
 
  EWX_SHUTDOWN 關(guān)機(jī)。

   
    至于第二個ByVal dwReserved As Long,為保留整形,一般為0即可。至于為什么為0,大家可以到網(wǎng)上下載一些專門講解API函數(shù)的電子書看看,里面有大部分API函數(shù)的詳細(xì)講解?;蛘呦螺dVS.MSDN看看,在MSDN中說Windows 2000/95/98/Me中此參數(shù)忽略,XP中是指定關(guān)機(jī)消息說明。

 
    最后看看這個API為Function聲明,說明該函數(shù)有返回值,返回值為Long,MSDN中說:如果執(zhí)行成功,則返回非零,否則為零。

 
    現(xiàn)在上面已經(jīng)把這個關(guān)機(jī)API和相關(guān)參數(shù)常量都給你分析透了,你可別告訴我你還不知道怎么寫?好了,這里我們做一個定時注銷程序,呵呵,雖然很簡單,不過很多時候用得上哦!在Form窗口上添加Timer控件,Interval 設(shè)置為1000,Enabled 設(shè)置為 True。好了,代碼如下:

 
  Private Declare Function ExitWindowsEx Lib "user32" (ByVal uFlags As Long, ByVal dwReserved As Long) As Long
  Private Const EWX_LOGOFF = 0
  Private Sub Timer1_Timer()
      Static i As Integer
   
      i = i + 1
   
      Me.Caption = i '這一步純粹是想看看當(dāng)前已經(jīng)執(zhí)行到幾秒了?可不要
   
      If i = 10 Then '秒數(shù)判斷,可以根據(jù)自己的需要進(jìn)行運算
          ExitWindowsEx EWX_LOGOFF, 0
      End If
  End Sub

 
    其實我都有點不想分析了,不過為了照顧大眾,不得不說下,Static i As Integer 靜態(tài)變量(問:啥叫靜態(tài)變量?答:我暈!),i = i + 1是每執(zhí)行Timer一次i就加1,Timer的interval設(shè)置為1000,1000為一秒,2000為二秒。。。。后面一個If i = 10 Then是判斷當(dāng)i=10以后,也就是10秒,就執(zhí)行注銷,這個時候你可別忘了保存好你的其它沒有保存的文件哦,如果沒保存資料丟失的話偶不承擔(dān)任何法律責(zé)任的。其實這里我們可以自己做一個,如可以寫成這樣:ExitWindowsEx EWX_LOGOFF Or EWX_FORCE, 0,其中用了Or運算,整體的意思是強(qiáng)制Windows注銷。這樣理解就夠了,只要能讓你明白。

 
    現(xiàn)在我又要說一下了,不說不行的!就是在API中使用 Or 運算,關(guān)于Or運算符VB書中都有詳細(xì)解釋的,別告訴我你沒看?沒看馬上去看!上面EWX_LOGOFF Or EWX_FORCE 的使用是把 注銷 和 強(qiáng)制 進(jìn)行Or位運算,對兩個數(shù)值執(zhí)行按位析取,這里涉及到二進(jìn)制運算,說多了你可能不明白(如果你還是想追根到底的想知道到底是怎么一回事的話,我也沒辦法,給個網(wǎng)址你慢慢看http://book.csdn.net/bookfiles/110/1001103366.shtml),我就說簡單點的吧,以后如果你想組合兩個API常數(shù)的功能,一般都是用 Or 進(jìn)行運行的。如上面寫的。

 
    好了,保存其它文件,然后F5運行之,看著Form標(biāo)題的數(shù)字慢慢添加,當(dāng)為10時,Windows開始注銷。。。

 
    小提示:在使用EWX_SHUTDOWN的時候你可能會感覺沒有作用,主要是NT系統(tǒng)的安全性提高,需要用其它API進(jìn)行提升自己的權(quán)限才可以。關(guān)于如何提升應(yīng)用程序權(quán)限請百度一下。

 
    2,先從一些最簡單的API開始

 
    無疑自己試著寫程序是最好的提升方法,學(xué)完一些知識以后自己試著寫寫,這樣能讓你理解的更快更好,好了不說廢話了,接著往下看。

 
    最簡單的API,呵呵,哪些最簡單呢?這個我也說不好,這樣吧,咱們就從Get(獲取)開始,那Get什么呢?Window(窗口),還是從窗口下手吧,這樣更接近我們?nèi)粘5木幊?,誰叫這是一個Windows操作系統(tǒng)呢?先列幾個常用的API:

 
  GetWindow、GetWindowDC、GetWindowLong、GetWindowRect、GetWindowRgn、GetWindowsDirectory、GetWindowText、GetWindowThreadProcessId
 

    還有很多,我就先列舉幾個簡單點的,咱們就從這幾個中間隨便抽幾個來講講吧。

 
    先從GetWindowText下手,大家就表面的意思進(jìn)行理解下,Get(獲取)Window(窗口)Text(文本),Very Good!這個API以前不錯的,可以獲取密碼框中的密碼,呵呵,說到這里,我估計有些人開始興奮起來了!那好,F(xiàn)ollow Me!

 
    新建一個Form窗口,然后添加一個CommandButton,Caption設(shè)置為:顯示密碼。接著添加兩個TextBox,Text1屬性設(shè)置:PasswordChar=*;Text=123456789,Text2的屬性基本上沒有什么需要設(shè)置的,只需要把Text屬性為空就可以了,它主要是用來幫助咱們顯示出密碼的。好了,在Form1代碼框中填入以下代碼:

 
  Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
  Private Sub Command1_Click()
      Dim sBuffer As String
   
      sBuffer = Space(255)
      GetWindowText Text1.hwnd, sBuffer, 255
   
      Text2.Text = sBuffer
  End Sub

 
    OK,F(xiàn)5運行,點擊Command1,怎么樣?Text1中的密碼字符顯示在Text2中了吧?你可以再更改下Text1中的密碼,然后再點擊Command1試試。也許你覺得會多此一舉,為何不Text2.Text=Text1.Text這樣?如果真的這樣的話看似簡單,那你就學(xué)不到API了。

 
    又到了開始分析的時候了,打起精神來,先看第一句:Dim sBuffer As String,不用說,聲明一個字符串變量唄!接著看第二句:sBuffer = Space(255) 那這一句呢?有些人可能不知道了,沒事,我會仔細(xì)講的。Space是VB內(nèi)置的字符串處理函數(shù),VB中的幫助文件中有說明:
 
 
  開始{
 
  本示例使用 Space 函數(shù)來生成一個字符串,字符串的內(nèi)容為空格,長度為指定的長度。
  Dim MyString
  ' 返回 10 個空格的字符串。
  MyString = Space(10)
  ' 將 10 個空格插入兩個字符串中間。
  MyString = "Hello" & Space(10) & "World"
 
  }結(jié)束

很顯然,我這一句是要分配255個空格字符串內(nèi)存,為啥要用分配?這都是為后面所要用到打定的基礎(chǔ)。接著往下:

 
    GetWindowText Text1.hwnd, sBuffer, 255 這一步是關(guān)鍵,通過它來獲取咱們想要的窗口文本,看第一個參數(shù),我前面講過hwnd一般都是需要傳入句柄的,這時咱們傳入了Text1.hwnd(Text1控件的句柄),第二個參數(shù),lpSting為字符串變量,所以這里咱們傳入sBuffer字符串變量。最后一個cch為Long整形,所以理應(yīng)傳入數(shù)字,這里我們傳入了255?,F(xiàn)在又有人想問了,為什么需要這么傳入值?貌似和以前的傳入不一樣?確實!一剛開始你可能搞不懂,這時候我先講講大概的意思,我們用GetWindowText來獲取窗口中的文本,當(dāng)獲取成功以后,理所當(dāng)然會返回窗口中的字符串,但是當(dāng)我們用這個API進(jìn)行獲取時,必須需要一個緩沖來保存我們所獲取的字符串,你如果不信去試試把sBuffer = Space(255)去掉,后面的255其實就是告訴這個API我們緩沖字符串的大小,這里再告訴大家一個技巧,以后只要是看見包函有cch字符時,大部分都是輸入相關(guān)類型的大小。
 

    再附加一點,就里我說過,hwnd是用來傳句柄的,你也可以傳入其它窗口句柄,只要其它窗口有文本,都是可以通過這個API獲取的。還有Text2.Text = sBuffer其實是可以先把sBuffer處理一下再傳給Text2.Text的,關(guān)于字符串處理這里不講。

 
    好了,分析結(jié)束,來個小提示:在Windows操作系統(tǒng)中,任何有句柄的東東都可被看作為一個窗口。另外你可能會去試試QQ的密碼框,^_^ 這里我要告訴你一下,無法成功,為什么無法成功呢?這是一個技術(shù)問題目前不提!

 
    接著再來試試GetWindowsDirectory,大家看表面意思吧!Get(獲取)Windows(就是Windows目錄)Directory(目錄),也就是獲取咱們那個系統(tǒng)目錄,如:C:/Windows。可能我的Windows目錄中在C盤,而其它人的可能在D盤、E盤也說不定,所以有的時候軟件需要這個API進(jìn)行獲取操作系統(tǒng)具體的Windows目錄。

 
    好了,還是新建一個標(biāo)準(zhǔn)EXE,添加一個CommandButton,屬性Caption=顯示W(wǎng)indows目錄,OK,寫入以下代碼:

 
  Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
  Private Sub Command1_Click()
      Dim sBuffer As String
   
      sBuffer = Space(255)
      GetWindowsDirectory sBuffer, 255
      MsgBox "Windows目錄在: " & sBuffer
  End Sub
 

    分析!第一個Dim sBuffer As String字符串變量,sBuffer = Space(255)緩沖字符串,GetWindowsDirectory sBuffer, 255這個和上面所講的一樣,最后一個參數(shù)nSize為Long整形,所以傳入數(shù)值,那傳入什么數(shù)值呢?Size???當(dāng)然是緩沖字符串大小了,以后遇到這個nSize一般也是傳入相關(guān)類型的大小的。MsgBox "Windows目錄在: " & sBuffer,是用MsgBox消息框顯示出Windows目錄的位置。

 
    OK,恭喜你,你又會使用了一個API,還要繼續(xù)嗎?(問:當(dāng)然還要啦!答:最后一次哦!)

 
    GetWindowThreadProcessId,這次玩玩窗口進(jìn)程,我估計有些人只要看見與進(jìn)程有關(guān)的東東也會變得興奮,呵呵!好了,先看看這個API是什么樣的?如下:

 
  Private Declare Function GetWindowThreadProcessId Lib "user32" Alias "GetWindowThreadProcessId" (ByVal hwnd As Long, lpdwProcessId As Long) As Long

 
    看表面意思:Get(獲取)Window(窗口)Thread(線程)Process(程序)Id(ID),組合:獲取當(dāng)前線程的窗口進(jìn)程ID。至于進(jìn)程ID要著有什么用,自己以后深入32編程就知道了。

    看看參數(shù),ByVal hwnd As Long,哈哈,熟悉吧,一個hWnd句柄。lpdwProcessId As Long這個就是咱們需要的進(jìn)程ID,老規(guī)矩,新建標(biāo)準(zhǔn)EXE,添加一個CommandButton,屬性:Caption=獲取窗口進(jìn)程ID。代碼如下:

 
  Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
  Private Sub Command1_Click()
      Dim PID As Long
   
      GetWindowThreadProcessId Me.hwnd, PID
   
      MsgBox "窗口進(jìn)程的ID是:" & PID
  End Sub
 

    我已經(jīng)習(xí)慣了給大家分析了。首先看看第一個參數(shù),ByVal hwnd As Long,又是句柄來的(問:廢話!答:教會了你也別這樣啊),lpdwProcessId As Long,這個就要注意了,看看這個參數(shù)的傳遞方式,是以ByRef進(jìn)行傳遞的(問:呵呵,不懂什么意思?答:不懂?轉(zhuǎn)回去看過程函數(shù)這章),也就是說ByRef是以地址進(jìn)行傳遞的,過程中可以改變傳遞的參數(shù)值。明白了嗎?還不明白的話回去乖乖看書吧!現(xiàn)在明白了傳遞方式,也就是說我們聲明的PID是用來獲取窗口進(jìn)程ID的,厲害啊。

    F5,運行之,點擊Command1,PID出來了吧?沒出來我馬上從十樓跳下去。

 
    溫馨小提示^_^:hWnd可以傳入其它窗口句柄,同樣可以獲取其它窗口進(jìn)程ID。

 
    接下來我們再來看看Set(設(shè)置),Set什么呢?當(dāng)然還是Window(窗口)容易些,先列出幾個常用的API:

 
    SetWindowLong、SetWindowPos、SetWindowRgn、SetWindowText
 
接上面的。

    首先咱們先看SetWindowText,咱們在上面講過GetWindowText這個API,GetWindowText是用來獲取窗口文本的,而這個正好相反?,F(xiàn)在可以看看表面意思Set(設(shè)置)Window(窗口)Text(文本),好了這樣理解就夠了,我們已經(jīng)知道這個API是設(shè)置窗口文本的,接著咱們就到API瀏覽器中找找這個API,如下:

 
    Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

    接著咱們看里面所需要傳遞的參數(shù),一共有兩,第一個ByVal hwnd As Long我就不用說了,傳入句柄唄,第二個ByVal lpString As String,其中聲明的lpString是字符串變量,可想而知,這里需要傳入字符串,好了,開始實踐。新建一個標(biāo)準(zhǔn)EXE,然后添加一個TextBox控件,然后再添加一個CommandButton,寫入以下代碼:

 
    Private Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long

    Private Sub Command1_Click()
      SetWindowText Text1.hwnd, "這是咱們設(shè)置的文本"
    End Sub

 
    呵呵,這個看似比前面的更簡單,不過我還是要羅嗦一下,首先把Text1的句柄傳入第一個參數(shù),這樣API知道咱們需要操作哪個窗口,第二個是一個字符串變量,所以這里就是我們需要傳入的文本。好了,F(xiàn)5運行,點擊Command1,OK。
 

    再看SetWindowPos,可以說這個API可以看成設(shè)置窗口位置,但是最終的實現(xiàn)效果取決于咱們傳遞的參數(shù),好了,在API瀏覽器中找到這個API,如下:

 
    Private Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long

    呵!好家伙,這個API看起來有些復(fù)雜啊?不過別擔(dān)心,有我在嘛,我會幫你好好分析的,這里還請大家別光我一個人分析,必須把自己融入進(jìn)來,咱們一起分析這樣不更有趣?好了,廢話少說,先看第一個參數(shù):
 

  ByVal hwnd As Long  這里我就不講了,傳入窗口句柄
 

    ByVal hWndInsertAfter As Long 好了,看看這個!hwndInstrAfter,可以看到里面包函有hwnd字符,這時你可能會說我前面不是已經(jīng)說過嘛,只要看見包函有hwnd字符的都應(yīng)該傳入句柄嘛?呵呵,沒錯,你很聰明,記得我說的話呢!在這里夸一下你,別驕傲??!現(xiàn)在咱們好好分析一下這個地方應(yīng)該傳入哪些參數(shù)!打開MSDN,不好意思是英文,這里我就把翻譯過來的說明放上來,如下:

 
  hWndInsertAfter -  Long,窗口句柄。在窗口列表中,窗口hwnd會置于這個窗口句柄的后面。也可能選用下述值之一:

 
  HWND_BOTTOM    將窗口置于窗口列表底部

 
  HWND_TOP        將窗口置于Z序列的頂部;Z序列代表在分級結(jié)構(gòu)中,窗口針對一個給定級別的窗口顯示的順序

 
  HWND_TOPMOST    將窗口置于列表頂部,并位于任何最頂部窗口的前面

 
  HWND_NOTOPMOST  將窗口置于列表頂部,并位于任何最頂部窗口的后面

 
    可以看到這個地方有四個參數(shù)供我們選擇,一般我們會使用第三個API常數(shù)和第四個API常數(shù),這幾個API常數(shù)都可以在API瀏覽器中找到,至于具體實現(xiàn)什么功能我相信大家都知道吧,后面有寫呢!

 
    再看看后面的幾個 x,y,cx,cy 分別為Long變量,我上面講過,SetWindowPos可以看成設(shè)置窗口位置嘛,所以這里理所當(dāng)然是傳入相關(guān)的坐標(biāo)值,如果忽略則為0,自己可以試下。

 
    ByVal wFlags As Long,這個參數(shù),我又說過,看看字符Flags,呵呵,熟悉吧,所以這里咱們需要傳入相關(guān)的標(biāo)識常數(shù),利用咱們以前學(xué)過的常數(shù)分析法進(jìn)行分析,Set(S)Window(W)Pos(P)=SWP_ ,可以看到相關(guān)的常數(shù)了吧?這里我把相關(guān)常數(shù)的說明發(fā)上來大家看下,如下:

 
  SWP_DRAWFRAME    圍繞窗口畫一個框
 
  SWP_HIDEWINDOW  隱藏窗口
 
  SWP_NOACTIVATE  不激活窗口
 
  SWP_NOMOVE      保持當(dāng)前位置(x和y設(shè)定將被忽略)
 
  SWP_NOREDRAW    窗口不自動重畫
 
  SWP_NOSIZE      保持當(dāng)前大小(cx和cy會被忽略)
 
  SWP_NOZORDER    保持窗口在列表的當(dāng)前位置(hWndInsertAfter將被忽略)
 
  SWP_SHOWWINDOW  顯示窗口
 
  SWP_FRAMECHANGED 強(qiáng)迫一條WM_NCCALCSIZE消息進(jìn)入窗口,即使窗口的大小沒有改變

    所以我說過,一個這樣的API他具體實現(xiàn)的功能取決于你所傳遞的參數(shù)。假設(shè)這里咱們需要實現(xiàn)一個窗口永遠(yuǎn)置前的功能,首先新建一個標(biāo)準(zhǔn)EXE,輸入以下代碼:

 
    Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
 Private Const HWND_TOPMOST = -1
 Private Const SWP_NOMOVE = &H2
 Private Const SWP_NOSIZE = &H1
 Private Sub Form_Load()
     SetWindowPos Me.hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE Or SWP_NOSIZE
 End Sub

    現(xiàn)在咱們開始分析,第一個參數(shù)傳入句柄,第二個我上面講過,實現(xiàn)什么功能傳入什么參數(shù),這里咱們是實現(xiàn)的窗口永久置前的功能,所以傳入HWND_TOPMOST常數(shù),現(xiàn)在看看其實坐標(biāo),如果你不想改變窗口的具體位置的話,這里可不設(shè)為0,再看看后面的wFlags,我傳入了兩個常數(shù),這兩個常數(shù)的相關(guān)說明請大家看看上面就知道,主要是不改變窗口位置和不改變窗口大小的前提下把窗口置前,其它常數(shù)如果大家有興趣可以自己試試。

 
    最后一個,看看SetWindowRgn,這里我要解釋一番,這個API所實現(xiàn)的功能呢就是改變窗口外觀,也就是咱們所說的異形窗口等,通過這個API咱們可以把窗口改變成任何形狀,在API瀏覽器找到這個API,如下:

 
    Private Declare Function SetWindowRgn Lib "user32" Alias "SetWindowRgn" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long

    好了,第一個參數(shù),句柄。第二個參數(shù),Long變量,這里需要傳入什么咱們下面會講到。第三個,Boolean變量,可以說明這里需要傳入布爾值,Redraw為重畫的意思,所以如果我們用這個API改變窗口形狀,這里需要為True,表示重畫窗口。

 
    現(xiàn)在新建一個標(biāo)準(zhǔn)EXE,然后把Form的ScaleMode設(shè)置成3-Pixel,我們知道Windows是以像素為單位的,所以使用這個API進(jìn)行設(shè)置的時候是以像素為單位進(jìn)行處理窗口外觀。然后把BorderStyle設(shè)置為0-None,這樣看得更明顯。好了,寫入以下代碼:

 
  Private Declare Function SetWindowRgn Lib "user32" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bRedraw As Boolean) As Long
  Private Declare Function CreateRoundRectRgn Lib "gdi32" (ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long, ByVal X3 As Long, ByVal Y3 As Long) As Long
  Private Sub Form_Load()
      Dim hRgn As Long
   
      hRgn = CreateRoundRectRgn(0, 0, Me.ScaleWidth, Me.ScaleHeight, 10, 10)
      SetWindowRgn Me.hWnd, hRgn, True
  End Sub

    我不得不說一下這里我又用了一個API,主要是因為使用SetWindowRgn API是需要和其它API一起進(jìn)行工作的,首先讓我們先看看CreateRoundRectRgn這個API。分析如下:

 
    整體的意思是:創(chuàng)建圓角矩形。這里提示大家一個技巧,一般API中包函Rgn字符的都是代表可以改變對象外觀的??梢钥纯次覀兪褂玫膬蓚€API,一個是SetWindowRgn(Rgn),一個是CreateRoundRectRgn(Rgn),希望你能明白其中的共同點。

  參數(shù):x1,y1,x2,y2,x3,y3這些都是坐標(biāo)值,具體說明見以下:
 
  X1,Y1 ----------  Long,矩形左上角的X,Y坐標(biāo)
  X2,Y2 ----------  Long,矩形右下角的X,Y坐標(biāo)
  X3 -------------  Long,圓角橢圓的寬。其范圍從0(沒有圓角)到矩形寬(全圓)
  Y3 -------------  Long,圓角橢圓的高。其范圍從0(沒有圓角)到矩形高(全圓)

    所以上面的代碼具體是先通過CreateRoundRectRgn創(chuàng)建一個圓角矩形對象,然后通過SetWindowRgn來改變窗口的外觀。
 
    小提示:使用CreateRoundRectRgn可以創(chuàng)建圓角矩形,也可以使用CreateEllipticRgn創(chuàng)建橢圓形,CreatePolyPolygonRgn創(chuàng)建多邊形,CreateRectRgn矩形等,細(xì)心觀察它們最后三個字符 Rgn 呵呵,明白了吧。

3,獲取其它窗口的句柄
 
    這個我本來打算不講的,不過網(wǎng)友們既然提出來了,我也只好詳細(xì)說說。一般獲取其它窗口的句柄使用以下API:

 
  FindWindow,F(xiàn)indWindowEx,WindowFromPoint
 

    這兩個API就足矣,先看看第一個API的原型:

 
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

    里面一共有兩個參數(shù),先看第一個:ByVal lpClassName As String,字符串變量,所以這里需要傳入字符串,第二個ByVal lpWindowName As String,同樣一個字符串變量,這里也需要傳入字符串。再看這個API為Function,有返回值的,那返回值就是我們需要的句柄了。好了,現(xiàn)在了解了兩個參數(shù)的具體傳遞類型,那我們現(xiàn)在就要知道這兩個參數(shù)中到底應(yīng)該傳入哪些值?如下:

 
  ByVal lpClassName As String,lpClassName:類名。指窗口類名,如果忽略則傳入vbNullString。
 

  ByVal lpWindowName As String,lpWindowName:窗口名稱。指窗口文本,如果忽略則傳入vbNullString。

 
    現(xiàn)在明白了兩個參數(shù)需要傳入哪些值就好辦了,一個窗口的類名咱們有可能不知道,但是一個窗口的名稱就好辦了。如:咱們打開記事本程序,可以看到窗口標(biāo)題顯示為“無標(biāo)題-記事本”。好了這就是咱們需要的,現(xiàn)在咱們就要通過這個窗口標(biāo)題來獲取記事本的句柄。新建一個標(biāo)準(zhǔn)EXE,然后輸入以下代碼:

 
  Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  Private Sub Form_Load()
      Dim WindowHandle As Long
   
      WindowHandle = FindWindow(vbNullString, "無標(biāo)題 - 記事本")
       
      MsgBox WindowHandle
  End Sub
 

    好了,F(xiàn)5運行,顯示MsgBox消息框,如果不為0,那么咱們就獲取成功了,如果為0,那么表示獲取失敗,這個時候你有必要檢查一下你所要獲取的窗口文本是否符合你所要獲取的那個窗口文本(呵,這句話還真長!)。具體代碼意思我就不講了,大家可以自己分析下。

 
    小提示:這個時候咱們已經(jīng)得到句柄了,具體得到這個句柄干什么?那就看你了。給個例子,如下:

 
    SetWindowText WindowHandle, "哈哈"

 
    看看把這個代碼放在上面代碼中試下,呵呵!注意,SetWindowText你要先聲明這個API。別忘了。

 


    再看第二個FindWindowEx,這個API是在窗口列表中尋找與指定條件相符的第一個子窗口,原型如下:

 
    Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

    看里面的參數(shù),第一個和第二個:ByVal hWnd1 As Long,ByVal hWnd2 As Long,這里都需要傳入句柄,再看第三個和第四個:ByVal lpsz1 As String, ByVal lpsz2 As String,這里所要傳入的是字符串。具體意思如下:

  hWnd1 ----------  Long,在其中查找子的父窗口。如設(shè)為零,表示使用桌面窗口(通常說的頂級窗口都被認(rèn)為是桌面的子窗口,所以也會對它們進(jìn)行查找)

  hWnd2 ----------  Long,從這個窗口后開始查找。這樣便可利用對FindWindowEx的多次調(diào)用找到符合條件的所有子窗口。如設(shè)為零,表示從第一個子窗口開始搜索

  lpsz1 ----------  String,欲搜索的類名。零表示忽略,注意一般傳入vbNullString

  lpsz2 ----------  String,欲搜索的類名。零表示忽略,注意一般傳入vbNullString

    用實踐幫我們分析,這里還是拿記事本開刀。打開一個記事本,新建一個標(biāo)準(zhǔn)EXE,接著新建一個CommandButton,Caption設(shè)置為:設(shè)置文本。OK,寫入以下代碼:

 
  Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
  Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
  Private Declare Function EnableWindow Lib "user32" (ByVal hwnd As Long, ByVal fEnable As Long) As Long

  Private Sub Command1_Click()
      Dim WindowHandle As Long, ChildWindowHandle As Long
   
      WindowHandle = FindWindow(vbNullString, "無標(biāo)題 - 記事本")
       
      If WindowHandle Then '如果獲取句柄成功
               
          ChildWindowHandle = FindWindowEx(WindowHandle, 0, "Edit", vbNullString)
       
          If ChildWindowHandle Then '如果成功獲取子句柄
              EnableWindow ChildWindowHandle, False '禁用子窗口
          Else
              MsgBox "無法獲取子窗口"
          End If
      End If
  End Sub
 

    好了,幫大家分析??吹谝恍校篋im WindowHandle As Long, ChildWindowHandle As Long,用于儲存獲取的句柄的。WindowHandle = FindWindow(vbNullString, "無標(biāo)題 - 記事本")這個就不用講了,上面已經(jīng)講過。

 
    ChildWindowHandle = FindWindowEx(WindowHandle, 0, "Edit", vbNullString),這一段是通過我們已經(jīng)獲取的記事本句柄獲取其中的子窗口句柄。大家可以用Spy++查看到記事本的TextBox類,然后根據(jù)類名寫入即可。

 
    EnableWindow ChildWindowHandle, False 這又是一個新的API,雖然前面我沒有前過,但是這個API使用起來及其簡單。這個API中有兩個參數(shù),第一個理所當(dāng)然是傳入窗口句柄,第二個為Long變量,其實這里應(yīng)該設(shè)為Boolean變量好些,主要是用來處理當(dāng)前窗口是否可用。True可用,F(xiàn)alse禁用。

 
    現(xiàn)在F5運行,記得打開記事本哦,然后點擊Command1,看看能不能在記事本的文本框中輸入字符串?是否被禁用了?

 
    小提示:EnableWindow之所有講出來,是希望提高大家使用API的興趣,有些被禁用的窗口你可以使用這個API把它激活,至于怎么使用就看你自己了,這里給大家布置一個作業(yè),呵呵,自己去完成吧。

 

 
    最后一個API,WindowFromPoint,這個API主要是獲取當(dāng)前坐標(biāo)的窗口句柄,不是有人想知道當(dāng)前鼠標(biāo)指針位置的窗口句柄嗎?用這個是不錯的選擇,原型如下:
 

  Private Declare Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" (ByVal xPoint As Long, ByVal yPoint As Long) As Long

    兩個參數(shù),一個是xPoint(x坐標(biāo)值),一個是yPoint(y坐標(biāo)值),現(xiàn)在你可以在這個兩個參數(shù)分別傳入其它窗口的坐標(biāo)值就可以獲取其它窗口的句柄了??梢钥吹綖镕unction聲明,返回值就是咱們需要的句柄。

 
    咱們想實現(xiàn)的功能是獲取當(dāng)前鼠標(biāo)指針位置的句柄,所以這里當(dāng)然需要用到GetCursorPos了,結(jié)合前面所講的,新建一個標(biāo)準(zhǔn)EXE,添加一個Timer控件,Interval設(shè)置為100,Enabled=True,OK,寫如以下代碼:

 
  Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
  Private Type POINTAPI
          x As Long
          y As Long
  End Type
  Private Sub Timer1_Timer()
      Dim lpPoint As POINTAPI
      Dim WindowHandle As Long
   
      GetCursorPos lpPoint '獲取當(dāng)前鼠標(biāo)指針坐標(biāo)
      WindowHandle = WindowFromPoint(lpPoint.x, lpPoint.y)
   
      Me.Caption = "當(dāng)前鼠標(biāo)指針位置句柄:" & WindowHandle
  End Sub

 
    好了,最后一次給大家分析了,至于GetCursorPos的使用與說明前面已經(jīng)講過,這里不再分析??纯碬indowHandle = WindowFromPoint(lpPoint.x, lpPoint.y)這句,它是通過GetCursorPos獲取的鼠標(biāo)坐標(biāo)值獲取當(dāng)前鼠標(biāo)坐標(biāo)位置的句柄。最后一句我就不用說了,在程序窗口顯示獲取的句柄。


 
 
    好了,API入門已經(jīng)告一段落,希望大家能從上面學(xué)到一些知識。具體的API應(yīng)用我就不多說,大家可以自己慢慢體會。如果你把以上全部都搞懂的話,那么證明你已經(jīng)基本了解API的使用方法了,那下面就靠你自己了。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多