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

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

?? 12.txt

?? VB文章集(含API、窗口、數據庫、多媒體、系統、文件、等等)
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
VB5.0與Windows API 間的呼叫技巧 
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一区二区三区免费野_久草精品视频
国产精品一区二区三区网站| 91精品国产全国免费观看| 日本电影亚洲天堂一区| 日韩一二三区不卡| 亚洲欧美国产三级| 成人深夜在线观看| 日韩一区二区三区在线视频| 亚洲黄色性网站| 国产成人免费在线视频| 日韩一区二区三免费高清| 一区二区欧美精品| 99riav一区二区三区| 国产日韩一级二级三级| 九九视频精品免费| 欧美一区二区三区在线观看视频| 亚洲视频网在线直播| 成人毛片视频在线观看| 久久亚洲春色中文字幕久久久| 视频一区二区国产| 欧美性大战久久| 一区二区三区四区在线| 91视频国产观看| 亚洲人成网站影音先锋播放| av成人免费在线| 欧美韩国日本不卡| 国产成人免费av在线| 26uuu欧美日本| 精品一区二区三区在线播放| 日韩欧美不卡在线观看视频| 秋霞国产午夜精品免费视频| 日韩欧美久久久| 麻豆久久久久久| 欧美不卡在线视频| 久久精品二区亚洲w码| 精品乱人伦小说| 国产精一区二区三区| 国产日本欧洲亚洲| 成人福利在线看| 亚洲色图欧美在线| 欧美午夜电影一区| 日韩av一二三| 久久影院电视剧免费观看| 国产精一区二区三区| 一区在线播放视频| 欧美性xxxxxx少妇| 精品一区二区精品| 中文字幕免费一区| 欧美性高清videossexo| 日韩一区精品视频| 久久一区二区三区四区| 成人av小说网| 天天综合网天天综合色| 精品久久久久久久久久久久久久久久久| 久久国产欧美日韩精品| 中文字幕不卡在线| 欧美伊人久久久久久久久影院| 五月综合激情网| 国产午夜精品一区二区三区四区| 91丨九色丨黑人外教| 亚洲妇女屁股眼交7| 亚洲精品一区二区三区影院| 成人午夜视频在线| 日本免费新一区视频| 国产日韩影视精品| 欧美日韩精品免费| 从欧美一区二区三区| 午夜精品福利一区二区三区av | 久久久久国产精品麻豆ai换脸| 国产精品一区二区果冻传媒| 一区二区免费看| 337p粉嫩大胆噜噜噜噜噜91av| 一本大道综合伊人精品热热| 久久精品久久99精品久久| 中文字幕一区二区三中文字幕| 欧美日韩国产欧美日美国产精品| 国产激情偷乱视频一区二区三区| 亚洲午夜精品网| 国产女同互慰高潮91漫画| 欧美军同video69gay| 成人天堂资源www在线| 久久99精品国产麻豆婷婷洗澡| 一区二区三区四区不卡在线| 久久综合丝袜日本网| 欧美挠脚心视频网站| 91色九色蝌蚪| 丁香激情综合五月| 久久精品国产在热久久| 亚洲成av人片在线观看| 国产精品乱码久久久久久| 欧美成人女星排名| 欧美一卡二卡三卡四卡| 欧美午夜电影在线播放| 99久久久国产精品| 春色校园综合激情亚洲| 国产一区二区视频在线| 麻豆久久久久久| 日本一不卡视频| 亚洲高清中文字幕| 亚洲一卡二卡三卡四卡| 亚洲色图19p| 亚洲欧美在线观看| 国产精品色一区二区三区| 久久婷婷久久一区二区三区| 欧美成人一区二区三区| 日韩视频一区二区三区在线播放 | 欧美一区二区三区人| 91国内精品野花午夜精品| 91论坛在线播放| 972aa.com艺术欧美| av成人老司机| 日本伦理一区二区| 欧美专区亚洲专区| 欧美亚洲一区三区| 555www色欧美视频| 欧美一二三区精品| 日韩视频免费直播| 26uuu亚洲综合色| 国产午夜精品福利| 亚洲国产精品t66y| ...xxx性欧美| 一级中文字幕一区二区| 亚洲综合无码一区二区| 丝袜美腿亚洲综合| 另类综合日韩欧美亚洲| 国产资源精品在线观看| 国产成人免费视频网站| 93久久精品日日躁夜夜躁欧美| 91国模大尺度私拍在线视频| 91 com成人网| 精品成人a区在线观看| 欧美激情一区二区三区蜜桃视频| 中文字幕在线观看不卡| 欧美成va人片在线观看| 国产精品视频一区二区三区不卡 | 久久久久久久网| 国产精品免费久久久久| 亚洲精品免费看| 日本女优在线视频一区二区| 国产精选一区二区三区| 972aa.com艺术欧美| 欧美日韩的一区二区| 久久五月婷婷丁香社区| 一区二区三区美女视频| 婷婷夜色潮精品综合在线| 国产一区二区按摩在线观看| 色一情一伦一子一伦一区| 欧美精品色综合| 久久久99精品免费观看不卡| 亚洲精品视频免费观看| 麻豆国产91在线播放| 99久久综合精品| 精品毛片乱码1区2区3区| 又紧又大又爽精品一区二区| 韩国女主播成人在线观看| 91精品福利视频| 国产欧美视频在线观看| 亚洲国产日韩综合久久精品| 国产高清在线精品| 欧美另类videos死尸| 国产精品乱子久久久久| 视频一区国产视频| 色综合中文字幕国产| 欧美精品1区2区3区| 国产精品美女久久久久av爽李琼| 日日夜夜免费精品视频| 不卡的av中国片| 亚洲精品一线二线三线无人区| 一区二区三区精品视频| 国产91丝袜在线18| 欧美电影免费观看高清完整版| 亚洲猫色日本管| 丁香激情综合国产| 精品动漫一区二区三区在线观看| 亚洲va欧美va人人爽午夜| 成人激情免费视频| 亚洲精品一区二区三区福利| 亚洲成人先锋电影| 欧美这里有精品| 亚洲女爱视频在线| 白白色 亚洲乱淫| 国产肉丝袜一区二区| 狠狠狠色丁香婷婷综合久久五月| 欧美日韩精品欧美日韩精品一 | 欧美国产精品中文字幕| 精品亚洲成a人| 欧美一区二区三区视频免费播放 | 欧美精品高清视频| 亚洲制服丝袜在线| 日本乱码高清不卡字幕| 亚洲欧美自拍偷拍色图| 99久久综合狠狠综合久久| 中文无字幕一区二区三区| 国产精品伊人色| 久久久久久久精| 国产剧情一区二区三区| 国产午夜精品久久久久久免费视 | 欧美丰满一区二区免费视频| 亚洲电影在线播放| 欧美日韩一区国产| 五月天亚洲婷婷|