Пример #1
0
        private User32.MOUSEEVENTF MakeGestureBtnEvent(GestureTriggerButton btn, bool isUp, out uint data)
        {
            data = 0;
            switch (btn)
            {
            case GestureTriggerButton.Right:
                var isMouseSwapped = Native.IsMouseButtonSwapped();
                if (!isMouseSwapped)
                {
                    return(isUp ? User32.MOUSEEVENTF.MOUSEEVENTF_RIGHTUP : User32.MOUSEEVENTF.MOUSEEVENTF_RIGHTDOWN);
                }
                else
                {
                    return(isUp ? User32.MOUSEEVENTF.MOUSEEVENTF_LEFTUP : User32.MOUSEEVENTF.MOUSEEVENTF_LEFTDOWN);
                }

            case GestureTriggerButton.Middle:
                return(isUp ? User32.MOUSEEVENTF.MOUSEEVENTF_MIDDLEUP : User32.MOUSEEVENTF.MOUSEEVENTF_MIDDLEDOWN);

            case GestureTriggerButton.X1:
                data = 1;
                return(isUp ? User32.MOUSEEVENTF.MOUSEEVENTF_XUP : User32.MOUSEEVENTF.MOUSEEVENTF_XDOWN);

            case GestureTriggerButton.X2:
                data = 2;
                return(isUp ? User32.MOUSEEVENTF.MOUSEEVENTF_XUP : User32.MOUSEEVENTF.MOUSEEVENTF_XDOWN);

            default:
                Debug.Assert(false, "WTF");
                return(User32.MOUSEEVENTF.MOUSEEVENTF_ABSOLUTE);
            }
        }
Пример #2
0
        public static string ToMnemonic(this GestureTriggerButton gestureBtn)
        {
            switch (gestureBtn)
            {
            case GestureTriggerButton.Middle:
                return("●");

            case GestureTriggerButton.Right:
                return("◑");

            case GestureTriggerButton.X1:
                return("X1");

            case GestureTriggerButton.X2:
                return("X2");

            default:
                return(string.Empty);
            }
        }
Пример #3
0
        //NOTE: hook procs run in a separate thread.
        private void MouseHookProc(MouseKeyboardHook.MouseHookEventArgs e)
        {
            //处理 左键 + 中键 用于 暂停继续的情形
            if (HandleSpecialButtonCombination(e))
            {
                return;
            }
            if (_isPaused)
            {
                return;
            }

            var mouseData = (Native.MSLLHOOKSTRUCT)Marshal.PtrToStructure(e.lParam, typeof(Native.MSLLHOOKSTRUCT));

            //fixme: 判断是否在模拟事件, 为什么不一定可靠?
            if (_simulatingInput || mouseData.dwExtraInfo.ToInt64() == SIMULATED_EVENT_TAG)
            {
                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:
            case MouseMsg.WM_XBUTTONDOWN:
                if (!_captured)
                {
                    if (m == MouseMsg.WM_MBUTTONDOWN && (TriggerButton & GestureTriggerButton.Middle) == 0 ||
                        m == MouseMsg.WM_RBUTTONDOWN && (TriggerButton & GestureTriggerButton.Right) == 0 ||
                        m == MouseMsg.WM_XBUTTONDOWN && (TriggerButton & GestureTriggerButton.X) == 0)
                    {
                        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);
                        switch (m)    //TODO: extract function
                        {
                        case MouseMsg.WM_RBUTTONDOWN:
                            _gestureBtn = GestureTriggerButton.Right;
                            break;

                        case MouseMsg.WM_MBUTTONDOWN:
                            _gestureBtn = GestureTriggerButton.Middle;
                            break;

                        case MouseMsg.WM_XBUTTONDOWN:
                            var x = (XButtonNumber)(mouseData.mouseData >> 16);         //which X Button
                            _gestureBtn = x == XButtonNumber.One ? GestureTriggerButton.X1 : GestureTriggerButton.X2;
                            break;

                        default:
                            Debug.Assert(false, "WTF! shouldn't happen");
                            break;
                        }

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

                    switch (m)               //TODO: extract function
                    {
                    case MouseMsg.WM_RBUTTONDOWN:
                        gestMod = GestureModifier.RightButtonDown;
                        break;

                    case MouseMsg.WM_MBUTTONDOWN:
                        gestMod = GestureModifier.MiddleButtonDown;
                        break;

                    case MouseMsg.WM_XBUTTONDOWN:
                        var x = (XButtonNumber)(mouseData.mouseData >> 16);         //which X Button
                        gestMod = x == XButtonNumber.One ? GestureModifier.X1 : GestureModifier.X2;
                        break;

                    default:
                        gestMod = GestureModifier.LeftButtonDown;
                        break;
                    }

                    e.Handled = HandleModifier(gestMod);
                }
                break;

            case MouseMsg.WM_MOUSEMOVE:
                if (_captured)
                {
                    //永远不拦截move消息,所以不设置e.Handled = true
                    Post(WM.GESTBTN_MOVE);
                }
                else
                {
                    if (_isVirtualGesturing)
                    {
                        //忽略禁用列表
                        OnBeforePathStart();
                        _captured   = true;
                        _gestureBtn = GestureTriggerButton.Right;
                        Post(WM.GESTBTN_DOWN, 1);
                    }
                    //未捕获的情况下才允许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:
            case MouseMsg.WM_XBUTTONUP:
                if (_captured)
                {
                    var gestBtn_as_MouseMsg = (MouseMsg)(-1);
                    switch (_gestureBtn)
                    {
                    case GestureTriggerButton.Middle:
                        gestBtn_as_MouseMsg = MouseMsg.WM_MBUTTONUP;
                        break;

                    case GestureTriggerButton.Right:
                        gestBtn_as_MouseMsg = MouseMsg.WM_RBUTTONUP;
                        break;

                    case GestureTriggerButton.X1:
                    case GestureTriggerButton.X2:
                        gestBtn_as_MouseMsg = MouseMsg.WM_XBUTTONUP;
                        break;
                    }

                    //是手势键up
                    if (m == gestBtn_as_MouseMsg)
                    {
                        _captured = false;
                        Post(WM.GESTBTN_UP);
                    }

                    e.Handled = true;
                }
                break;

            default:
                //其他消息不处理
                break;
            }
        }
Пример #4
0
 public Gesture(GestureTriggerButton gestureBtn = GestureTriggerButton.Right, int defaultCapacity = 16)
 {
     GestureButton = gestureBtn;
     Dirs          = new List <GestureDir>(defaultCapacity);
     Modifier      = GestureModifier.None;
 }