Ejemplo n.º 1
0
        public Win32MousePathTracker2()
        {
            var dpiFactor = Native.GetScreenDpi() / 96.0f;

            //properties defaults
            TriggerButton            = /*GestureButtons.RightButton |*/ GestureTriggerButton.Middle;
            InitialValidMove         = (int)(5 * dpiFactor);
            InitialStayTimeout       = true;
            InitialStayTimeoutMillis = 150;

            EffectiveMove            = (int)(10 * dpiFactor) * 2; //todo: 增加灵敏度调整
            StepSize                 = EffectiveMove / 2;         // (int) (EffectiveMove * 0.8 * dpiFactor);// EffectiveMove/8;
            StayTimeout              = false;
            PerformNormalWhenTimeout = false;

            _mouseHook = new MouseHook();
            _mouseHook.MouseHookEvent += HookProc;
        }
Ejemplo n.º 2
0
        public Win32MousePathTracker2()
        {
            //properties defaults
            //GestureButton = GestureButtons.RightButton;
            InitialValidMove         = 10;
            InitialStayTimeout       = true;
            InitialStayTimeoutMillis = 150;

            EffectiveMove            = 20;
            StayTimeout              = false;
            PerformNormalWhenTimeout = false;

            _mouseHook = new MouseHook();
            _mouseHook.MouseHookEvent += HookProc;
            //_mouseHook.GotMessage += HookGotMessage;

#if DEBUG
            _monitoringHook.MouseHookEvent += args =>
            {
                //Debug.Write("M");
            };
            _monitoringHook.Install();
#endif
        }
Ejemplo n.º 3
0
        public Win32MousePathTracker2()
        {
            var dpiFactor = Native.GetScreenDpi()/96.0f;

            //properties defaults
            TriggerButton = /*GestureButtons.RightButton |*/ GestureTriggerButton.Middle;
            InitialValidMove = (int)(5 * dpiFactor);
            InitialStayTimeout = true;
            InitialStayTimeoutMillis = 150;

            EffectiveMove = (int)(10 * dpiFactor) * 2;//todo: 增加灵敏度调整
            StepSize = (int) (2*dpiFactor);// EffectiveMove/8;
            StayTimeout = false;
            PerformNormalWhenTimeout = false;

            _mouseHook = new MouseHook();
            _mouseHook.MouseHookEvent += HookProc;
        }
