子控件获得焦点时如何在主窗体中获取鼠标移动事件

问题描述 投票:0回答:1

我有一个 winforms 应用程序,其 UI 设计为多层用户控件。我正在添加代码更改来监视我的应用程序是否空闲一段时间。为此,我正在以基本形式监视键盘和鼠标事件。即使子控件处于焦点状态,也会接收键盘事件,而在基本窗体中不会接收鼠标事件。 注意 - 子控件几乎覆盖整个主窗体区域。

无效的方法:

  1. 我尝试在主窗体的WndProc()中捕获WM_MOUSEMOVE、WM_LBUTTONDOWN。当鼠标在子控件上移动时,不会捕获这些消息

  2. 挂钩主窗体中的MouseMove、MouseClick、KeyDown事件,将KeyPreview和Captrere设置为true 这样,当子控件处于焦点状态时,只接收按键事件,不接收鼠标事件

  3. 不想使用系统挂钩,因为它会带来严重的安全问题

有人可以告诉我当子控件获得焦点时在主窗体中获取鼠标移动事件的简单方法是什么?我不想在每个子控件中进行更改,因为它们中的许多子控件不是从单个基本用户控件类继承的

c# winforms mouseevent childcontrol
1个回答
0
投票

使用普通事件处理程序捕获永久表单上的事件,然后在表单构造函数中添加以下代码

foreach (Control control in this.Controls)
{
    control.MouseMove += Form1_MouseMove; //where Form1_MouseMove is the name of the event handler
}

如果您想确保也捕获稍后添加的控件中的事件,请添加以下代码

private void Form1_ControlAdded(object sender, ControlEventArgs e)
{
    e.Control.MouseMove += Form1_MouseMove;
}

并将其附加到 Form.ControlAdded 事件

请参阅下面的完整示例

namespace mouse_capture_example
{
    public partial class Form1 : Form
    {
        int moveCount = 0;
        public Form1()
        {
            InitializeComponent();
            //capture MouseMove event for all controls
            foreach (Control control in this.Controls)
            {
                control.MouseMove += Form1_MouseMove;
            }
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            moveCount++;
            Console.WriteLine($"The mouse has been moved {moveCount} times");
        }
        
        //capture mouse events for controls being added later
        private void Form1_ControlAdded(object sender, ControlEventArgs e)
        {
            e.Control.MouseMove += Form1_MouseMove;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.