Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create wParam for GET_WHEEL_DELTA_WPARAM

Tags:

windows

api

vb6

If I scroll a window using the computer mouse, I get the following Spy++ results:

fwKeys: 0, zDelta: -120

I need to emulate a mouse wheel event by code, so I use PostMessage like this:

Public Declare Function CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long) As Long

PostMessage lHwnd, WM_MOUSEWHEEL, MakeWParam(0, -120), 0

Public Function MakeWParam(ByVal uHigh As Long, ByVal uLow As Long) As Long

    Dim foo(0 To 1) As Integer
    Dim lRet As Long

    foo(0) = uHigh
    foo(1) = uLow

    Call CopyMemory(lRet, VarPtr(foo(0)), Len(lRet))

    MakeWParam = lRet

End Function

This however results in Spy++ telling me the following:

fwKeys: 3C40, zDelta: 8996

I don't see where I'm doing it wrong.

According to MSDN, zDelta can be extracted from wParam using GET_WHEEL_DELTA_PARAM, but I don't see any information on how this wParam is actually created from fwKeys and zDelta. And obviously my approach is not correct.

I have also tried SendMessage instead of PostMessage, but the result was the same.

Thank you for the help!

like image 370
tmighty Avatar asked Jan 10 '20 19:01

tmighty


2 Answers

Since you don't have ByVal for pSource, you either shouldn't use VarPtr for foo(0), or you should pass it explicitly ByVal: CopyMemory lRet, ByVal VarPtr(foo(0))... or CopyMemory lRet, foo(0)...

Also, you have foo() As Integer, but you assign Long variables to its contents. Are you sure that's what you want?

like image 132
Jim Mack Avatar answered Oct 19 '22 19:10

Jim Mack


If you need to simulate the mouse wheel I think you would be much better off using SendInput like this:

Private Const MOUSEEVENTF_WHEEL = &H800
Private Const INPUT_MOUSE = 0
Private Type MOUSEINPUT
    dx As Long
    dy As Long
    mouseData As Long
    dwFlags As Long
    time As Long
    dwExtraInfo As Long
End Type
Private Type GENERALINPUT
    dwType As Long
    xi(0 To 23) As Byte
End Type
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" (dest As Any, ByVal numbytes As Long)
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Declare Function SendInput Lib "user32.dll" (ByVal nInputs As Long, pInputs As GENERALINPUT, ByVal cbSize As Long) As Long

Private Sub RotateMouseWheel(Optional lWheelClicks As Long = 1, Optional lWheelDirection As Long = 1)
Dim i As Long, GInput() As GENERALINPUT, MInput As MOUSEINPUT
    ReDim GInput(0 To lWheelClicks - 1)
    ZeroMemory MInput, Len(MInput): MInput.dwFlags = MOUSEEVENTF_WHEEL: MInput.mouseData = 120 * lWheelDirection
    For i = 0 To lWheelClicks - 1
        GInput(i).dwType = INPUT_MOUSE
        CopyMemory GInput(i).xi(0), MInput, Len(MInput)
    Next i
    SendInput lWheelClicks, GInput(0), Len(GInput(0))
End Sub

You can specify the number of wheel clicks to rotate the wheel as well as the rotation direction (1 means forward and -1 backward) as parameters. Hope this helps.

like image 23
VanGogh Gaming Avatar answered Oct 19 '22 19:10

VanGogh Gaming