c#在任何地方检测鼠标点击(表格内外)

时间:2018-03-02 11:44:03

标签: c# forms winforms click mouse

是否可以在if语句中的任何位置(表单内部和外部)检测鼠标单击(左/右)?如果可能,怎么样?

if(MouseButtons.LeftButton == MouseButtonState.Pressed){

...

}

3 个答案:

答案 0 :(得分:2)

当用户在窗体控件外部单击时,它会失去焦点,您可以使用它。这意味着您必须使用窗体控件的_Deactivate(object sender, EventArgs e)事件才能使其工作。因为当表单失去焦点并且不再是活动表单时会触发 。让Form1成为表单,然后事件将如下所示:

private void Form1_Deactivate(object sender, EventArgs e)
{
    // Your code here to handle this event
}

答案 1 :(得分:1)

如果我理解了你需要"从窗外点击"这是一个入门者。而Hans Passant的建议并不适合你的需要。您可能需要为Form1_Click添加事件处理程序。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        Mutex checking = new Mutex(false);
        AutoResetEvent are = new AutoResetEvent(false);
        //You could create just one handler, but this is to show what you need to link to
        private void Form1_MouseLeave(object sender, EventArgs e)
        {
            StartWaitingForClickFromOutside();
        }

        private void Form1_Leave(object sender, EventArgs e)
        {
            StartWaitingForClickFromOutside();
        }

        private void Form1_Deactivate(object sender, EventArgs e)
        {
            StartWaitingForClickFromOutside();
        }

        private void StartWaitingForClickFromOutside()
        {
            if (checking.WaitOne(10))
            {
                var ctx = new SynchronizationContext();
                are.Reset();

                Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        if (are.WaitOne(1))
                        {
                            break;
                        }
                        if (MouseButtons == MouseButtons.Left)
                        {
                            ctx.Send(CLickFromOutside, null);
                            //you might need to put in a delay here and not break depending on what you want to accomplish
                            break;
                        }
                    }

                    checking.ReleaseMutex();
                });
            }
        }

        private void CLickFromOutside(object state)
        {
            MessageBox.Show("Clicked from outside of the window");
        }


        private void Form1_MouseEnter(object sender, EventArgs e)
        {
            are.Set();
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            are.Set();
        }

        private void Form1_Enter(object sender, EventArgs e)
        {
            are.Set();
        }

        private void Form1_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible == true)
            {
                are.Set();
            }
            else
            {
                StartWaitingForClickFromOutside();
            }
        }
    }
}

如果我理解错误,您可能会觉得这很有用:Pass click event of child control to the parent control

答案 2 :(得分:0)

一种方法是用无边框形式覆盖整个屏幕,并将属性设置为透明(比完全透明高几个百分点,不确定完全透明是否有效,但您不会注意到差异)并且还设置为最上面。然后使用表单中的事件。一旦检测到点击,这不会影响表单下方的任何内容(在我的应用程序中这是我想要发生的事情),但可以关闭表单并在几分之一秒后模拟另一次鼠标点击以激活控件下。我在 VB6 中使用 windows API 使用鼠标钩子没有问题,但似乎无法找到在 c# 中使用 2019 版 .NET 的东西,所以这是一个很好的解决方法。当然,要真正聪明,您可以使用不规则表单方法使透明表单与鼠标形状相同并跟随它。 注意:我刚刚找到了使用钩子来完成它的完整代码,普通人可以立即启动并运行! KeyboardMouseHooks C# 库 - CodePlex 存档 PS,如果您使用我的(愚蠢的)方法,请记住创建一个转义键或按钮,否则您将不得不重新启动计算机,除非该表单被编程为按照建议的真正点击消失!