2012-06-28 24 views
2

我有一個滾輪的羅技M705鼠標,可以進行水平滾動。我已經在我的C#程序中成功實現了此按鈕事件的處理程序(按照here的描述實現),但到目前爲止,我只能讓它滾動一次。在資源管理器中,當我按下輪子右側時,它會連續滾動到,直到我鬆開輪子。在我的程序中,它只滾動一個步驟。在我釋放並再次按下滾輪之前,不會看到WM_MOUSEHWHEEL消息!如何處理WM_MOUSEHWHEEL Explorer的方式呢?

問:如何實現連續水平滾動的WM_MOUSEHWHEEL消息?

+0

http://stackoverflow.com/questi ons/10999659/make-mouse-tilt-horizo​​ntal-scrolling-always-repeat,解決方案是VB.NET,但很容易轉換爲C#。 – Viezevingertjes

+0

謝謝。這幾乎是我已經實施的。問題不在於處理消息。問題是該消息只發送一次。對於Explorer.exe也是如此,所以我真的不明白他們如何設法實現持續滾動。我在Spy ++中看不到額外的消息... – l33t

回答

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); 
    } 
} 

的關鍵是針對可能處理消息的所有控件返回一個非零值!

0

使用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); 

也在形式收附加:

Application.RemoveMessageFilter(this); 

這將拿起所有窗口的消息(雖然只有鼠標滾輪被困在這裏) - 通過使用mouseposition找到控制其結束,然後可以強制Windows將消息發送到該控件,即使它沒有焦點。

注:我已經使用WindowsMessages.MOUSEWHEEL這是一類我有枚舉的消息,只需更換

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

與評論位在年底

if (m.Msg == 0x20a)

相關問題