防止鼠标离开我的表格

我已经将一些MouseMoveMouseClick事件附加到我的程序中,接下来就是其中之一:

  1. 获得“全局”鼠标移动,这样我甚至可以在窗体外读取鼠标位置。
  2. 首先防止我的鼠标离开表单。

我的项目是一个游戏,因此像大多数其他游戏一样阻止鼠标离开我的形状真是太棒了(如果你用alt + tab fe切换焦点,你可以把它移出来),并看看其他人的答案。要求全球摩苏运动的问题,他们似乎对我的需求非常混乱。

有一种简单的方法可以阻止我的鼠标走出我的表格边界吗? 或者实际上为了防止它首先超出边界,我希望鼠标留在客户区域内。


有关游戏的其他信息:

游戏是一个短暂的,长达5到30秒的生存游戏(在你活着的30秒后变得太难了)你必须用你的鼠标躲避子弹。 当你将鼠标移出表格然后播放器(连接到鼠标的System.Windows.Forms.Panel )停止移动并立即被子弹击中时,这真的很烦人。 这就是为什么防止鼠标离开该区域会很好。

迟到的答案可能会派上用场。 您可以将表单订阅到MouseLeaveMouseMove事件并按如下方式处理它们:

  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; } 

以上将确保鼠标光标永远不会离开窗体的边界。 确保在游戏结束时取消订阅活动。

编辑:

Hans Passants的回答比我的回答更有意义。 在MouseEnter上使用Cursor.Clip

 private void Form1_MouseEnter(object sender, EventArgs e) { Cursor.Clip = this.Bounds; } 

如果出现任何错误/崩溃,你可以释放光标(我确定你可以赶上):

 Cursor.Clip = Rectangle.Empty; 

您无法捕获鼠标,这会阻止用户操作“开始”菜单。 最接近的是分配Cursor.Clip属性。 但是用户按下Ctrl + Esc很容易打败它,例如,没有通知。

最好的办法是订阅表单的Deactivated事件,它可靠地告诉您用户切换到另一个程序。 Activated事件会告诉您用户何时向后移动。 当然,当游戏得分取决于保持游戏对象移动时,用户几乎没有理由真正做到这一点。 所以不要忘记给用户一个简单的方法来暂停游戏,比如Escape键。

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

您可以使用Cursor类。 例如:

 int X = Cursor.Position.X; int Y = Cursor.Position.Y; 

至于阻止用户将鼠标移动到表单之外,最好的方法可能是如果你已经知道屏幕上表单的坐标是什么并附加一个MouseMove事件,并检查鼠标是否在表单内长方形。

要知道屏幕上的表格位置,请看一下这个问题。

我不建议全局鼠标移动控制有两个原因。

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

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

也就是说,上次我检查(前一段时间,在Vista上) SetWindowsHookEx仍然可以工作(但它没有正式支持IIRC),这是一个非托管调用,所以你必须用pinvoke但是用它就可以拒绝传递消息将鼠标移动到应用程序的边界之外。 我不是100%确定操作系统是否会让你击败光标控件(我之前只在桌面盒上阻止了键盘)但它可能是你最好的镜头。