【问题标题】:Create wParam for GET_WHEEL_DELTA_WPARAM为 GET_WHEEL_DELTA_WPARAM 创建 wParam
【发布时间】:2020-01-10 19:56:05
【问题描述】:

如果我使用计算机鼠标滚动窗口,我会得到以下 Spy++ 结果:

fwKeys: 0, zDelta: -120

我需要通过代码模拟鼠标滚轮事件,所以我像这样使用 PostMessage:

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

然而,这导致 Spy++ 告诉我以下内容:

fwKeys: 3C40, zDelta: 8996

我看不出哪里做错了。

根据 MSDN,zDelta 可以使用 GET_WHEEL_DELTA_PARAM 从 wParam 中提取,但我没有看到任何关于这个 wParam 是如何从 fwKeys 和 zDelta 实际创建的信息。显然我的方法是不正确的。

我也试过用 SendMessage 代替 PostMessage,但结果是一样的。

感谢您的帮助!

【问题讨论】:

  • 显示您对CopyMemory 的声明。这看起来有点像ByRef/ByVal mismatch
  • 不知道为什么你使用 CopyMemory 违反了你的编程合同(看看当 MS 忘记做编程合同时会发生什么devblogs.microsoft.com/oldnewthing/20200110-00/?p=103316)。此代码显示了如何正常提取它Dim x As Long: x = &h00050078: MsgBox "HiParam " & x \ 65535: MsgBox "LoParam " & (x And 65535)
  • VB.NET 中的 MS 使 VB6 在某种程度上具有可移植性。访问 VB6 的内部变量会使您的代码完全不可移植。
  • @JimMack 谢谢。我已将我的声明添加到帖子中。
  • @Mark 我使用了 CopyMemory,因为我在 VB6 论坛中找到了这个示例。

标签: windows api vb6


【解决方案1】:

因为你没有ByVal 对应pSource,所以你不应该使用VarPtr 对应foo(0),或者你应该明确地传递它ByValCopyMemory lRet, ByVal VarPtr(foo(0))...或@987654327 @...

另外,您有foo() As Integer,但您将Long 变量分配给它的内容。你确定这就是你想要的吗?

【讨论】:

  • 你说得对,我的功能有问题。我现在改用这个函数: Public Function MAKEWParam(uLowWord&, uHiWord&) As Long MAKEWParam = (uLowWord And &HFFFF&) Or (uHiWord * &H10000) End Function 它不容易出错。
【解决方案2】:

如果您需要模拟鼠标滚轮,我认为您最好像这样使用 SendInput:

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

您可以指定旋转轮子的点击次数以及旋转方向(1 表示向前,-1 表示向后)作为参数。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2012-03-07
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 2021-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多