我有一个自定义 WinForms 控件(从 Control 派生),我在其中覆盖 OnMouseXXX 和 OnKeyXXX 事件。
我想在按下鼠标按钮时处理滚轮和/或键盘事件(即 OnMouseDown 已触发,但 OnMouseUp 尚未触发)。出于某种原因,在释放鼠标按钮之前,我无法获得其中的任何一个。
请就此事提出建议。使用互操作/不安全代码(如果需要)可以,但不能使用计时器读取键盘状态。
我有一个自定义 WinForms 控件(从 Control 派生),我在其中覆盖 OnMouseXXX 和 OnKeyXXX 事件。
我想在按下鼠标按钮时处理滚轮和/或键盘事件(即 OnMouseDown 已触发,但 OnMouseUp 尚未触发)。出于某种原因,在释放鼠标按钮之前,我无法获得其中的任何一个。
请就此事提出建议。使用互操作/不安全代码(如果需要)可以,但不能使用计时器读取键盘状态。
您可以上一层并使用 IMessageFilter() 代替全局挂钩,而不是全局挂钩。这适用于您的应用程序仅聚焦时。不知道你需要在什么级别工作...
public partial class MyUserControl : UserControl
{
private MyFilter filter;
public MyUserControl()
{
InitializeComponent();
filter = new MyFilter();
filter.LButtonScroll += new MyFilter.LBUTTONSCROLLDELEGATE(filter_LButtonScroll);
Application.AddMessageFilter(filter);
}
private void filter_LButtonScroll()
{
Console.WriteLine("WM_MOUSEWHEEL while LBUTTONDOWN");
}
private class MyFilter : IMessageFilter
{
private bool LBUTTONDOWN = false;
private const int WM_LBUTTONDOWN = 0x201;
private const int WM_LBUTTONUP = 0x202;
private const int WM_MOUSEWHEEL = 0x20a;
public delegate void LBUTTONSCROLLDELEGATE();
public event LBUTTONSCROLLDELEGATE LButtonScroll;
public bool PreFilterMessage(ref Message m)
{
switch (m.Msg)
{
case WM_LBUTTONDOWN:
LBUTTONDOWN = true;
break;
case WM_MOUSEWHEEL:
if (LBUTTONDOWN)
{
if (LButtonScroll != null)
{
LButtonScroll();
}
}
break;
case WM_LBUTTONUP:
LBUTTONDOWN = false;
break;
}
return false;
}
}
}