我有带滚轮的罗技 M705 鼠标,允许水平滚动。我已经在我的 C# 程序中成功地为这个按钮事件实现了一个处理程序(按照这里的描述实现),但到目前为止我只能让它滚动一次。在资源管理器中,当我向右按下滚轮时,它会不断向右滚动,直到我松开滚轮。在我的程序中,它只滚动一步。在我松开并再次按下滚轮之前,看不到WM_MOUSEHWHEEL消息!
Q:如何实现消息的连续水平滚动WM_MOUSEHWHEEL
?
我有带滚轮的罗技 M705 鼠标,允许水平滚动。我已经在我的 C# 程序中成功地为这个按钮事件实现了一个处理程序(按照这里的描述实现),但到目前为止我只能让它滚动一次。在资源管理器中,当我向右按下滚轮时,它会不断向右滚动,直到我松开滚轮。在我的程序中,它只滚动一步。在我松开并再次按下滚轮之前,看不到WM_MOUSEHWHEEL消息!
Q:如何实现消息的连续水平滚动WM_MOUSEHWHEEL
?
将此添加到所有控件(表单、子项等):
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);
}
}
关键是为所有可能处理消息的控件返回一个非零值!
使用 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);
这将获取所有窗口消息(尽管此处仅捕获鼠标滚轮)-通过使用鼠标位置找到控件,然后您可以强制窗口将消息发送到该控件,即使它没有焦点。
注意:我使用了 WindowsMessages.MOUSEWHEEL,它来自一个枚举消息的类,只需替换
if (m.Msg.IsWindowMessage(WindowsMessages.MOUSEWHEEL))
最后带有注释位
if (m.Msg == 0x20a)