2

水平スクロールを可能にするスクロールホイール付きのLogitechM705マウスを持っています。このボタンイベントのハンドラーをC#プログラム(ここで説明するように実装)に正常に実装しましたが、これまでのところ、スクロールできるのは1回だけです。Explorerで、ホイールを右に押すと、ホイールを離すまで右にスクロールし続けます。私のプログラムでは、1ステップだけスクロールします。WM_MOUSEHWHEELメッセージは、離してホイールをもう一度押すまで表示されません。

Q:メッセージの連続水平スクロールをどのように実装しWM_MOUSEHWHEELますか?

4

2 に答える 2

1

これをすべてのコントロール (フォーム、子など) に追加します。

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    base.WndProc(ref m);

    const int WM_MOUSEHWHEEL = 0x020E;
    if (m.Msg == WM_MOUSEHWHEEL)
    {
        m.Result = new IntPtr(HIWORD(m.WParam) / WHEEL_DELTA);
    }
}

重要なのは、メッセージを処理する可能性のあるすべてのコントロールに対してゼロ以外の値を返すことです!

于 2012-07-11T14:47:28.313 に答える
0

Use IMessageFilter

    public partial class MyForm: Form, IMessageFilter
...
 public ImageForm(Image initialImage)
        {
            InitializeComponent();            
            Application.AddMessageFilter(this);
        }

/// <summary>
        /// Filters out a message before it is dispatched.
        /// </summary>
        /// <returns>
        /// true to filter the message and stop it from being dispatched; false to allow the message to continue to the next filter or control.
        /// </returns>
        /// <param name="m">The message to be dispatched. You cannot modify this message. </param><filterpriority>1</filterpriority>
        public bool PreFilterMessage( ref Message m )
        {
            if (m.Msg.IsWindowMessage(WindowsMessages.MOUSEWHEEL))  //if (m.Msg == 0x20a)
            {   // WM_MOUSEWHEEL, find the control at screen position m.LParam      
                var pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
                var hWnd = WindowFromPoint(pos);
                if (hWnd != IntPtr.Zero && hWnd != m.HWnd && FromHandle(hWnd) != null)
                {
                    SendMessage(hWnd, m.Msg, m.WParam, m.LParam);
                    return true;
                }
            }

            return false;
        }


        [DllImport("user32.dll")]
        private static extern IntPtr WindowFromPoint(Point pt);

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

also in form closing add:

Application.RemoveMessageFilter(this);

This will pick up an all windows messages (although only mousewheel is trapped here) - by using the mouseposition to find the control its over, you can then force windows to send the message to that control even if it has no focus.

NOTE: I have used WindowsMessages.MOUSEWHEEL which is from a class I have that enumerates the messages, just replace

if (m.Msg.IsWindowMessage(WindowsMessages.MOUSEWHEEL))

with the commented bit at the end

if (m.Msg == 0x20a)

于 2012-07-11T15:01:05.210 に答える