Call tips between VB5.0 and Windows API
The situation of the Window API is usually used because the VB itself does not provide certain functions, but the program is
Need to be, for example: reading the information within Registry, VB only provides Savesetting, GetSetting, etc.
The series of instructions, but it can only read the value of a particular area, read, delete, and more than the value of other regions, it will not
use. Again: Take a closer look at the Events of Combo Box, there is no mousemove, but this is what we often use.
A EVENT, what is it? Yes, it only has through the Winodow API. VB call Window API
Do not all use the API reviewer, directly put the corresponding API COPY to our program, what technology is used
Do you? In fact, because the problem of VB data format, plus VB itself has no indicator, in many places need one
Some tips can be solved, and we often have a different demand to announce the declaration of the API examiner COPY
Do some modifications, the most important, if there is a .dll file, it is not defined in the API reviewer, then only
I want to think about it.
First, integer parameters
Windows API32-bit VB
============================== ============================================================================================================================================================= =========
Int, int Byval Long
Unit, DWORD BYVAL Long
Bool byval long ture is 1
WParam, LPARM, LRESULT BYVAL Long
Handle (such as HKEY) BYVAL Long
Word, Atom, Short byval integer
Byte, char Byval byte
EG.
-------------------------------------------------- ---------------------------
Windows API declares
Short getKeyState (int NVIRTKEY)
Corresponding VB declaration
Declare function getKeyState LIB "User32" (Byval Nvirtkey As Long) AS Integer
-------------------------------------------------- ---------------------------
This API can be used to see some Key (such as INSERT, NUM LOCK, CAPSLOCK, etc.) is ON / OFF. Approach
The formula is as follows: This example should be very well seen in the declaration of each integer.
-------------------------------------------------- -------------------------- DIM INSERTMODE AS INTEGER
INSERTMODE = GetKeyState (VBKEYINSERT) and VBSHIFTMASK
IF insertmode = 1 THEN
Debug.print "Represents Insert Mode"
Else
Debug.print "indicates Overwrite Mode"
END IF
-------------------------------------------------- ---------------------------
Second, point to an integer
Windows API 32-bit VB
============================ ======================== ====
LPINT (BYREF) LONG
LPUNIT (BYREF) Long
LPBOOL (Byref) Long
LPDWORD (BYREF) LONG
LPHANDLE (like: phkey) (byref) long
LPWORD (Byref) Integer
LPShort (byref) Integer
Lpbyte (byref) Byte
VB demonstrates uses a partition call, so Byref can be omitted, that is to say
Func (Byref Param1 As Type)
versus
Func (param1 as type)
Is the same, way of using the service call, not to pay attention to the parameter to the API, will pass the result back. However, Long
The address call of the type has a considerable amount of parts in VB, because the 32-bit indicators are LONG types, while words
Strings, Structure, Structure in the Windows API, is transmitted by indicators, and the passage of the indicator is actually
It is the transmission of the long value, only the last LONG value, it will be used as address in the Win API, and again
The content of the indicator is indicated by the indicator, which will be important behind it.
E.g:
-------------------------------------------------- ---------------------------
Long regopenkeyex
HKEY HKEY, / / HANDLE OF Open Key
LPCTSTR LPSZSUBKEY, / / Address of Name of Subkey To Open
DWORD dwreserved, // reserved
Regsam Samdesired, // Security Access MaskphKey Phkresult // Address of Handle of Open Key
);
Comparison VB declaration
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 '// The last parameter is by Byref
-------------------------------------------------- ---------------------------
We often want to use the program to read the materials in Registry, for example: we want to know Win95 PRODU
How do CT IDs do? There are several ideas here to be clear: First: What is the productID? in
HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows / CurrentVerson's ProductID.
What we have to get is
Key is HKEY_LOCAL_MACHINE
Subkey is Software / Microsoft / Windows / CurrentVerson
Valuename is Value for ProductID
However, to get the productID Value is not so direct, you must first get the keyhandle of Subkey and Key.
The acquisition of Handle is the use of RegQueryKeyex's API. The program part is introduced when the WIN API string is passed.
And introduced.
Third, string parameters
Any all string parameter indicators are passed on byval parameter name. REGOPENKEYEX ()
The second parameter byval lpsubkey as string is an example. Maybe asked, this example is the Subkey value
To the Win API, use byval, there is nothing big, in fact, when you want to pass back the string, you must have a Win API.
Use ByVal announcement. This is a different factor in VB5 string format (BSTR) and WIN API Standard String Format (LPSTR).
The LPSTR string format is a string of Null Terminate. If there is a string "Haha! OK!", The format is as follows:
-------------------------------------------------- ---------------------------
Address 0 1 2 3 4 5 6 7 8 9
- - - - - - - - -
Content h a h a! O k! / 0
BSTR has a long value in front of the string, and the format is as follows:
Address 0 .. 3 4 5 6 7 8 9 10 11 12 13
---- - - - - - - - - - -
Content 9 h a h a! O k! / 0
-------------------------------------------------- ---------------------------
Therefore, the string is unregistered in the words of ByVal, and is it as if it is in the case of the BSTR? I think it is because of this way of passing String in a BYVAL. String can get the Win API's pass.
Return value, (Even if this is not the case, at least I want to make a string to pass by byval). Now there is one
A problem, the string of Window95 API uses ASCII CODE but VB is unicode, Unicode accounts for two digits.
Mesets, then can the WinAPI string? Fortunately, we can do it right, because VB itself has made it, ie
When VB is passed to the API, turn it again, turn back to Unicode again, so if we use Byte Array
The signal is also possible, but you have to go to the code.
. However, in the 32-bit VB, the string has a format, one is BSTR, the other is HLSTR, if we declare
The string is a non-fixed length, which will be BSTR, and it is HLSTR.
DIM BSTR5 AS STRING BSTR
DIM HLSTR5 AS STRING (255) HLSTR
Call in VB5 Win32 API, use BSTR, because the result of using HLSTR is, VB has to do HLSTR
-> BSTR's conversion to call the Win API if there is a back String and then do the work of BSTR-> HLSTR. However
When BSTR is working, if there is a String parameter with the return value, there is an additional action:
1. First give the primary value of the string, and the length of the string is enough to release the value.
2. Remove the extra valence in the return value.
or
E.g:
-------------------------------------------------- ---------------------------
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
);
The API obtains text of Window Title Bar, and the return value is the number of Character placed in lpstring.
The declaration of VB is as follows:
DECL area Function getWindowText lib "user32" alias "getWindowTexta" _
(Byval Hwnd As Long, _
Byval LPSTRING As String, _
BYVAL CCH AS Long) As long
Example
*********************************************************** ***********************************
DIM Charcnt As Long
Dim lpstring as string
DIM TMPSTR AS STRING
DIM NULLPOS As Long
Form1.caption = "This is a Test"
LPSTRING = String (255, 0) 'Setting initial value
Charcnt = getWindowText (me.hwnd, lpstring, 256) 'Charcnt = 12
TMPSTR = Left (lpstring, charcnt) 'This will have some questions debug.print len (tmpstr)'
Label1.caption = left (lpstring, charcnt)
Debug.print len (label1.caption) 'Get 8
*********************************************************** ***********************************
From an example of example one, the purpose of setting lpstring = string (255, 0) is to set 255 characters.
The space is given to lpstring (plus the last NULL 256), the value of Charcnt is 12, and the eye can see Len ("this
Is a test ") will be 8, but Charcnt is 12, so use the Left () function directly to obtain a child sequence.
Question, this is the relationship between Unicode and ANSI String, so, when you see some books, this method is used
Sub strings, it is not very perfect, so the way of modification is written, it is more correct.
Example 2
*********************************************************** ***********************************
Form1.caption = "This is a Test"
LPSTRING = String (255, 0) 'Setting initial value
Charcnt = getWindowText (me.hwnd, lpstring, 256) 'Charcnt = 12
Nullpos = INSTR (1, LPString, Chr (0), VBINARYCOMPARE)
Tmpstr = Left (LPSTRING, NULLPOS - 1)
Lable1.caption = tmpstr
*********************************************************** ***********************************
Fourth, NULL value
Let's go back to the question of ProductID, we know the use of regopenkeyex () to get Subkey Han
The DLE value is followed by 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
);
Declaration of VB (Copy from the API viewer)
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
-------------------------------------------------- ---------------------------
Take a closer look, Win API is LPDWORD in VB, is it transmitted with ByVal?
? The reason is that LPRESERVED must pass NULL in, and VB is filled in the position of this parameter when the call is called.
Example 3). Why do you pass NULL? We can think so, we have next instructions in the program, tell VB to
Byval's way 0 out, while in the Win API, it can be vb is Byval or byref, API identifies us
Enter
It is what it needs, so, the third parameter determines that we pass us in the API, and VB
In 0 Go, if the API will get the content of Address 0, maybe Window's
NULL value is pointing to address 0! Another method is directly related to the third parameter of VB announcement
BYVAL LPRESERVED AS Long change to Byval LPRESERVED AS STRING and fixed transmission
VBnullString can also be in. Here is in an idea, that is, VB's announcement of Win API, purely to VB
I look at it yourself, define a parameter of an indicator in the API, and the API viewer will declare it into a Byref method (string
Except for it), but we can do it with the needs, an original should be declared by parameters of Byref, we can change it to
Byval's way, as long as we can obtain the address of the parameters, and the location of this state is transmitted by ByVal.
Win API doesn't know what the VB terminal is used. Anyway, as long as we pass a long value into, Win API
This will operate as ADDRESS as this long value.
The problem has not been resolved, and the fourth parameter of RegQueryValueex () LPTYPE is represented by reg_sz (= 1)
LPDATA is Null Terminate String, if reg_dword (= 4) that represents LPDATA is a long value,
positive
It is because there is no way to know the true state of LPDATA in advance, so VB uses Asany's type, it wants VB to give up
The check of the type, what is the value, but there are some problems here, if lpty is reg_dword
Then LPDATA doesn't have a problem in a Byref, but if lptype is reg_sz, string is to use byval
The way is to declare, so there will be conflicts, and the way solution is to rewrite the declaration of the API reviewer 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
-------------------------------------------------- ---------------------------
Use two declaration to solve this problem, call different functions according to different LPTYPE, ie LPTYPE = REG_
When DWORD, call regQuerylong, lptype = reg_sz is regQueryString this can also make us
Learn why the VB API declares why there is Alias existence.
Example three
*********************************************************** ***********************************
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 Longdim TP As Long, i As Long
Key5 = "Software / Microsoft / Windows / CurrentVerson"
Resul = regopenkeyex (HKEY_CLASS_ROOT, Key5, 0, Key_Read, HKey)
'HKEY is the keyhandle of Subkey (Key5), first get it to access Valuename in Subkey
Valuename = "ProductID"
TP = reg_sz
Strbuff = string (255, 0)
Leng1 = len (strbuff) 1
Resul = regQueryString (HKEY, VALUENAME, 0, TP, STRBUFF, LENG1)
'Note, the third parameter transmission 0, the number of characters (ANCI) (ANCI) passing back COPY to STRBUFF
Leng1 = INSTR (1, strbuff, chr (0), vbinarycompare) 'Re-calculate a number (Unicode)
Resultstr = left (strbuff, leng1-1) 'This is the value of ProductID
*********************************************************** ***********************************
There is another thing here to specifically explain that there is a line of leng1 = len (strbuffer) 1 in the exemplary three-way.
This line can save, very strange, why is it clearly a return value, but be sure to set it a strBuff
What about the size? This is because many Win APIs are not smart to find StrBuff's null char where,
The program is passed, and then it is again transferred back to the number of StrBuff.
V. Parameters of Array Parameters
We know that the array of WIN API is the start address of the pass array, so, the only thing to pay in VB
It is a way of writing. The API of the path where the Window directory is located
example:
-------------------------------------------------- ---------------------------
Uint getWindowsDirectory
LPTSTR LPBUFFER, // Address of Buffer for Windows DIRECTORY
UINT USIZE // Size of Directory Buffer
); // If successful, return the number of characters of the directory
VB announcement (API reviewer)
DECLARE FUNCTION GETWINDOWSDIRECTORY LIB "kernel32" alias _
"GetWindowsDirectorya" (byval lpbuffer as string, byval nsize as long)
As long
We will change it to
DECLARE FUNCTION GETWINDOWSDIRECTORY LIB "kernel32" alias _
"GetWindowsDirectorya" (LPBuffer As Byte, Byval Nsize As Long) As long