C# 防止鼠标离开我的窗体

C# 防止鼠标离开我的窗体,c#,.net,mouse,mouseevent,mousemove,C#,.net,Mouse,Mouseevent,Mousemove,我已将一些MouseMove和MouseClick事件附加到我的程序中,下一步是其中之一: 获取“全局”鼠标移动,以便我可以读取鼠标位置,甚至在窗体外部 首先防止我的鼠标离开窗体 我的项目是一个游戏,所以它是可怕的,以防止鼠标离开我的形式像大多数其他游戏一样(ofc。你可以移动它,如果你切换重点与alt+tab fe。)并看看其他问题的答案,要求全球移动,他们似乎相当混乱,我的需要 有没有一种简单的方法可以防止我的鼠标离开表单的边界?或者,实际上,为了防止鼠标越过边界,我希望鼠标停留在客户端区域

我已将一些
MouseMove
MouseClick
事件附加到我的程序中,下一步是其中之一:

  • 获取“全局”鼠标移动,以便我可以读取鼠标位置,甚至在窗体外部
  • 首先防止我的鼠标离开窗体
  • 我的项目是一个游戏,所以它是可怕的,以防止鼠标离开我的形式像大多数其他游戏一样(ofc。你可以移动它,如果你切换重点与alt+tab fe。)并看看其他问题的答案,要求全球移动,他们似乎相当混乱,我的需要

    有没有一种简单的方法可以防止我的鼠标离开表单的边界?或者,实际上,为了防止鼠标越过边界,我希望鼠标停留在客户端区域内


    有关游戏的其他信息:


    这个游戏是一个短的,5-30秒长的生存游戏(30秒后你很难活下来),你必须用鼠标躲避子弹。当你将鼠标移出窗体,然后播放器(
    System.Windows.Forms.Panel
    连接到鼠标)停止移动并立即被子弹击中时,这真的很烦人。这就是防止鼠标离开该区域的原因。

    您可以使用
    光标
    类。例如:

    int X = Cursor.Position.X;
    int Y = Cursor.Position.Y;
    
    至于防止用户将鼠标移到窗体外部,最好的方法可能是,如果您有办法知道窗体在屏幕上的坐标,并附加一个
    MouseMove
    事件,并检查鼠标是否在窗体矩形内


    要知道表单在屏幕上的位置,请看一看问题。

    我不知道您的确切问题的解决方案,但我对您有一个完全不同的想法。我不知道你的游戏是如何运作的,但根据你告诉我的,为什么不让它更难一步:在游戏区域添加边框,例如4像素宽的矩形,你是不允许触摸的。如果你触摸它们,你就会死掉,鼠标就会被释放。

    你不能捕捉鼠标,这会阻止用户,比如说,操作“开始”菜单。最接近的是指定Cursor.Clip属性。但是如果用户按Ctrl+Esc,则很容易失败。例如,没有关于此操作的通知


    最好的办法是订阅表单的停用事件,它可靠地告诉您用户切换到了另一个程序。激活的事件告诉您用户何时返回。当然,当游戏分数取决于保持游戏对象移动时,用户几乎没有理由这样做。因此,别忘了给用户提供一种简单的暂停游戏的方法,比如说使用Escape键。

    出于两个原因,我不推荐使用全局鼠标移动控制

    • 这是糟糕的设计,你应该尊重操作系统的界限。如果需要这种行为,请使应用程序全屏显示。应该执行此类操作的唯一应用程序是“kiosk”模式的应用程序,它锁定整个操作系统(以防止操作员滥用)

    • 全局键挂钩杂乱无章,不能保证工作,而且很危险,因为它们会影响操作系统的关键部分(所有控件)。代码中的错误可能导致需要重新启动计算机


    也就是说,上一次我检查(不久前,在Vista上)仍然有效(但它不是官方支持的IIRC),这是一个非托管调用,因此您必须使用pinvoke,但通过它,您可以拒绝传递将鼠标移动到应用程序边界之外的消息。我不能100%确定操作系统是否能让你在光标控制上击败它(我以前只在桌面框上屏蔽过键盘),但这可能是你最好的选择。

    回答晚了,但可能会派上用场。您可以将表单订阅到
    MouseLeave
    MouseMove
    事件,并按如下方式处理它们:

        private int X = 0;
        private int Y = 0;
    
        private void Form1_MouseLeave(object sender, EventArgs e)
        {
            Cursor.Position = new Point(X, Y);
        }
    
        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (Cursor.Position.X < this.Bounds.X + 50 )
                X = Cursor.Position.X + 20;
            else
                X = Cursor.Position.X - 20;
    
            if (Cursor.Position.Y < this.Bounds.Y + 50)
                Y = Cursor.Position.Y + 20;
            else
                Y = Cursor.Position.Y - 20;           
        }
    
    如果出现任何错误/崩溃,您可以释放光标(我相信您可以捕获它们):


    作为我的用户,我会认为这是一个粗鲁的行为。也许当鼠标不在你的窗口上时,你停止游戏会更好吗?只是说一点(作为评论,而不是回答),但这种行为会让我非常恼火。事实上,这会使我无法经常玩这样的游戏(因为我通常通过鼠标点击来切换窗口)阅读我添加的“附加信息”部分,这不是一个真正的问题,因为鼠标只锁定10-30秒,你可以随时自杀。所以,假设你成功地让鼠标停留在游戏的客户端区域内。现在,假设您的游戏碰巧崩溃。哎呀!鼠标现在卡在屏幕的该区域内,没有出路!最好采纳SJuan76的建议,将游戏冻结,直到鼠标移回客户端区域。@RobH我见过游戏这么做,我曾经玩过“传奇联盟”,只要窗口有焦点,你就不能将光标移出游戏窗口。一旦焦点丢失(或游戏关闭,或游戏崩溃等),鼠标就会恢复正常工作。其他答案并不能让我感到安慰,这其实是个不错的主意。以前没想过,谢谢!:)这很简单,但每个人都在抱怨吗?哇,谢谢:P
    确保在游戏结束时取消订阅活动。
    如果你的程序碰巧崩溃,那么它就无法取消订阅活动,你将陷入困境。这就是投诉的全部内容。我对为什么在2013年出现如此多关于这个问题的负面意见感到非常困惑。鼠标捕获被多个虚拟机接口使用,如果需要,它非常有助于将鼠标集中在虚拟O/S上。关键词在那里。
    private void Form1_MouseEnter(object sender, EventArgs e)
        {
            Cursor.Clip = this.Bounds;
        }
    
    Cursor.Clip = Rectangle.Empty;