【问题标题】:Trapping mouse on one monitor在一台显示器上捕获鼠标
【发布时间】:2014-09-16 22:57:42
【问题描述】:

我有一个 Windows 系统,它连接了多个显示器作为扩展桌面。只有主监视器对用户来说是物理可见的,所以我想将鼠标困在那个监视器上。

似乎有一个使用 ClipMouse API 函数的简单解决方案,如trap-mouse-in-wpf 中所述:

[DllImport("user32.dll")]
static extern void ClipCursor(ref System.Drawing.Rectangle rect);

private void TrapMouse()
        {
            System.Drawing.Rectangle r = new System.Drawing.Rectangle(x, y, width, height);
            ClipCursor(ref r);
        }

但是,鼠标很容易挣脱,例如使用 alt-tab 更改程序或触摸辅助触摸屏之一时。

有什么方法可以在一台显示器上可靠且永久地捕获鼠标?

【问题讨论】:

    标签: .net mouse multiple-monitors


    【解决方案1】:

    您可以尝试以下一些简单的 Windows 窗体代码。它使用 SetWindowsHookEx 函数设置全局鼠标挂钩。在钩子方法中,它检查鼠标坐标是否在主屏幕的范围内,并在必要时调整坐标。当您运行此代码时,只要您只是移动鼠标,鼠标光标仍然能够离开主屏幕区域,但是一旦发生单击事件,它就会跳回来。您可能希望将我的代码与您的 ClipCursor 技术结合起来以防止这种情况发生。

    public partial class Form1 : Form
    {
        private const int WH_MOUSE_LL = 14;
    
        private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    
        [DllImport("user32.dll", EntryPoint = "SetWindowsHookEx", SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
    
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
    
        Rectangle _ScreenBounds;
    
        HookProc _HookProc;
    
        public Form1()
        {
            InitializeComponent();
    
            _ScreenBounds = Screen.PrimaryScreen.Bounds;
            _HookProc = HookMethod;
            IntPtr hook = SetWindowsHookEx(WH_MOUSE_LL, _HookProc, GetModuleHandle("user32"), 0);
            if (hook == IntPtr.Zero) throw new System.ComponentModel.Win32Exception();
        }
    
        private int HookMethod(int code, IntPtr wParam, IntPtr lParam)
        {
            if (Cursor.Position.X < _ScreenBounds.Left)
            {
                Cursor.Position = new Point(_ScreenBounds.Left, Cursor.Position.Y);
            }
            else if (Cursor.Position.X > _ScreenBounds.Right)
            {
                Cursor.Position = new Point(_ScreenBounds.Right - 1, Cursor.Position.Y);
            }
    
            if (Cursor.Position.Y < _ScreenBounds.Top)
            {
                Cursor.Position = new Point(Cursor.Position.X, _ScreenBounds.Top);
            }
            else if (Cursor.Position.Y > _ScreenBounds.Bottom)
            {
                Cursor.Position = new Point(Cursor.Position.X, _ScreenBounds.Bottom - 1);
            }
    
            return 0;
        }
    }
    

    【讨论】:

    • 感谢这个 sn-p!我们玩弄了它,但由于它只有在按下或释放鼠标按钮后才会启动,它并不能真正解决我们的问题。所以我必须继续寻找其他东西。
    猜你喜欢
    • 2012-10-08
    • 2010-11-19
    • 1970-01-01
    • 2010-12-26
    • 2011-08-30
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多