【问题标题】:How to pass messages from a child user-control to the parent如何将消息从子用户控件传递给父控件
【发布时间】:2010-01-07 23:34:40
【问题描述】:

这是一个 Windows 窗体/.Net C# 问题。

我有一个无边框窗口,其透明度键和背景颜色使其完全透明。窗口内有几个用户控件。

我希望能够移动窗口。我知道如何在父窗口上执行此操作,但我的问题是子控件是唯一可见的东西,因此是唯一可点击的东西。

问题是:如何将某些消息传递给父级,以便在按下鼠标右键并且鼠标在任何一个子控件上移动时父级可以移动?

或者你可以建议另一种方式?

感谢您的帮助。

标记

【问题讨论】:

  • 向窗口添加一些内容,使用户可以清楚地看到她可以单击它并移动窗口。除了带有“点击此处移动”标签的靶心之外,标题栏还提供了一个明显的 UI 小工具。

标签: c# .net winforms parent-child messages


【解决方案1】:

即使没有使用 System.Windows.Forms.Message 类的 SendMessage,您也可以实现您的目标。如果您已经完成拖动,我想您对WM_NCLBUTTONDOWN 消息很熟悉。从控件的 MouseDown 事件将其发送给您的父级。

这是一个移动表单的例子,点击控件 label1。请注意第一行,其中 sender 用于从单击的控件中释放捕获。通过这种方式,您可以将此处理程序设置为旨在移动表单的所有控件。

这是移动表单的完整代码。不需要其他任何东西。

public const int WM_NCLBUTTONDOWN = 0xA1; public const int HT_CAPTION = 0x2; private void label1_MouseDown(object sender, MouseEventArgs e) { (sender as Control).Capture = false; Message msg = Message.Create(Handle, WM_NCLBUTTONDOWN, (IntPtr)HT_CAPTION, IntPtr.Zero); base.WndProc(ref msg); }

希望这会有所帮助。

【讨论】:

  • 感谢您的建议。不幸的是,您提供的代码导致 UserControl 沿着父窗体的边界移动。一种简洁的效果,但不幸的是不是我所追求的。
  • 刚刚发现通过将代码中的 Handle 更改为 parent.Handle...效果很好。非常感谢您的帮助。现在我只需要弄清楚如何允许 UserControl 处理它自己的一些鼠标事件,并且只将拖动事件传递给 Parent。但我觉得我很接近。再次感谢。
  • 嗨,马克,不客气。如果您发现我的答案有用,请将其标记为有用或已接受的答案,谢谢。您希望 UserControl 处理哪些事件?
  • 这是天才,我想我将不得不覆盖所有控件中的所有 WndProc。非常感谢。
  • 我同意,纯粹的天才!
【解决方案2】:

我认为最简单的方法是将此事件添加到您的子控件中:

/// <summary>
/// The event that you will throw when the mouse hover the control while being clicked 
/// </summary>
public event EventHandler MouseRightClickedAndHoverChildControl;

之后,父级所要做的就是订阅这些事件并进行移动父级的操作:

ChildControl.MouseRightClickedAndHoverChildControl += OnMouseHoverChildControl;

private void OnMouseHoverChildControl(object sender, EventArgs e)
{
    //do foo...
}

【讨论】:

    【解决方案3】:

    您需要调用SendMessage API 函数将mouse messages 发送到您的父控件。

    覆盖控件的WndProc 方法可能是最简单的方法。

    【讨论】:

    • 我应该在我的 WndProc 中捕获哪些消息?我会按原样(相同的 wParam 和 lParam)将它们传递给 parent.Handle 吗?
    • 您应该捕获链接中的所有鼠标消息。您需要将坐标调整为相对于父控件。 (拨打PointToScreen,然后拨打PointToScreen
    • 谢谢。我想我明白了。但是你说PointToScreen然后PointToScreen?您的意思是 PointToScreen 获取屏幕坐标,然后 PointToClient 将它们转置到父窗口的客户端?
    • 是的,我确实是这个意思。 (错字)
    【解决方案4】:

    我确实有这个问题......但想出了一个不同的答案。 如果您的 WndProc 中有消息,则只需将句柄更改为父句柄,然后将其传递。

    我需要在派生的 TextBox 中执行此操作... TextBox 会吃滚轮事件,即使它的 ScrollBars 设置为 None。我希望那些传播到表格。所以,我只是把它放在我派生的 TextBox 的 WndProc 中:

                case 0x020A: // WM_MOUSEWHEEL
                case 0x020E: // WM_MOUSEHWHEEL
                    if (this.ScrollBars == ScrollBars.None && this.Parent != null)
                        m.HWnd = this.Parent.Handle; // forward this to your parent
                    base.WndProc(ref m);
                    break;
    
                default:
                    base.WndProc(ref m);
                    break;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 2011-12-02
      • 2020-08-21
      • 1970-01-01
      相关资源
      最近更新 更多