Consulting

Results 1 to 11 of 11

Thread: Get a Structure from a Pointer

  1. #1

    Get a Structure from a Pointer

    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:

    [vba]
    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
    [/vba]

    Thanks
    Last edited by Adamski; 06-08-2010 at 08:26 AM.

  2. #2
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    That is not exactly clear. Explain it a different way.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  3. #3
    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.

  4. #4
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    No, you would access it like a class with properties. something like

    [vba]

    MsgBox WinRect.left
    MsgBox WinRect.top
    'etcx.
    [/vba]
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  5. #5
    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.

  6. #6
    VBAX Master stanl's Avatar
    Joined
    Jan 2005
    Posts
    1,141
    Location
    Quote Originally Posted by Adamski
    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

  7. #7
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,956
    Location
    Too many unknowns to say for sure. Maybe:
    [VBA]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
    [/VBA]

  8. #8
    lParam only contains the address of the RECT - It is a number

  9. #9
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,729
    Location
    Filed under "USE AT YOUR OWN RISK" , you could try something like this. -- Really not tested

    [vba]
    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
    [/vba]

    Paul

  10. #10
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,729
    Location
    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

    [vba]
    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
    [/vba]

    Paul

  11. #11
    Cheers Paul,

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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •