在 UserControl 中捕获包含控件的鼠标事件 [英] Catching a Contained Control's Mouse Events in a UserControl

查看:36
本文介绍了在 UserControl 中捕获包含控件的鼠标事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 UserControl 包含另一个 UserControl.我希望包含控件能够处理发生在包含控件区域上的任何鼠标事件.最简单的方法是什么?

I have a UserControl that contains another UserControl. I'd like the containing control to be able to handle any mouse events that happen over the contained control's area. What's the easiest way to do this?

更改包含控件的代码是可能的,但只能作为最后的手段.包含的控件有一个由非托管库控制的窗口.

Changing code for the contained control is possible, but only as a last resort. The contained control has a window that is controlled by an unmanaged library.

FWIW,我尝试为包含的控件的鼠标事件添加处理程序,但这些处理程序永远不会被调用.我怀疑包含的控件正在消耗鼠标事件.

FWIW, I have tried adding handlers for the contained control's mouse events, but those handlers never get called. I suspect the contained control is consuming the mouse events.

我已经考虑在包含的控件之上添加某种透明窗口来捕获事件,但我对 Windows 窗体仍然很陌生,我想知道是否有更好的方法.

I've considered adding some sort of transparent window on top of the contained control, to catch the events, but I'm still pretty new to Windows Forms and I'm wondering if there is a better way.

推荐答案

嗯,这在技术上是可行的.您必须自己重定向鼠标消息,这需要一些 P/Invoke.将此代码粘贴到您的内部 UserControl 类中:

Well, it's technically possible. You have to redirect the mouse message yourself, that requires a bit of P/Invoke. Paste this code into your inner UserControl class:

    protected override void WndProc(ref Message m) {
        // Re-post mouse messages to the parent window
        if (m.Msg >= 0x200 && m.Msg <= 0x209 && !this.DesignMode && this.Parent != null) {
            Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
            // Fix mouse position to be relative from parent's client rectangle
            pos = this.PointToScreen(pos);
            pos = this.Parent.PointToClient(pos);
            IntPtr lp = (IntPtr)(pos.X + pos.Y << 16);
            PostMessage(this.Parent.Handle, m.Msg, m.WParam, lp);
            return;
        }
        base.WndProc(ref m);
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

顺便说一句,最好避免这种情况.父控件应该只订阅内部控件的鼠标事件.

This is best avoided btw. The parent control should probably just subscribe to the inner control's mouse events.

这篇关于在 UserControl 中捕获包含控件的鼠标事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