PDA

View Full Version : Get a Structure from a Pointer



Adamski
06-08-2010, 06:31 AM
Hi,

I am using WinAPI calls with VBA. How do I access a RECT from the pointer to it that the API returns? Something like this:


Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type

Private Function CBTProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

If nCode = HCBT_MOVESIZE Then
Dim WinRect As RECT
WinRect = lParam ' But lParam is only a pointer to the RECT!
Debug.Print WinRect.left
end If

End Function


Thanks

Bob Phillips
06-08-2010, 07:12 AM
That is not exactly clear. Explain it a different way.

Adamski
06-08-2010, 08:25 AM
lParam is a pointer to a rect structure returned via API.
How can I access it to get left, top, right and bottom?
I think maybe I need to use the CopyMemory api call.

Bob Phillips
06-08-2010, 09:25 AM
No, you would access it like a class with properties. something like



MsgBox WinRect.left
MsgBox WinRect.top
'etcx.

Adamski
06-08-2010, 09:42 AM
WinRect is empty.
The data is in the RECT pointed to by lParam.
I want to populate WinRect with the same data as in the RECT Structure pointed at by lParam.

stanl
06-08-2010, 10:02 AM
WinRect is empty.
The data is in the RECT pointed to by lParam.
I want to populate WinRect with the same data as in the RECT Structure pointed at by lParam.

I'll go out on a limb here, since you did not include the API call that produces lParam. If lParam truly returns a memory address, then I suppose you could go with memcopy, but I would think it points to an array and you would fill your Winrect structure accordingly... viz.

Winrect.left = lParam(0,1) 'or lParam(0)

just .02

Kenneth Hobs
06-08-2010, 01:07 PM
Too many unknowns to say for sure. Maybe:
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, rectangle As RECT) As Boolean

Const HCBT_MOVESIZE = 1

Private Function CBTProc(ByVal nCode As Long, ByVal wParam As Long, ByRef lParam As RECT) As Long
If nCode = HCBT_MOVESIZE Then
Dim WinRect As RECT
WinRect = lParam ' But lParam is only a pointer to the RECT!
Debug.Print WinRect.Left, WinRect.Top, WinRect.Right, WinRect.Bottom
End If
End Function

Sub Test()
Dim r As RECT
GetWindowRect Application.hwnd, r
CBTProc 1, 2, r
End Sub

Adamski
06-23-2010, 08:48 AM
lParam only contains the address of the RECT - It is a number

Paul_Hossler
06-23-2010, 09:05 AM
Filed under "USE AT YOUR OWN RISK" : pray2: , you could try something like this. -- Really not tested


Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
dest As Any, source As Any, ByVal Bytes As Long)

Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type

Private Function CBTProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

Dim WinRect As RECT

Call CopyMemory(VarPtr(WinRect), lParam, 16)

End Function


Paul

Paul_Hossler
06-23-2010, 07:03 PM
Actually I did get a chance to try the concept out -- this might just work for you ... but you have to be careful.

I didn't have enought of your code to do more than the CopyMemory concept, so you'll have to work it into your module


Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
ByVal dest As Any, ByVal source As Any, ByVal Bytes As Long)

Private Type RECT
left As Long
top As Long
right As Long
bottom As Long
End Type

Sub test()

Dim WinRect As RECT
Dim WinRect2 As RECT
Dim ptrWinRect As Long
Dim ptrWinRect2 As Long

With WinRect
.bottom = 100
.left = 200
.right = 300
.top = 400
End With


'input pointer
ptrWinRect = VarPtr(WinRect)

'pointer to destination
ptrWinRect2 = VarPtr(WinRect2)

Call CopyMemory(ptrWinRect2, ptrWinRect, 16)

With WinRect2
MsgBox .bottom
MsgBox .left
MsgBox .right
MsgBox .top
End With

End Sub


Paul

Adamski
06-28-2010, 07:48 AM
Cheers Paul,

I had been screwing up ByVal/ByRef in the API declare. I have them figured out now.