原文:C# WPF 实现鼠标固定在指定范围内运动

 

一.背景:

需要实现带有三个屏幕,三个屏幕分别显示窗体,但鼠标只能在主窗体中运动,不能移动到其他的两个附屏中。

 

二.实现:

具体实现使用的是user32.dll下的GetWindowRect(int hwnd,
ref RECT lpRect)函数。

参考百度百科:https://baike.baidu.com/item/ClipCursor

 

ClipCursor,函数名。该函数把鼠标限制在屏幕上的一个矩形区域内,如果调用SetCursor或用鼠标设置的一个随后的鼠标位置在该矩形区域的外面,则系统自动调整该位置以保持鼠标在矩形区域之内。

函数原型

BOOL ClipCursor(CONST RECT * lpRect);

参数

IpRect:指向RECT结构的指针,该结构包含限制矩形区域左上角和右下角的屏幕坐标,如果该指针为NULL(空),则鼠标可以在屏幕的任何区域移动。

返回值

如果成功,返回值非零;如果失败,返回值为零。若想获得更多错误信息,请调用GetLastError。

备注

1.光标是一个共享资源,如果一个应用控制了鼠标,在将控制转向另一个应用之前,必须要使用ClipCursor来释放鼠标,该调用过程必须具有对窗口的WINSTA_WRITEATTRIBUTES访问权。

2.此函数为api函数,调用时要函数声明:Private Declare Function ClipCursor Lib "user32" (lpRect
As Any) As Long

及以上版本;Windows
CE:不支持;头文件:winuser.h;库文件;user32.lib。

 

 

三.代码

我主要实现的是限定屏幕,所以提供的接口直接和屏幕有关,其他的具体情况具体分析。

 

using System;

using System.Linq;

using System.Runtime.InteropServices;

 

 

namespace Tool.ClipCursor

{

    class ClipCursorHelper

    {

 

        [DllImport("user32.dll")]

        static extern bool ClipCursor(ref RECT lpRect);

 

        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint =
"GetWindowRect")]

        extern static int GetWindowRect(int hwnd,
ref RECT lpRect);

 

        public struct RECT

        {

            public int Left;

            public int Top;

            public int Right;

            public int Bottom;

 

            public RECT(Int32 left,
Int32 top,
Int32 right, Int32 bottom)

            {

                Left = left;

                Top = top;

                Right = right;

                Bottom = bottom;

            }

        }

        /// <summary>

        /// 设置鼠标显示在主屏范围内

        /// </summary>

        /// <returns></returns>

        public static bool SetCursorInPrimaryScreen()

        {

            System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.AllScreens.OrderBy(t => t.WorkingArea.X).First();

            RECT rect =
new RECT(screen.Bounds.X, screen.Bounds.Y, screen.Bounds.Right+screen.Bounds.X, screen.Bounds.Bottom);

            return ClipCursor(ref rect);

        }

        /// <summary>

        /// 恢复鼠标显示,可以所以屏幕的任何位置

        /// </summary>

        /// <returns></returns>

        public static bool Default()

        {

            System.Windows.Forms.Screen screen = System.Windows.Forms.Screen.AllScreens.OrderByDescending(t => t.WorkingArea.X).First();

            RECT rect =
new RECT(0, 0, screen.Bounds.Right+ screen.Bounds.X, screen.Bounds.Bottom);

            return ClipCursor(ref rect);

        }

 

    }

}

 

 

四.遇到的问题

1、在调试过程中发现每次窗体切换(如生成新的窗体),鼠标的范围又都返回到可以在任意位置使用,所以在每当生成窗体的时候都需要调一下上面的接口;

2、当使用Alt+Tab切换任务后,鼠标的限定范围也会不起作用,目前还无法解决;

但目前已经满足需要,网友知道如何避免上述两种问题的望交流学习。

