1

下部に水平スクロール バーがドッキングされたフォームを設計しています。マウスのチルト ボタンを使用した横スクロールのサポートを追加したいと考えていたところ、このソリューションを見つけました。これは、少しいじくり回した後、うまくいくように見えました。つまり、フォームの表面には GDI グラフィックスしか描画されていませんでした。

ただし、それ以来、フォームにいくつかのコントロールを追加したところ、マウスがそれらのいずれかの上にあるときに、マウスが他の部分の上にあるときのように繰り返しではなく、一度に 1 回だけチルト操作が発生することがわかりました。フォームの。

私が何を意味するかを確認するには (チルト ボタン付きのマウスを使用している場合)、水平スクロールバーをフォームの下部にドッキングし、他のいくつかのコントロールを追加して、次のコードを貼り付けます。

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 関数に例外をスローしたため、正しい値を返しているかどうかさえわかりません。Spy++ を使用して解決しようとしましたが、明らかなことは何もわかりません。

アイデアはありますか?


アップデート

Spy++ に「子」ウィ​​ンドウを含めると、2 つの (0x020E) メッセージと 1 と 0 の 2 つの戻り値があることに気付きました。メッセージはフォームによってコントロールに渡されていると思います。したがって、問題は次のとおりだと思います。メッセージがコントロールに渡されないようにすることはできますか? または、コントロールの戻り値を傍受して 1 に変換できますか?

4

1 に答える 1

0

私はなんとか回避策を考え出しましたが、これよりも良い方法があるはずだと確信しています。私が行ったことは、フォームで使用され、コントロールから継承する各タイプのコントロールのクラスを追加することです。次に、これらのコントロールによって処理されるメッセージ1に対して常に返されるように、各クラスに WndProc プロシージャを追加しました。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

次に、フォームのデザイナー コードの参照を変更するだけでした。

私が言うように、これよりも良い方法があるに違いないと確信しています。多数の異なるコントロール クラスに対してそれを行わなければならない場合は大変ですが、私の場合は、いくつかの基本的なコントロールに対してのみ必要でした。


誰かがより良い解決策を提案してくれることを期待して、これを数日間開いたままにしましたが、何も来ていないので、私自身の答えを受け入れるつもりです.

于 2012-06-15T15:29:45.360 に答える