Ejemplo n.º 4
0
        private void HookProc(MouseHook.MouseHookEventArgs e)
        {
            //处理 左键 + 中键 用于 暂停继续的情形
            if (!_captured && e.Msg == MouseMsg.WM_MBUTTONDOWN)
            {
                var mouseSwapped = Native.GetSystemMetrics(Native.SystemMetric.SM_SWAPBUTTON) != 0;
                var lButtonPressed = Native.GetAsyncKeyState(mouseSwapped ? Keys.RButton : Keys.LButton) < 0;
                var shiftPressed = Native.GetAsyncKeyState(Keys.ShiftKey) < 0;

                if (lButtonPressed)
                {
                    if (shiftPressed)
                    {
                        Post(WM.GUI_REQUEST, (int)GUI_RequestType.ShowHideTray);
                    }
                    else
                    {
                        Post(WM.GUI_REQUEST, (int)GUI_RequestType.PauseResume);
                    }

                    return;
                }
            }

            if (_isPaused) return;

            var mouseData = (Native.MSLLHOOKSTRUCT)Marshal.PtrToStructure(e.lParam, typeof(Native.MSLLHOOKSTRUCT));
            //fixme: 判断是否在模拟事件, 为什么不一定可靠?
            if (_simulatingMouse || mouseData.dwExtraInfo.ToInt64() == MOUSE_EVENT_EXTRA_SIMULATED)
            {
                Debug.WriteLine("Simulated:" + e.Msg);
                if (InitialStayTimeout && _isInitialTimeout)
                {
                    Debug.WriteLine("_captured=false");
                    _captured = false;
                }
                return;
            }

            var prevPos = _curPos;
            _curPos = new Point(e.X, e.Y);

            var m = e.Msg;
            switch (m)
            {
                //必须在这里立即决定是否应该捕获
                case MouseMsg.WM_RBUTTONDOWN:
                case MouseMsg.WM_MBUTTONDOWN:
                    if (!_captured)
                    {
                        if (m == MouseMsg.WM_MBUTTONDOWN && (TriggerButton & GestureTriggerButton.Middle) != GestureTriggerButton.Middle
                            || m == MouseMsg.WM_RBUTTONDOWN && (TriggerButton & GestureTriggerButton.Right) != GestureTriggerButton.Right)
                        {
                            return;
                        }
                        try
                        {
                            //notice: 这个方法在钩子线程中运行,因此必须足够快,而且不能失败
                            _captured = OnBeforePathStart();
                        }
                        catch (Exception ex)
                        {
            #if DEBUG
                            throw;
            #endif
                            //如果出错,则不捕获手势
                            _captured = false;
                        }

                        if (_captured)
                        {
                            _gestureBtn = (m == MouseMsg.WM_RBUTTONDOWN ? GestureButtons.RightButton : GestureButtons.MiddleButton);

                            _modifierEventHappendPrevTime = new DateTime(0);
                            e.Handled = true;
                            //Console.WriteLine("Down");
                            Post(WM.GESTBTN_DOWN);
                        }
                    }
                    else //另一个键作为手势键的时候,作为修饰键
                    {
                        var gestMod = m == MouseMsg.WM_RBUTTONDOWN ? GestureModifier.RightButtonDown : GestureModifier.MiddleButtonDown;
                        e.Handled = HandleModifier(gestMod);
                    }
                    break;

                case MouseMsg.WM_MOUSEMOVE:
                    if (_captured)
                    {
                        //永远不拦截move消息,所以不设置e.Handled = true
                        Post(WM.GESTBTN_MOVE);
                    }
                    else //未捕获的情况下才允许hotcorner
                    {
                        HotCornerHitTest();
                    }

                    break;

                case MouseMsg.WM_MOUSEWHEEL:
                    if (_captured)
                    {
                        //获得滚动方向
                        int delta = (short)(mouseData.mouseData >> 16);
                        var gestMod = delta > 0 ? GestureModifier.WheelForward : GestureModifier.WheelBackward;

                        e.Handled = HandleModifier(gestMod);
                    }
                    else if (DateTime.UtcNow - _modifierEventHappendPrevTime < TimeSpan.FromMilliseconds(300))//延迟一下,因为 中键手势 + 滚动,可能导致快捷键还没结束,而滚轮事件发送到了目标窗口,可鞥解释成其他功能(比如ctrl + 滚轮 = 缩放)
                    {
                        e.Handled = true;
                    }
                    break;

                case MouseMsg.WM_LBUTTONDOWN:
                    if (_captured)
                    {
                        e.Handled = HandleModifier(GestureModifier.LeftButtonDown);
                    }
                    break;

                case MouseMsg.WM_RBUTTONUP:
                case MouseMsg.WM_MBUTTONUP:
                    if (_captured)
                    {
                        //是手势键up
                        if (m == (_gestureBtn == GestureButtons.RightButton ? MouseMsg.WM_RBUTTONUP : MouseMsg.WM_MBUTTONUP))
                        {
                            _captured = false;

                            //起始没有移动足够距离
                            /*if (!_initialMoveValid)
                            {
                                //Note: 在hook线程里面模拟点击, 行为不可预测。
                                Debug.WriteLine("Simulating Click");
                                Post(WM.SIMULATE_MOUSE, (int) GestureBtnEventType.CLICK);
                                /*new Thread(() =>
                                {
                                    SimulateGestureBtnEvent(GestureBtnEventType.CLICK, _curPos.X, _curPos.Y);
                                }).Start();*/
                                //SimulateGestureBtnEvent(GestureBtnEventType.UP, _curPos.X, _curPos.Y);

                                //SimulateGestureBtnEvent(GestureBtnEventType.CLICK, _curPos.X, _curPos.Y);
                                //e.Handled = true;
                                //Thread.Sleep(50);
                            //}
                            //else
                            {
                                e.Handled = true;
                                Post(WM.GESTBTN_UP);
                            }
                        }
                    }

                    break;

                default:
                    //其他消息不处理
                    //e.Handled = false;
                    break;
            }
        }