亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 22.txt

?? VB文章集(含API、窗口、數據庫、多媒體、系統、文件、等等)
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
WIN32 API
一、VB5.0與Windows API 間的呼叫技巧 

一、VB5.0與Windows API 間的呼叫技巧

一般會使用WINDOW API的情況,實在是因為VB本身不提供某些功能,但是,程式所需又
不得不然,例如:讀取Registry內的資料,VB只提供SaveSetting、Getsetting 等系列
的指令,但是它只能讀取特定地區的值,要讀、刪、更動其他區域的值時,就無法使用
。再如:仔細看一看Combo Box的Events,其中沒有MouseMove,但這是我們經常用上的
一個Event,那該如何呢?是的,那只有透過Winodow API。而VB呼叫Window API一般不
都使用API檢視員,直接將相對應的API COPY到我們的程式中就好,那還用什麼技巧嗎?
其實不然,因為VB資料格式的問題,又加上VB本身沒有指標,在許多地方需要一些小技
巧才能解決,而且我們經常因應不同的需求,將API 檢視員的宣告COPY過來後再做一些
修改,最重要的,如果有一個.DLL檔,它不在API 檢視員中定義,那時,就只有自己想
辦法啦。
一、 整數叁數

Windows API32位元VB 
Int, INT ByVal Long 
UNIT, DWORD ByVal Long 
BOOL ByVal Long ture時為1 
WPARAM, LPARAM, LRESULT ByVal Long 
Handle(如HKEY) ByVal Long 
WORD, ATOM, SHORT ByVal Integer 
BYTE, CHAR ByVal Byte 

Windows API 宣告
SHORT GetKeyState( int nVirtKey )
對應的VB宣告
Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
-----------------------------------------------------------------------------
這個API 可用來檢視某些KEY (如Insert鍵、Num Lock、CapsLock等)是on/off。程式如
下:這個例子應該可十分楚的看到各個整數間的宣告對應。
----------------------------------------------------------------------------- 
Dim InsertMode as Integer
InsertMode = GetKeyState(vbKeyInsert) And vbShiftMask
If InsertMode = 1 then
Debug.print "表示 Insert Mode"
Else
Debug.print "表示 OverWrite Mode"
End If


----------------------------------------------------------------------------- 
二、 指向整數的指標
Windows API 32位元VB 
LPINT (ByRef ) Long 
LPUNIT (ByRef ) Long 
LPBOOL (ByRef ) Long 
LPDWORD (ByRef ) Long 
LPHANDLE (如:PHKEY) (ByRef ) Long 
LPWORD (ByRef ) Integer 
LPSHORT (ByRef ) Integer 
LPBYTE (ByRef ) Byte 

