将子控件MouseMove事件无缝转发到父控件

编程入门 行业动态 更新时间:2024-10-04 01:27:16
本文介绍了将子控件MouseMove事件无缝转发到父控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个使用GDI +绘制的自定义UserControl.这是一个透明的控件,可以在父控件的顶部绘制小形状.

I have a custom UserControl that I am drawing using the GDI+. It is a transparent control which draws small shapes on top of the parent control.

父窗口所做的全部工作就是创建控件,为其提供一个可在其中绘制自身的矩形,然后,如果用户单击非透明区域,它将接收事件.

All the parent window does is creates the control, gives it a Rectangle in which to draw itself, and then it receives events if the user clicks on the non-transparent areas.

工程图部分工作正常,但是现在我需要做的是将所有MouseMove,MouseClick等事件尽可能无缝地转发到父控件(如果这些事件发生在形状之外).

The drawing part works perfectly, but right now what I need to do is to as seamlessly as possible forward all MouseMove, MouseClick, etc. events to the parent control IF those events occurred outside the shapes.

使用GraphicsPath绘制形状,并且我已经能够使用GraphicsPath.IsVisible()检测鼠标位置是否在形状上方.

The shapes are drawn using GraphicsPath, and I am already able to detect if the mouse position is over a shape using GraphicsPath.IsVisible().

我想要以这样的方式来执行此操作,即在父级上需要零个或最少的额外代码.父级不必一定知道是否从子级控件转发了MouseMove事件,它应该将它们同等对待.

I want to do this in a way that requires zero or minimal extra code on the parent. The parent should not necessarily know whether the MouseMove event was forwarded from the child control or not, it should treat them all equally.

我是否必须pinvoke/SendMessage()才能做到这一点?还是有使用.NET框架的更简单方法?

Do I have to pinvoke/SendMessage() to do this? Or is there an easier way using the .NET framework?

推荐答案

这在winapi中是可能的,窗口管理器发送WM_NCHITTEST消息以询问鼠标位于控件顶部的哪个部分.您可以做的是返回HTTRANSPARENT,它将询问父窗口.这是实现此目的的示例UserControl.捕获消息需要覆盖WndProc():

This is possible in the winapi, the WM_NCHITTEST message is sent by the window manager to ask what part of the control the mouse is on top of. What you can do is return HTTRANSPARENT and it will ask the parent window. Here's a sample UserControl that implements this. Catching the message requires overriding WndProc():

public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); paths = new List<GraphicsPath>(); GraphicsPath example = new GraphicsPath(); example.AddEllipse(new Rectangle(10, 10, 50, 30)); paths.Add(example); } List<GraphicsPath> paths; protected override void OnPaint(PaintEventArgs e) { foreach (var path in paths) e.Graphics.FillPath(Brushes.Blue, path); base.OnPaint(e); } protected override void WndProc(ref Message m) { base.WndProc(ref m); // Trap WM_NCHITTEST on the client area if (m.Msg == 0x84 && m.Result == (IntPtr)1) { Point pos = new Point(m.LParam.ToInt32()); pos = this.PointToClient(pos); bool oncurve = false; foreach (var path in paths) if (path.IsVisible(pos)) oncurve = true; if (!oncurve) m.Result = (IntPtr)(-1); // HTTRANSPARENT } } }

以下形式的测试代码:

private void userControl11_MouseMove(object sender, MouseEventArgs e) { Console.WriteLine("On shape {0}", e.Location); } private void Form1_MouseMove(object sender, MouseEventArgs e) { Console.WriteLine("On form {0}", e.Location); }

更多推荐

将子控件MouseMove事件无缝转发到父控件

本文发布于:2023-11-03 04:23:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1554224.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控件   事件   MouseMove

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!