C# 如何检测鼠标是否在整个窗体和子控件内?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/986529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to detect if the mouse is inside the whole form and child controls?
提问by rfgamaral
I need to detect when the user moves the mouse over the Form and all its child controls and also when it leaves the Form. I tried the MouseEnter
and MouseLeave
events of the Form, I tried the WM_MOUSEMOVE
& WM_MOUSELEAVE
and WM_NCMOUSEMOVE
& WM_NCMOUSELEAVE
pairs of windows messages but none seem to work as I want...
我需要检测用户何时将鼠标移到 Form 及其所有子控件上,以及何时离开 Form。我尝试了窗体的MouseEnter
和MouseLeave
事件,我尝试了WM_MOUSEMOVE
&WM_MOUSELEAVE
和WM_NCMOUSEMOVE
&WM_NCMOUSELEAVE
对 Windows 消息,但似乎没有一个像我想要的那样工作......
Most of my Form is occupied by child controls of many sorts, there's not much client area visible. This means that if I move the mouse very quickly the mouse movement will not be detected, although the mouse is inside the Form.
我的大部分表单都被各种子控件占用,没有多少客户区可见。这意味着如果我非常快速地移动鼠标,则不会检测到鼠标移动,尽管鼠标在窗体内。
For instance, I have a TextBox that is docked at the bottom and between the desktop and the TextBox, there's only a very small border. If I quickly move the mouse from the bottom into the TextBox, the mouse movement won't be detected, but the mouse is inside the TextBox, therefore, inside the Form.
例如,我有一个文本框,它停靠在桌面和文本框的底部和之间,只有一个非常小的边框。如果我将鼠标从底部快速移动到 TextBox 中,则不会检测到鼠标移动,但鼠标在 TextBox 内,因此,在 Form 内。
How can I achieve what I need?
我怎样才能达到我所需要的?
采纳答案by TcKs
You can hook the main message loop and preprocess/postprocess any (WM_MOUSEMOVE) message what you want.
您可以挂钩主消息循环并根据需要预处理/后处理任何 (WM_MOUSEMOVE) 消息。
public class Form1 : Form {
private MouseMoveMessageFilter mouseMessageFilter;
protected override void OnLoad( EventArgs e ) {
base.OnLoad( e );
this.mouseMessageFilter = new MouseMoveMessageFilter();
this.mouseMessageFilter.TargetForm = this;
Application.AddMessageFilter( this.mouseMessageFilter );
}
protected override void OnClosed( EventArgs e ) {
base.OnClosed( e );
Application.RemoveMessageFilter( this.mouseMessageFilter );
}
class MouseMoveMessageFilter : IMessageFilter {
public Form TargetForm { get; set; }
public bool PreFilterMessage( ref Message m ) {
int numMsg = m.Msg;
if ( numMsg == 0x0200 /*WM_MOUSEMOVE*/) {
this.TargetForm.Text = string.Format( "X:{0}, Y:{1}", Control.MousePosition.X, Control.MousePosition.Y );
}
return false;
}
}
}
回答by NascarEd
How about this: In your form's OnLoad, recursively go through all of the child controls (and their children) and hook up the MouseEnter event.
怎么样:在表单的 OnLoad 中,递归遍历所有子控件(及其子控件)并连接 MouseEnter 事件。
Then whenever the mouse enters any descendant, the event handler will be called. Similarly, you could hook up MouseMove and/or MouseLeave events.
然后每当鼠标进入任何后代时,将调用事件处理程序。同样,您可以连接 MouseMove 和/或 MouseLeave 事件。
protected override void OnLoad()
{
HookupMouseEnterEvents(this);
}
private void HookupMouseEnterEvents(Control control)
{
foreach (Control childControl in control.Controls)
{
childControl.MouseEnter += new MouseEventHandler(mouseEnter);
// Recurse on this child to get all of its descendents.
HookupMouseEnterEvents(childControl);
}
}
回答by fkerrigan
On your user control create a mousehover Event for your control like this, (or other event type) like this
在您的用户控件上为您的控件创建一个鼠标悬停事件,(或其他事件类型)像这样
private void picBoxThumb_MouseHover(object sender, EventArgs e)
{
// Call Parent OnMouseHover Event
OnMouseHover(EventArgs.Empty);
}
On your WinFrom which hosts the UserControl have this for the UserControl to Handle the MouseOver in your Designer.cs
在承载 UserControl 的 WinFrom 上,UserControl 可以在 Designer.cs 中处理 MouseOver
this.thumbImage1.MouseHover += new System.EventHandler(this.ThumbnailMouseHover);
Which calls this method on your WinForm
在您的 WinForm 上调用此方法
private void ThumbnailMouseHover(object sender, EventArgs e)
{
ThumbImage thumb = (ThumbImage) sender;
}
Where ThumbImage is the type of usercontrol
其中 ThumbImage 是用户控件的类型
回答by Defkon1
Quick and dirty solution:
快速而肮脏的解决方案:
private bool MouseInControl(Control ctrl)
{
return ctrl.Bounds.Contains(ctrl.PointToClient(MousePosition));
}