2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

VB中的API詳解

 云中凌 2015-04-18

一、API是什么?

  這個(gè)我本來(lái)不想說(shuō)的,不過(guò)也許你知道其它人不知道,這里為了照顧一下新手,不得不說(shuō)些廢話(huà),請(qǐng)大家諒解。

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

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

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

二、如何使用API?

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

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

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

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

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

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

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

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

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

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

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

  1,自己做MsgBox

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

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

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

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

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

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

  2,來(lái)點(diǎn)實(shí)用的吧

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

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

  又到了分析的時(shí)候了,這對(duì)剛?cè)腴T(mén)的新手可謂是最激動(dòng)的時(shí)候了。好了,還是老子,看看兩個(gè)API的表面意思和傳遞值變量。

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

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

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

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

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

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

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

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

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

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

Private Type POINTAPI
        x As Long
        y As Long
End Type

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

    Interval = 100
    Enabled  = True

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

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

    好了,分析開(kāi)始,緊張不?別緊張,沒(méi)啥值得緊張的!見(jiàn)以下:

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

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

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

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

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

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

1,試著自己從小程序開(kāi)始寫(xiě)起。

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

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

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

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

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

 
  Exit  :頭一個(gè)大寫(xiě)字符 E
  Windows:頭一個(gè)大寫(xiě)字符 W
  Ex    :頭一個(gè)大寫(xiě)字符 E
  組合  :EWE_
 

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

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

    怎么樣?看得懂吧?英語(yǔ)稍微好一點(diǎn)基本上沒(méi)問(wèn)題。不過(guò)這里我還是要解釋一番,照顧新手嘛!

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

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

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

 
    現(xiàn)在上面已經(jīng)把這個(gè)關(guān)機(jī)API和相關(guān)參數(shù)常量都給你分析透了,你可別告訴我你還不知道怎么寫(xiě)?好了,這里我們做一個(gè)定時(shí)注銷(xiāo)程序,呵呵,雖然很簡(jiǎn)單,不過(guò)很多時(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)行運(yùn)算
          ExitWindowsEx EWX_LOGOFF, 0
      End If
  End Sub

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

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

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

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

 
    2,先從一些最簡(jiǎn)單的API開(kāi)始

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

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

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

    還有很多,我就先列舉幾個(gè)簡(jiǎn)單點(diǎn)的,咱們就從這幾個(gè)中間隨便抽幾個(gè)來(lái)講講吧。

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

 
    新建一個(gè)Form窗口,然后添加一個(gè)CommandButton,Caption設(shè)置為:顯示密碼。接著添加兩個(gè)TextBox,Text1屬性設(shè)置:PasswordChar=*;Text=123456789,Text2的屬性基本上沒(méi)有什么需要設(shè)置的,只需要把Text屬性為空就可以了,它主要是用來(lái)幫助咱們顯示出密碼的。好了,在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運(yùn)行,點(diǎn)擊Command1,怎么樣?Text1中的密碼字符顯示在Text2中了吧?你可以再更改下Text1中的密碼,然后再點(diǎn)擊Command1試試。也許你覺(jué)得會(huì)多此一舉,為何不Text2.Text=Text1.Text這樣?如果真的這樣的話(huà)看似簡(jiǎn)單,那你就學(xué)不到API了。

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

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

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

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

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

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

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

 
  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
 

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

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

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

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

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

    看看參數(shù),ByVal hwnd As Long,哈哈,熟悉吧,一個(gè)hWnd句柄。lpdwProcessId As Long這個(gè)就是咱們需要的進(jìn)程ID,老規(guī)矩,新建標(biāo)準(zhǔn)EXE,添加一個(gè)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í)慣了給大家分析了。首先看看第一個(gè)參數(shù),ByVal hwnd As Long,又是句柄來(lái)的(問(wèn):廢話(huà)!答:教會(huì)了你也別這樣啊),lpdwProcessId As Long,這個(gè)就要注意了,看看這個(gè)參數(shù)的傳遞方式,是以ByRef進(jìn)行傳遞的(問(wèn):呵呵,不懂什么意思?答:不懂?轉(zhuǎn)回去看過(guò)程函數(shù)這章),也就是說(shuō)ByRef是以地址進(jìn)行傳遞的,過(guò)程中可以改變傳遞的參數(shù)值。明白了嗎?還不明白的話(huà)回去乖乖看書(shū)吧!現(xiàn)在明白了傳遞方式,也就是說(shuō)我們聲明的PID是用來(lái)獲取窗口進(jìn)程ID的,厲害啊。

    F5,運(yùn)行之,點(diǎn)擊Command1,PID出來(lái)了吧?沒(méi)出來(lái)我馬上從十樓跳下去。

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

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

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

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

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

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

 
    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, "這是咱們?cè)O(shè)置的文本"
    End Sub

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

    再看SetWindowPos,可以說(shuō)這個(gè)API可以看成設(shè)置窗口位置,但是最終的實(shí)現(xiàn)效果取決于咱們傳遞的參數(shù),好了,在A(yíng)PI瀏覽器中找到這個(gè)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

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

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

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

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

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

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

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

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

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

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

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

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

    所以我說(shuō)過(guò),一個(gè)這樣的API他具體實(shí)現(xiàn)的功能取決于你所傳遞的參數(shù)。假設(shè)這里咱們需要實(shí)現(xiàn)一個(gè)窗口永遠(yuǎn)置前的功能,首先新建一個(gè)標(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)在咱們開(kāi)始分析,第一個(gè)參數(shù)傳入句柄,第二個(gè)我上面講過(guò),實(shí)現(xiàn)什么功能傳入什么參數(shù),這里咱們是實(shí)現(xiàn)的窗口永久置前的功能,所以傳入HWND_TOPMOST常數(shù),現(xiàn)在看看其實(shí)坐標(biāo),如果你不想改變窗口的具體位置的話(huà),這里可不設(shè)為0,再看看后面的wFlags,我傳入了兩個(gè)常數(shù),這兩個(gè)常數(shù)的相關(guān)說(shuō)明請(qǐng)大家看看上面就知道,主要是不改變窗口位置和不改變窗口大小的前提下把窗口置前,其它常數(shù)如果大家有興趣可以自己試試。

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

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

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

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

 
  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

    我不得不說(shuō)一下這里我又用了一個(gè)API,主要是因?yàn)槭褂肧etWindowRgn API是需要和其它API一起進(jìn)行工作的,首先讓我們先看看CreateRoundRectRgn這個(gè)API。分析如下:

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

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

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

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

 
  FindWindow,F(xiàn)indWindowEx,WindowFromPoint
 

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

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

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

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

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

 
    現(xiàn)在明白了兩個(gè)參數(shù)需要傳入哪些值就好辦了,一個(gè)窗口的類(lèi)名咱們有可能不知道,但是一個(gè)窗口的名稱(chēng)就好辦了。如:咱們打開(kāi)記事本程序,可以看到窗口標(biāo)題顯示為“無(wú)標(biāo)題-記事本”。好了這就是咱們需要的,現(xiàn)在咱們就要通過(guò)這個(gè)窗口標(biāo)題來(lái)獲取記事本的句柄。新建一個(gè)標(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, "無(wú)標(biāo)題 - 記事本")
       
      MsgBox WindowHandle
  End Sub
 

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

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

 
    SetWindowText WindowHandle, "哈哈"

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

 


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

 
    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ù),第一個(gè)和第二個(gè):ByVal hWnd1 As Long,ByVal hWnd2 As Long,這里都需要傳入句柄,再看第三個(gè)和第四個(gè):ByVal lpsz1 As String, ByVal lpsz2 As String,這里所要傳入的是字符串。具體意思如下:

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

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

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

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

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

 
  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, "無(wú)標(biāo)題 - 記事本")
       
      If WindowHandle Then '如果獲取句柄成功
               
          ChildWindowHandle = FindWindowEx(WindowHandle, 0, "Edit", vbNullString)
       
          If ChildWindowHandle Then '如果成功獲取子句柄
              EnableWindow ChildWindowHandle, False '禁用子窗口
          Else
              MsgBox "無(wú)法獲取子窗口"
          End If
      End If
  End Sub
 

    好了,幫大家分析。看第一行:Dim WindowHandle As Long, ChildWindowHandle As Long,用于儲(chǔ)存獲取的句柄的。WindowHandle = FindWindow(vbNullString, "無(wú)標(biāo)題 - 記事本")這個(gè)就不用講了,上面已經(jīng)講過(guò)。

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

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

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

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

 

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

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

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

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

 
  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的使用與說(shuō)明前面已經(jīng)講過(guò),這里不再分析??纯碬indowHandle = WindowFromPoint(lpPoint.x, lpPoint.y)這句,它是通過(guò)GetCursorPos獲取的鼠標(biāo)坐標(biāo)值獲取當(dāng)前鼠標(biāo)坐標(biāo)位置的句柄。最后一句我就不用說(shuō)了,在程序窗口顯示獲取的句柄。


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

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多