c# – 在用户控件中捕获所有鼠标单击和按键
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 在用户控件中捕获所有鼠标单击和按键,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3370字,纯文字阅读大概需要5分钟。
内容图文
我想捕获特定用户控件中的所有按键和鼠标单击.我需要这样做才能创建一个空闲检测,这样如果用户在用户控件中没有做任何事情,我可以解锁实体.
我的第一次尝试是PreProcessMessage来检测Windows消息,但它似乎没有被调用?我的第二个是使用DefWndProc,但没有为这些消息调用它.
我怎样才能获得WM_KEYDOWN& WM_MOUSEUP用于用户控件及其所有子项?
更新
ProcessKeyPreview用于检测密钥
解决方法:
对于键盘方面,您可以尝试覆盖UserControl中的ProcessCmdKey事件.
UserControl.cs:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
//a key has been pressed within your user control
//invoke event or some other action
//...
return base.ProcessCmdKey(ref msg, keyData);
}
对于鼠标,我想你的UserControl实现IMessageFilter接口的PreFilterMessage方法可能是前进的方向(虽然我不确定这是否可以特定于用户控件).
编辑
我快速浏览了一下IMessageFilter,我认为我有一些可行的方法,虽然看起来有点复杂.
创建一个实现IMessageFilter的MessageHandler.
class MessageHandler : IMessageFilter
{
private int WM_LBUTTONUP = 0x0202; //left mouse up
private int WM_MBUTTONUP = 0x0208; //middle mouse up
private int WM_RBUTTONUP = 0x0205; //right mouse up
//stores the handles of the children controls (and actual user control)
List<IntPtr> windowHandles = new List<IntPtr>();
public MessageHandler(List<IntPtr> wnds)
{
windowHandles = wnds;
}
public bool PreFilterMessage(ref Message m)
{
//make sure that any click is within the user control's window or
//its child controls before considering it a click (required because IMessageFilter works application-wide)
if (windowHandles.Contains(m.HWnd) && (m.Msg == WM_LBUTTONUP || m.Msg == WM_MBUTTONUP || m.Msg == WM_RBUTTONUP))
{
Debug.WriteLine("Clicked");
}
return false;
}
}
在您的用户控件(或新类)中,您可以使用P / Invoke来获取给定父级的子窗口.从pinvoke.net
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
private static List<IntPtr> GetChildWindows(IntPtr parent, bool addParent = true)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
if (addParent)
result.Add(parent);
return result;
}
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
// You can modify this to check to see if you want to cancel the operation, then return a null here
return true;
}
GetChildWindows将返回我们需要的窗口.我修改了一下并添加了一个可选的addParent bool,它将用户控件本身添加到列表中.
在您的UserControl.cs构造函数中,我们可以注册MessageFilter并传递句柄列表(或者只要您知道用户控件的句柄,就可以通过其他形式添加它).
public MyControl()
{
InitializeComponent();
Application.AddMessageFilter(new MessageHandler(GetChildWindows(this.Handle)));
}
您现在应该能够在用户控件及其任何子窗口中检测到三个鼠标按钮事件.当您的应用程序关闭或UserControl关闭/处置时,不要忘记调用Application.RemoveMessageFilter.
正如我所说,这不是最直接的方式,但如果标准事件处理程序不适合您,它将捕获点击(我假设您已尝试订阅标准鼠标点击事件).
内容总结
以上是互联网集市为您收集整理的c# – 在用户控件中捕获所有鼠标单击和按键全部内容,希望文章能够帮你解决c# – 在用户控件中捕获所有鼠标单击和按键所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。