在我的 C# 3.5 Windows 窗体应用程序中,我有一些 SplitContainer。每个内部都有一个列表控件(停靠填充)。当焦点位于这些控件之一并且我移动鼠标滚轮时,现在获得焦点的列表会滚动。
我的任务是滚动当前由鼠标悬停的列表,而不是选定的列表。在 Windows 窗体中可以吗?如果不行的话,用 PInvoke 可以吗?
看起来你可以使用IMessageFilter
和 PInvoke 来处理这个问题。 VB 中的示例可以在以下位置找到将鼠标滚轮事件重定向到未聚焦的 Windows 窗体控件 http://www.codeproject.com/Articles/280310/Redirect-Mouse-Wheel-Events-To-Unfocused-Windows-F。您应该能够轻松地将其转换为 C#。
兴趣点
此类针对给定任务使用以下技术:
- 侦听控件的 MouseEnter 和 MouseLeave 事件以确定鼠标指针何时位于控件上方。
- 实现 IMessageFilter 以捕获应用程序中的 WM_MOUSEWHEEL 消息。
- PInvoke Windows API 调用 SendMessage,将 WM_MOUSEWHEEL 消息重定向到控件的句柄。
- IMessageFilter 对象作为 MouseWheelRedirector 类的单例实现,并由共享成员 Attach、Detach 和 Active 访问。
Using VB.NET 到 C# 转换器 http://www.developerfusion.com/tools/convert/vb-to-csharp/,这就是你最终得到的结果:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class MouseWheelRedirector : IMessageFilter
{
private static MouseWheelRedirector instance = null;
private static bool _active = false;
public static bool Active
{
get { return _active; }
set
{
if (_active != value)
{
_active = value;
if (_active)
{
if (instance == null)
{
instance = new MouseWheelRedirector();
}
Application.AddMessageFilter(instance);
}
else
{
if (instance != null)
{
Application.RemoveMessageFilter(instance);
}
}
}
}
}
public static void Attach(Control control)
{
if (!_active)
Active = true;
control.MouseEnter += instance.ControlMouseEnter;
control.MouseLeave += instance.ControlMouseLeaveOrDisposed;
control.Disposed += instance.ControlMouseLeaveOrDisposed;
}
public static void Detach(Control control)
{
if (instance == null)
return;
control.MouseEnter -= instance.ControlMouseEnter;
control.MouseLeave -= instance.ControlMouseLeaveOrDisposed;
control.Disposed -= instance.ControlMouseLeaveOrDisposed;
if (object.ReferenceEquals(instance.currentControl, control))
instance.currentControl = null;
}
private MouseWheelRedirector()
{
}
private Control currentControl;
private void ControlMouseEnter(object sender, System.EventArgs e)
{
var control = (Control)sender;
if (!control.Focused)
{
currentControl = control;
}
else
{
currentControl = null;
}
}
private void ControlMouseLeaveOrDisposed(object sender, System.EventArgs e)
{
if (object.ReferenceEquals(currentControl, sender))
{
currentControl = null;
}
}
private const int WM_MOUSEWHEEL = 0x20a;
public bool PreFilterMessage(ref System.Windows.Forms.Message m)
{
if (currentControl != null && m.Msg == WM_MOUSEWHEEL)
{
SendMessage(currentControl.Handle, m.Msg, m.WParam, m.LParam);
return true;
}
else
{
return false;
}
}
[DllImport("user32.dll", SetLastError = false)]
private static extern IntPtr SendMessage(
IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)