PDA

View Full Version : Win32 API Programming / Question reference book example(s)



GTO
10-20-2015, 03:48 PM
Hello All :hi:,

After far too long, I have started trying to muddle my way through Win32 API Programming with Visual Basic (by Steven Roman).

I made it to the second example in the book before experiencing a different return than the author...:banghead:. Being as I'd rather not be missing stuff while trying to understand and learn, here's the examples, in case anyone can point out what I am missing (or if there is an error in the example of course).

In case there are followup questions, here are the declared functions thus far. I'll repost the lot of them only if there are added ones or changes...


In a Standard Module:


Option Explicit
'//*************************************************************************** **********//
'// All Basic Examples from Win32 API Programming with Visual Basic by Steven Roman
'// I tacked in (hopefully correct) conditional declarations in some cases, just in case
'// it would make any difference...
'//*************************************************************************** **********//

Public Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000
Public Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200

#If VBA7 Then
Const FAKE As Boolean = True
Declare PtrSafe Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (lpDest As Any, _
lpSource As Any, _
ByVal cbCopy As LongPtr)

Declare PtrSafe Sub VBGetTarget Lib "kernel32" _
Alias "RtlMoveMemory" (Target As Any, _
ByVal lPointer As LongPtr, _
ByVal cbCopy As LongPtr)

Declare PtrSafe Function GetClassName Lib "user32" _
Alias "GetClassNameA" (ByVal hWnd As LongPtr, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long _
) As Long
Declare PtrSafe Function FormatMessage Lib "kernel32" _
Alias "FormatMessageA" (ByVal dwFlags As Long, _
lpSource As Any, _
ByVal dwMessageId As Long, _
ByVal dwLanguageId As Long, _
ByVal lpBuffer As String, _
ByVal nSize As Long, _
Arguments As LongPtr _
) As Long
#Else
Const FAKE As Boolean = False
Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" (lpDest As Any, _
lpSource As Any, _
ByVal cbCopy As Long)

Declare Sub VBGetTarget Lib "kernel32" _
Alias "RtlMoveMemory" (Target As Any, _
ByVal lPointer As Long, _
ByVal cbCopy As Long)

Declare Function GetClassName Lib "user32" _
Alias "GetClassNameA" (ByVal hWnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long _
) As Long

Declare Function FormatMessage Lib "kernel32" _
Alias "FormatMessageA" (ByVal dwFlags As Long, _
lpSource As Any, _
ByVal dwMessageId As Long, _
ByVal dwLanguageId As Long, _
ByVal lpBuffer As String, _
ByVal nSize As Long, _
ByVal Arguments As Long _
) As Long
#End If



Here are the two examples, the difference in return is shown in the code as comment.

In a Standard Module:


' PG 34, output a string by bytes
Sub CopyMemoryString_ANSI()
Dim sString As String
Dim aBytes(1 To 20) As Byte
Dim i As Integer

sString = "help"

CopyMemory aBytes(1), ByVal sString, LenB(sString)

For i = 1 To 20
Debug.Print aBytes(i);
Next
' Book shows output of: 104 101 108 112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
' At least in WIN7, I get: 104 101 108 112 0 0 110 0 0 0 0 0 0 0 0 0 0 0 0 0
End Sub

Private Sub CopyMemoryString_Uni()
Dim sString As String
Dim aBytes(1 To 20) As Byte
Dim i As Integer
Dim lng As Long

sString = "help"
lng = StrPtr(sString) 'Get contents of BSTR variable
CopyMemory aBytes(1), ByVal lng, LenB(sString) 'Now copy as array

For i = 1 To 20
Debug.Print aBytes(i);
Next
' Book shows and I get correct output of: 104 0 101 0 108 0 112 0 0 0 0 0 0 0 0 0 0 0 0 0
End Sub

Tommy
10-21-2015, 06:45 AM
Hi GTO

The information I have is this.
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long).
· Destination
Points to the starting address of the copied block’s destination.


· Source
Points to the starting address of the block of memory to copy.


· Length
Specifies the size, in bytes, of the block of memory to copy.

so
CopyMemory aBytes(1), ByVal sString, LenB(sString)
(in my way of thinking) Should be
CopyMemory aBytes(1), StrPtr(sString), LenB(sString) 'StrPtr is a string pointer to the string.
You could also clear the byte array just to make sure it IS clear, we used to have to do that in FORTRAN because you never knew what you got when you initialized variables.:think:

GTO
10-21-2015, 09:43 PM
Hi Tommy and thank you for the response.

In the other example 'CopyMemoryString_Uni()', the author shows using the pointer and returning the character array in unicode fashion.
That is, it would return: 104 0 101 0 108 0 112 0 0 0 0 0 0 0 0 0 0 0 0 0

Although the locals window showed the byte array initialized to zeros, I also cleared the array to zeros, just in case.

I tried two other PCs. Still, the errant character would be reported (a different character, but at the same position) when sending the string itself. But (to my embarrassment) it finally dawned on me to run the code full speed (I had been stepping through the code each and every time) at least through the call to CopyMemory.

Sigh… That was it, as it returns correctly every time. I don't remember what other API functions I've noticed this on, but I do seem to recall that certain ones (or VBA when using them) seem to hiccup when stepping through.

Phew! I sure hope my 'muddle' speed picks up or it's going to be an awfully long book!

Thank you again for your response, it is much appreciated :friends:

Mark

Tommy
10-22-2015, 04:14 AM
I have an API-Guide the http://allapi.mentalis.org/agnet/apiguide.shtml it has working examples with explanations. You can also download a program with the examples and you can search it for what you are looking for. I found out the hard way that you do some serious damage with this if you are not careful.

GTO
10-22-2015, 11:32 PM
Thanks again. I have gone through AllAPI some myself. Hopefully the book will help me get a better understanding (I'm sure it will) of the underpinnings...

Have a great weekend!

Mark

Aflatoon
10-23-2015, 08:18 AM
FWIW I'd also highly recommend Dan Appleman's Visual Basic Programmer's Guide to the Win32 API book.

GTO
10-25-2015, 11:43 PM
Thanks Rory. I'll get it :-)