Call tips between VB and Windows API

zhaozj2021-02-17  51

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

转载请注明原文地址:https://www.9cbs.com/read-29669.html

New Post(0)