VB內定是使用傳址呼叫,所以ByRef 可以省略,也就是說
Func(ByRef param1 as type)
Func(param1 as type)
是相同的,使用傳址呼叫的方式,不外??想將叁數傳給API 後將結果傳回來。然而LONG
型態的傳址呼叫在VB中又占了相當大的份量,因為32位元的指標都是LONG的型態,而字
串、自定型態的Structure在Windows API中是以指標來傳遞的,而指標的傳遞事實上也
是Long值的傳遞,只不過傳過去的LONG值,於WIN API中會將之當成Address,而再配合
指標運作而得指標所指的內容,這個觀念在後面會很重要。 
例如: ----------------------------------------------------------------------------- 
LONG RegOpenKeyEx(
HKEY hKey, // handle of open key
LPCTSTR lpszSubKey, // address of name of subkey to open
DWORD dwReserved, // reserved
REGSAM samDesired, // security access mask
PHKEY phkResult // address of handle of open key
);
相對應的VB 宣告
Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
(ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
phkResult As Long) As Long '//最後一個叁數是ByRef之宣告
-----------------------------------------------------------------------------
我們經常會想要用程式來讀取Registry中的資料,例如:我們想得知Win95的Produ ct
ID該如何做呢?這里有幾個觀念要先清楚:首先:ProductId在何處呢?在
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVerson下的ProductId。
我們要取得的便是
KEY 為 HKEY_LOCAL_MACHINE
SUBKEY 為 SOFTWARE\Microsoft\Windows\CurrentVerson
ValueName 為 ProductId 的value
然而要取得ProductId的value可沒那麼直接,要先取得SubKey的KeyHandle而Key Handle
的取得便是利用RegQueryKeyEx的API 。程式部份在介紹Win API字串傳遞時再一并介紹。
三、 字串叁數
凡是所有字串叁數指標都以 ByVal 叁數名稱 As String 傳。如RegOpenKeyEx()的第二叁
數ByVal lpSubKey As String,便是一例。或許會問,這個例子是把subkey值傳給 Win 
API所以用ByVal,沒什麼大不了,其實不然,要Win API傳回字串時,也一定要用ByVal
的宣告。這是VB5字串格式(BSTR)與WIN API標準字串格式(LPSTR)不同的因素。 LPSTR 
字串格式是NULL Terminate的字串,若有一字串"HaHa !OK!",則格式如下:
----------------------------------------------------------------------------- 
Address 0 1 2 3 4 5 6 7 8 9
-- -- -- -- -- -- -- -- -- --
內容 H a H a ! O K ! \0
而BSTR則在字串的前面還有一個LONG值存字串長度,格式如下:
Address 0.. 3 4 5 6 7 8 9 10 11 12 13
------ -- -- -- -- -- -- -- -- -- --
內容 9 H a H a ! O K ! \0
-----------------------------------------------------------------------------
所以了字串以ByVal的方式來傳像不像指到BSTR中第4個位置,如此一來,不就和LP STR 
可以相容了嗎?我想也正因為如此以ByVal的方式來傳String可以取得Win API的傳回值,
(就算不是如此,至少這麼想比較記得住String要用ByVal的方式傳)。現在又有一個問題,
Window95 API的字串使用的是ASCII Code但VB是用Unicode,Unicode占兩個位元組,那麼
能和WinAPI的字串相?所幸我們可以先不用管它,因為vb本身做了轉換,即 vb傳給api時,
轉了一次,傳回時又轉回 Unicode,所以如果我們用的是Byte Array來傳字串,也可以但
是要自己去轉碼。。然而32位元的VB 中,字串有種格式,一個是BSTR,另一個是HLSTR
,如果我們宣告的串是非固定長度者,就會是BSTR,反之則為HLSTR。
DIM BSTR5 AS STRING 劤 BSTR
DIM HLSTR5 AS STRING(255) 劤 HLSTR
VB5中WIN32 API的呼叫請多多使用BSTR,因為使用HLSTR的結果是,VB還得做HLSTR ->
BSTR的轉換來呼叫WIN API若有傳回STRING而後再做BSTR->HLSTR的工作。然而使用 
BSTR來工作時,若處理有傳回值的STRING叁數,則還要有額外的動作:
1.先給定字串的初值,且字串的長度要夠放傳回值。
2.傳回後,去除傳回值中多馀的字元。
例如:
----------------------------------------------------------------------------- 
int GetWindowText(
HWND hWnd, // handle of window or control with text
LPTSTR lpString, // address of buffer for text
int nMaxCount // maximum number of characters to copy
);
該 API 取得WINDOW Title Bar的文字,而傳回值是放入lpString的character個數。
VB的宣告如下:
Decl are Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
范例一
***************************************************************************** 
Dim CharCnt As Long
Dim lpString As String
Dim tmpstr As String
Dim NullPos As Long
Form1.Caption = "這是一個test"
lpString = String(255, 0) '設定初值
CharCnt = GetWindowText(Me.hwnd, lpString, 256) 'CharCnt = 12
tmpstr = Left(lpString, CharCnt) '如此做會有一些問題
Debug.Print Len(tmpstr) '得12
Label1.Caption = Left(lpString, CharCnt)
Debug.Print Len(Label1.Caption) '得8
***************************************************************************** 
以范例一的例子來看,設定lpString= String(255,0)的目的,是設定255個字元的空間
給lpString(加上最後的null一共256),CharCnt的值是12,明眼者可看到len("這是一個
test") 會是8,但CharCnt是12, 所以直接使用Left()函數來取得子字串會有問題,這
是UniCode與ANSI String間的關系,所以了,當您看到有些書的范例用這種方法取子字
串,是不太完善的,所以改用范例二的方式,比較正確。
范例二
***************************************************************************** 
Form1.Caption = "這是一個test"
lpString = String(255, 0) '設定初值
CharCnt = GetWindowText(Me.hwnd, lpString, 256) 'CharCnt = 12
NullPos = InStr(1, lpString, Chr(0), vbBinaryCompare)
tmpstr = Left(lpString, NullPos - 1)
lable1.Caption = tmpstr
***************************************************************************** 
四、 Null 值的傳遞
我們再回到求ProductId的問題,我們已知使用RegOpenKeyEx()來取得subkey的Han dle
值,緊接著便是用RegQueryValueEx()來取值。
----------------------------------------------------------------------------- 
LONG RegQueryValueEx(
HKEY hKey, // handle of key to query
LPTSTR lpszValueName, // address of name of value to query
LPDWORD lpdwReserved, // reserved
LPDWORD lpdwType, // address of buffer for value type
LPBYTE lpbData, // address of data buffer
LPDWORD lpcbData // address of data buffer size
);
VB的宣告(由API檢視員中Copy下來者)
Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" _
(ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
lpType As Long, _
lpData As Any, _
lpcbData As Long) As Long
----------------------------------------------------------------------------- 
仔細看一下第三個叁數,WIN API中是LPDWORD可是VB中麼會是用ByVal的方式傳遞呢?原
因在於 lpReserved一定要傳Null進去,VB在呼叫時便在 這叁數的位置上填0(見范例三)。
為何傳Null就得這做?我們可以這麼想,我們 在程式中下指令,告訴VB要以 ByVal 的
方式傳0出去,而WIN API里,它可不管VB是ByVal或ByRef,API 認定我們傳進來的就是
它需要的,所以了,第三個叁數在API中認定我們傳進的是一個Address,而VB 傳0進去,
那代表API若去取得它的內容,便會取得Address 0 的內容,或許Window的 Null值便是
指向Address 0呢!另一個作法比較直接,將VB宣告的第三個叁數宣告由 ByVal 
lpReserved As Long改成 ByVal lpReserved as String而使用時固定傳 vbNullString 
進去也可以。這里在一個觀念,那就是VB對Win API的宣告,純粹是給VB 自己看的,在
API中定義了一個指標的叁數,Api檢視員會將之宣告成ByRef的方式(字串除外),但我們
可隨需要而更動它,一個原始應為ByRef的叁數宣告,我們可以將之改為 ByVal的方式,
只要我們能取得叁數的位址,而將這型態為Long的位址以ByVal傳出去, Win API 端根
本不知道VB端是用什麼方式傳,反正只要我們傳了一Long值進去,Win API 就會以這個
Long值當作是Address來運作。
問題還沒有解決,RegQueryValueEx()的第四個叁數lpType若為REG_SZ(= 1)那代表 
lpData是Null Terminate的String,若為REG_DWORD ( = 4)那代表lpData是Long值,正
是因為沒有辦法事先知道lpData的真正型態,所以VB就使用 ASAny的型態,它要VB放棄
型態的檢查,傳什麼值進去都可以,但是在這里有一些問題,如果lpType是REG_DWORD 
那麼lpData以ByRef的方式沒有問題,但是如果lpType 是REG_SZ,STRING是要以ByVal 
的方式來宣告,所以會有沖突,而解決的方式就是改寫API檢視員Copy進來的宣告。
----------------------------------------------------------------------------- 
Declare Function RegQueryLong Lib "advapi32.dll" Alias "RegQueryValueExA" _
(ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
lpType As Long, _
lpData As Long, _
lpcbData As Long) As Long
Declare Function RegQueryString Lib "advapi32.dll" Alias "RegQueryValueExA" _
(ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal lpReserved As Long, _
lpType As Long, _
Byval lpData As String, _
lpcbData As Long) As Long
----------------------------------------------------------------------------- 
使用兩個宣告來解決這個問題,依不同的lpType呼叫不同的函式,即lpType= 
REG_ DWORD時,呼叫RegQueryLong, lpType = REG_SZ時則為RegQueryString這也可以讓
我們了解為何VB API的宣告為什麼要有Alias的存在。
范例三
*****************************************************************************
Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) _
As Long
Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA"
(ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
ByVal samDesired As Long, phkResult As Long) As Long
Declare Function RegQueryString Lib "advapi32.dll" Alias _
"RegQueryValueExA" (ByVal hKey As Long, _
ByVal lpValueName As String, ByVal lpReserved As Long, _
lpType As Long, ByVal lpData As String, lpcbData As Long) As Long
Const REG_EXPAND_SZ = 2
Const HKEY_CLASSES_ROOT = &H80000000
Const READ_CONTROL = &H20000
Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Const KEY_QUERY_VALUE = &H1
Const KEY_ENUMERATE_SUB_KEYS = &H8
Const KEY_NOTIFY = &H10
Const SYNCHRONIZE = &H100000
Const KEY_READ = ((STANDARD_RIGHTS_READ Or _
KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or _
KEY_NOTIFY) And (Not SYNCHRONIZE))
Dim key5 As String, ValueName as String, strBuff as String, ResultStr as String
Dim leng1 As Long, resul As Long, hkey As Long
Dim tp As Long, i As Long
key5 = " SOFTWARE\Microsoft\Windows\CurrentVerson "
resul = RegOpenKeyEx(HKEY_CLASSES_ROOT, key5, 0, KEY_READ, hkey)
'hkey便是subkey (key5)的KeyHandle,先取得它才能存取Subkey內的ValueName
ValueName= "ProDuctId "
tp = REG_SZ
strBuff = String(255, 0)
leng1 = Len(strBuff) + 1
resul = RegQueryString(hkey, ValueName, 0, tp, strBuff, leng1)
'注意,第三個叁數傳0,leng1傳回copy 到strBuff的字元個數(anci)
leng1 = InStr(1, strBuff, Chr(0), vbBinaryCompare) '重新算個數(UniCode)
ResultStr = Left(StrBuff,leng1-1) '這便是ProductId的值
***************************************************************************** 
在這里有另外一件事要特別說明,范例三程式中有一行leng1=Len(strBuffer)+1,這行
可省不得,很奇怪吧,為什麼明明是一個傳回值,卻一定要設定給它一個strBuff 的大
小呢?這是因為許多WIN API 不會聰明到找strBuff的Null Char在哪里,所以需要程式
傳進去,而後它再依這個欄位傳回填入strBuff 的數目。
五、Array叁數的傳遞
我們知道Win API 的陣列傳遞是傳陣列的起始位址,所以了,在VB中唯一要注意的是起
始位置的寫法。以另一個取得Window目錄所在路徑的API為
例: ----------------------------------------------------------------------------- 
UINT GetWindowsDirectory(
LPTSTR lpBuffer, // address of buffer for Windows directory

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产一区二区不卡老阿姨| av男人天堂一区| 不卡一区中文字幕| 69堂成人精品免费视频| 中文字幕在线一区二区三区| 日本亚洲视频在线| 91视频com| 久久久.com| 蜜臀av一区二区在线观看| 91丨九色丨黑人外教| www国产亚洲精品久久麻豆| 亚洲同性gay激情无套| 国产综合成人久久大片91| 欧美日韩成人在线一区| 亚洲美女屁股眼交| www.视频一区| 国产精品黄色在线观看| 国产精品99久| 久久久亚洲午夜电影| 日韩精品三区四区| 欧美人xxxx| 亚洲综合在线第一页| 成人av在线一区二区三区| 国产偷国产偷精品高清尤物| 美女视频一区二区三区| 欧美一区二区视频观看视频| 亚洲高清视频中文字幕| 日韩欧美国产综合一区 | 成人免费高清视频在线观看| 欧美成人精精品一区二区频| 日本欧美一区二区三区乱码| 欧美精品少妇一区二区三区| 午夜日韩在线观看| 欧美日韩免费高清一区色橹橹| 亚洲女爱视频在线| 色一情一乱一乱一91av| 亚洲午夜免费电影| 欧美一区二区三区思思人| 蜜桃精品在线观看| 久久综合狠狠综合久久激情| 久久国产成人午夜av影院| 欧美精品一区二区三区一线天视频| 精品一区二区在线免费观看| 精品国产91乱码一区二区三区 | 久久综合九色综合欧美就去吻| 毛片av一区二区| 久久久精品一品道一区| 成人午夜电影小说| 亚洲女性喷水在线观看一区| 在线欧美日韩国产| 奇米在线7777在线精品| 久久久久国产精品麻豆| 99久久精品国产麻豆演员表| 亚洲一区二区中文在线| 精品成人佐山爱一区二区| 岛国精品在线观看| 亚洲国产精品久久人人爱| 精品奇米国产一区二区三区| 成人精品鲁一区一区二区| 亚洲免费三区一区二区| 欧美一级午夜免费电影| 国产不卡免费视频| 一区二区三区欧美久久| 日韩视频在线一区二区| 99re8在线精品视频免费播放| 亚洲国产精品久久人人爱蜜臀| 精品国产电影一区二区| 色一区在线观看| 激情综合亚洲精品| 亚洲综合区在线| 久久综合九色综合97婷婷女人| 91在线视频观看| 久久99精品久久只有精品| 亚洲你懂的在线视频| 久久综合精品国产一区二区三区| 色噜噜狠狠成人中文综合| 老汉av免费一区二区三区| 亚洲私人影院在线观看| 欧美va亚洲va| 欧美色爱综合网| 不卡的av在线| 国产一区中文字幕| 日精品一区二区三区| 亚洲欧美另类小说视频| 精品福利一区二区三区免费视频| 欧美影院一区二区| 国产精品一级在线| 性感美女久久精品| 中文字幕日韩一区| 久久久久国产免费免费| 4438x亚洲最大成人网| 色综合天天综合网国产成人综合天| 蜜桃视频一区二区三区在线观看| 樱花影视一区二区| 国产精品国产三级国产普通话99 | 亚洲激情六月丁香| 日韩欧美的一区二区| 91国偷自产一区二区三区成为亚洲经典 | 捆绑变态av一区二区三区| 一区二区三区四区在线免费观看| 中文字幕免费不卡在线| 精品剧情在线观看| 亚洲精品在线一区二区| 欧美一区二区三区系列电影| 欧美喷潮久久久xxxxx| 欧美午夜电影在线播放| 91丝袜高跟美女视频| va亚洲va日韩不卡在线观看| 国产毛片精品视频| 久久国产精品99久久人人澡| 日韩不卡一二三区| 免费日韩伦理电影| 免费人成网站在线观看欧美高清| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 精品久久久久久最新网址| 91精品国产入口| 日韩视频在线一区二区| 精品国产欧美一区二区| 精品欧美乱码久久久久久| 欧美videos大乳护士334| 欧美精品一区二区三区蜜桃| 久久精品夜色噜噜亚洲aⅴ| 欧美激情一区在线观看| 亚洲日本在线视频观看| 一区二区三区美女视频| 日韩在线一二三区| 久久99久国产精品黄毛片色诱| 国产一区二区三区免费观看| 成人av在线播放网站| 91麻豆免费视频| 欧美精品少妇一区二区三区| 日韩欧美国产一区在线观看| 国产女主播一区| 一区二区三区日韩欧美精品| 日韩国产欧美在线播放| 激情国产一区二区| 99精品一区二区三区| 欧美日韩视频在线一区二区| 日韩精品专区在线影院观看| 国产精品乱人伦一区二区| 亚洲小少妇裸体bbw| 麻豆精品一区二区三区| 成人免费va视频| 欧美日韩一卡二卡| 国产三级三级三级精品8ⅰ区| 亚洲美女淫视频| 久久av中文字幕片| 色综合色狠狠天天综合色| 欧美高清视频在线高清观看mv色露露十八 | 日韩午夜精品视频| 国产日产亚洲精品系列| 亚洲成人777| 国产成人精品综合在线观看 | 在线免费观看视频一区| 日韩欧美国产系列| 综合自拍亚洲综合图不卡区| 亚洲国产成人精品视频| 国产一区二区视频在线播放| 在线观看日韩一区| 国产三级欧美三级日产三级99| 亚洲国产综合人成综合网站| 国产成人超碰人人澡人人澡| 欧美熟乱第一页| 午夜久久久久久久久久一区二区| 久久97超碰国产精品超碰| 97久久久精品综合88久久| 欧美一级日韩不卡播放免费| 自拍偷拍国产精品| 国产不卡视频一区| 精品理论电影在线| 五月激情六月综合| 91在线丨porny丨国产| 久久综合九色综合97婷婷| 午夜久久久久久电影| 91麻豆福利精品推荐| 中文字幕的久久| 国产麻豆欧美日韩一区| 欧美一级午夜免费电影| 亚洲第一综合色| 色综合久久88色综合天天免费| 国产日本亚洲高清| 国产九色精品成人porny| 日韩一级二级三级精品视频| 性欧美疯狂xxxxbbbb| 欧美性色综合网| 中文字幕在线不卡一区 | 中文字幕免费不卡| 国产精品一区一区| 欧美精品一区二区三区在线| 奇米影视一区二区三区| 91精品国产入口在线| 日韩成人午夜电影| 欧美久久久影院| 天天亚洲美女在线视频| 欧美人与性动xxxx| 日韩电影免费一区| 精品蜜桃在线看| 狠狠色狠狠色合久久伊人| 久久婷婷色综合| 国产大陆亚洲精品国产|