使鼠标倾斜水平滚动始终重复

时间:2012-06-12 15:17:26

标签: .net vb.net winforms mouseevent mousewheel

我正在设计一个水平滚动条停靠在底部的表单。我希望使用鼠标倾斜按钮添加对侧滚动的支持,并找到this solution,经过一些修补,似乎可以解决这个问题 - 也就是说,表格只在其表面上绘制了GDI图形。

然而,从那时起我已经在表单中添加了一些控件,发现当鼠标悬停在他们中的任何一个上时,倾斜操作只会一次触发一次,而不是反复触发当鼠标悬停在表单的任何其他部分上时,它会发生。

要查看我的意思(如果您的鼠标带有倾斜按钮)将水平滚动条停靠在表单底部,请添加一些其他控件并粘贴此代码:

Public Class Form1
    Const WM_MOUSEHWHEEL As Integer = &H20E

    Protected Overrides Sub WndProc(ByRef m As Message)
        MyBase.WndProc(m)
        If Me.IsDisposed OrElse m.HWnd <> Me.Handle Then Return 
        Select Case m.Msg
            Case WM_MOUSEHWHEEL
                With HScrollBar1
                    If CType(m.WParam, Integer) < 0 Then '______________ Left Scroll
                        If .Value > 0 Then .Value -= 1
                    Else '______________________________________________ Right Scroll
                        If .Value < (.Maximum - .LargeChange + 1) Then .Value += 1
                    End If
                End With
                m.Result = CType(1, IntPtr) 'Indicates the message has been handled
        End Select
    End Sub

    Private Sub HScrollBar1_ValueChanged(sender As Object, e As System.EventArgs) Handles HScrollBar1.ValueChanged
        Console.WriteLine(HScrollBar1.Value)
    End Sub
End Class

当鼠标悬停在表单的空白部分上时,您会看到侧滚动重复,但当它超过控件时只会“一次性”。

我猜测解决方案位于消息.Result值的某处,但我不知道应该是什么。事实上,我甚至不确定我是否正在返回正确的值,因为原始解决方案中的代码引发了DirectCast函数的异常,因此我将其替换为CType,这似乎工作正常。我尝试使用Spy ++进行解决,但我看不出任何明显的东西。

有什么想法吗?


更新

我注意到当我在Spy ++中包含'Child'窗口时,有两个(0x020E)消息和两个返回值,1然后是0.我假设消息正在通过表单传递给控件。所以我想现在的问题是:是否可以阻止消息传递给控件?或者可以拦截控件的返回值并将其转换为1?

1 个答案:

答案 0 :(得分:0)

我设法设计了一种解决方法,但我确信必须有比这更好的方法。我所做的是为我的表单上使用的每种控件添加一个类,并从控件继承。然后我为每个类添加了一个WndProc过程,以便始终为这些控件处理的1消息返回WM_MOUSEHWHEEL。例如,这是按钮类:

Public Class scButton
    Inherits Button
    Protected Overrides Sub WndProc(ByRef m As Message)
        MyBase.WndProc(m)
        If Me.IsDisposed OrElse m.HWnd <> Me.Handle Then Return
        If m.Msg = Win32Messages.WM_MOUSEHWHEEL Then m.Result = New IntPtr(1)
    End Sub
End Class

然后只需更改表单设计器代码中的引用即可。

正如我所说,我相信必须有比这更好的方法。如果你不得不为大量不同的控制类做这件事会很痛苦,但就我而言,我只是需要一些基本控件。


我将这个开放了几天,希望有人能提出更好的解决方案,但一切都没有,所以我会接受我自己的答案。