C# WPF 实现鼠标固定在指定范围内运动的更多相关文章

  1. WPF 程序鼠标在窗口之外的时候,控件拿到的鼠标位置在哪里?

    原文:WPF 程序鼠标在窗口之外的时候,控件拿到的鼠标位置在哪里? 在 WPF 程序中,我们有 Mouse.GetPosition(IInputElement relativeTo) 方法可以拿到鼠标 ...

  2. WPF绑定文本时使用指定格式文本

    原文:WPF绑定文本时使用指定格式文本 Text="{Binding PlayletModel.characters,StringFormat=Cast : {0}}" Strin ...

  3. WPF 跟随鼠标动画 by wgscd

    WPF 跟随鼠标动画 by wgscd <UserControl x:Class="WpfApplication1.Spark" xmlns="http://sch ...

  4. WPF 使用鼠标拖动一个控件的实现[2018.7.15]

    原文:WPF 使用鼠标拖动一个控件的实现[2018.7.15] Q:已经把一个Shape和一个TextBlock组合起来放到了一个Grid中,现在想要实现用鼠标拖动这个Grid到任意位置的功能,如何做 ...

  5. WPF 获取鼠标屏幕位置、窗口位置、控件位置

    原文:WPF 获取鼠标屏幕位置.窗口位置.控件位置 public struct POINT { public int X; public int Y; public POINT(int x, int ...

  6. wpf 判断鼠标在一段时间内是否移动

    原文:wpf 判断鼠标在一段时间内是否移动 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/config_man/article/details/74 ...

  7. [WPF]自定义鼠标指针

    原文:[WPF]自定义鼠标指针 [WPF]自定义鼠标指针 周银辉 看看WPF Cursor类的两个构造函数吧:  * f));            g.Flush();            g.D ...

  8. [WPF]获取鼠标指针下的元素

    原文:[WPF]获取鼠标指针下的元素   [WPF]获取鼠标指针下的元素 周银辉 以前写过一些GetElementUnderMouse之类的函数,要用到坐标换算而显得有些麻烦(特别是当元素有XXXTr ...

  9. 《Programming WPF》翻译 第3章 3.内嵌控件

    原文:<Programming WPF>翻译 第3章 3.内嵌控件 WPF提供了一系列内嵌控件.其中大多数符合标准的你已经熟悉的Windows控件类型.注意到没有一个是包装在旧的Win32 ...

随机推荐

  1. python的报错

    1;; //////////////////////////////////////////////////////////////////////////////////////////////// ...

  2. [AngularJS] Using an AngularJS directive to hide the keyboard on submit

    Pleasea refer to Link <form ng-submit="foo()" handle-phone-submit> <input type=&q ...

  3. 编译pano13的一些注意事项

    作者:朱金灿 来源:error C2037: "jmpbuf"的左侧部分指定未定义的结构/联合"png_struct_def"e:\src\Test\libpa ...

  4. Python IDLE如何清屏

    金gordon 原文 IDLE如何清屏 在学习和使用python的过程中,少不了要与Python IDLE打交道.但使用 Python IDLE 都会遇到一个常见而又懊恼的问题——要怎么清屏? 答案是 ...

  5. Lucene学习总结之四:Lucene索引过程分析 2014-06-25 14:18 884人阅读 评论(0) 收藏

    对于Lucene的索引过程,除了将词(Term)写入倒排表并最终写入Lucene的索引文件外,还包括分词(Analyzer)和合并段(merge segments)的过程,本次不包括这两部分,将在以后 ...

  6. Android 控件EditText的setOnEditorActionListener方法的理解

    需要注意的是 setOnEditorActionListener这个方法,并不是在我们点击EditText的时候触发,也不是在我们对EditText进行编辑时触发,而是在我们编辑完之后点击软键盘上的回 ...

  7. Spring之i18n配置与使用

    Spring的i18n配置: <!-- conf:i18n --> <bean id="messageSource" class="org.spring ...

  8. php课程 4-16 数组自定义函数(php数组->桶)

    php课程 4-16  数组自定义函数(php数组->桶) 一.总结 一句话总结:php的数组储存机制,和桶排序完美的结合.所以php的操作中多想多桶的操作. 二.数组自定义函数 1.相关知识 ...

  9. C++常用数据结构的实现

    常用数据结构与算法的实现.整理与总结 我将我所有数据结构的实现放在了github中:Data-Structures-Implemented-By-Me 常用数据结构与算法的实现.整理与总结 KMP字符 ...

  10. numpy tricks(二)—— 删除多维数组的行或列

    numpy.delete numpy 下的多维数组,如果要删除其中的某些行,或某些列,不可以用置空的方式,进行设置: A[1, :] = None, ⇒ 会将 A 中的第一行数据全部置为 Nan 1. ...