Ejemplo n.º 1
0
        internal void OnMouseInputReceived(object sender, Model.Input.MouseInput e)
        {
            // do not forward mouse-move events to extensions (they are unecessary, and it wastes cpu)
            // TODO: consider dispatching on a 'tile-snapped' basis, if 'tile under cursor' would change, dispatch a single update
            if (e.WM == WinAPI.WM.MOUSEMOVE)
            {
                return;
            }

            // TODO: consider queued mouse input instead of spawning a new task fro every event
            Task.Factory.StartNew(delegate()
            {
                // translate input
                var client = GetClientByHandle(e.WindowHandle) ?? GetActiveClient();

                // dispatch to extensions
                _extensions.Values.ToList()
                .ForEach(ext =>
                {
                    try
                    {
                        var L_e = new Extensibility.Input.MouseEventArgs
                        {
                            Client     = client,
                            Handled    = e.Handled,
                            Time       = e.Time,
                            IsAbsolute = e.IsAbsolute,
                            X          = e.Point.X,
                            Y          = e.Point.Y,
                            WM         = e.WM,
                            Flags      = e.Flags,
                        };
                        ext.Bridge.Mouse.OnInputReceived(client, L_e);
                        e.Handled = e.Handled || L_e.Handled;
                    }
                    catch (Exception ex)
                    {
                        ex.Log();
                    }
                });
            }, TaskCreationOptions.PreferFairness);
        }
Ejemplo n.º 2
0
        private void OnMouseInputReceived(Model.Input.MouseInput mouseInput)
        {
            //bool useTIQ = true; //TODO: this needs test and reverification of semantics/rules because it does not appear to allow mouse broadcast

            // translate message and track MK changes
            //WinAPI.WM wm = WinAPI.WM.USER;
            //bool isButtonUpEvent = false;

            // strip 'absolute' flag from mask and process result

            // denormalize coordinates to local
            //WinAPI.Windows.RECT clientRect;
            //WinAPI.Windows.GetClientRect(WindowHandle, out clientRect);
            //int lPointX = (int)(((double)clientRect.Width / (double)65536) * mouseInput.Point.X);
            //int lPointY = (int)(((double)clientRect.Height / (double)65536) * mouseInput.Point.Y);

            // TODO: the X and Y coordinates here should be "relative" -- might want to dig up the old "mrel" code -- it doesnt matter if we xlate coordinates to client area/pixels or not

            InputManager.Enqueue(mouseInput);

            /* superceded by InputManager (above)
             * // no target window? can't use
             * if (WindowHandle == IntPtr.Zero)
             * {
             *  ("NoWindowHandle Failed OnMouseInputReceived, Input Loss for " + this.DisplayName).Log();
             *  return;
             * }
             *
             * lock (_tiqLock)
             * {
             *  if (useTIQ)
             *  {
             *      // can't resolve TIQ? can't use
             *      IntPtr windowInputQueue = WindowInputQueue;
             *      if (windowInputQueue == IntPtr.Zero)
             *      {
             *          ("NoWindowInputQueue Failed OnMouseInputReceived, Input Loss for " + this.DisplayName).Log();
             *          useTIQ = false;
             *      }
             *      else
             *      {
             *          // resolve TIQ
             *          IntPtr foregroundWindowHandle;
             *          IntPtr foregroundInputQueue;
             *          if (!TryResolveTIQ(out foregroundInputQueue, out foregroundWindowHandle, DateTime.Now.AddMilliseconds(300).Ticks))
             *          {
             *              ("TryResolveTIQ Failed OnMouseInputReceived, Input Loss for " + this.DisplayName).Log();
             *              useTIQ = false;
             *          }
             *          else
             *          {
             *              ActionViaTIQ(() =>
             *              {
             *                  //WinAPI.SendInputApi.MouseActionViaSendInput(mouseInput.Flags, mouseInput.Time, (int)mouseInput.Point.X, (int)mouseInput.Point.Y, mouseInput.MouseData);
             *                  MouseActionViaPostMessage((int)mouseInput.Point.X, (int)mouseInput.Point.Y, lPointX, lPointY, wm, mouseInput.MouseData, isButtonUpEvent);
             *              },
             *                  foregroundInputQueue, "OnMouseInputReceived");
             *          }
             *      }
             *  }
             *
             *  if (!useTIQ)
             *  {
             *      // dispatch
             *      MouseActionViaSendMessage((int)mouseInput.Point.X, (int)mouseInput.Point.Y, lPointX, lPointY, wm, mouseInput.MouseData, isButtonUpEvent);
             *  }
             * }
             */
        }
Ejemplo n.º 3
0
        private void OnMouseInputReceived(Model.Input.MouseInput mouseInput)
        {
            bool useVIQ = (Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_ABSOLUTE == (mouseInput.Flags & Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_ABSOLUTE));

            // translate message and track MK changes
            Win32.WM wm = Win32.WM.USER;
            bool     isButtonUpEvent = false;
            ushort   wheelDelta      = 0;

            Win32.SendInputApi.MouseEventFlags lFlags = useVIQ
                ? mouseInput.Flags ^ Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_ABSOLUTE
                : mouseInput.Flags;
            switch (lFlags)
            {
            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_MOVE:
                wm = Win32.WM.MOUSEMOVE;
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_LEFTDOWN:
                wm         = Win32.WM.LBUTTONDOWN;
                CurrentMK |= Win32.Windows.MK.MK_LBUTTON;
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_LEFTUP:
                wm = Win32.WM.LBUTTONUP;
                isButtonUpEvent = true;
                CurrentMK       = (CurrentMK | Win32.Windows.MK.MK_LBUTTON) ^ Win32.Windows.MK.MK_LBUTTON;
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_RIGHTDOWN:
                wm         = Win32.WM.RBUTTONDOWN;
                CurrentMK |= Win32.Windows.MK.MK_RBUTTON;
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_RIGHTUP:
                wm              = Win32.WM.RBUTTONUP;
                CurrentMK       = (CurrentMK | Win32.Windows.MK.MK_RBUTTON) ^ Win32.Windows.MK.MK_RBUTTON;
                isButtonUpEvent = true;
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_MIDDLEDOWN:
                wm         = Win32.WM.MBUTTONDOWN;
                CurrentMK |= Win32.Windows.MK.MK_MBUTTON;
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_MIDDLEUP:
                wm              = Win32.WM.MBUTTONUP;
                CurrentMK       = (CurrentMK | Win32.Windows.MK.MK_MBUTTON) ^ Win32.Windows.MK.MK_MBUTTON;
                isButtonUpEvent = true;
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_XDOWN:
                wm = Win32.WM.XBUTTONDOWN;
                {
                    var xbutton = Win32.MACROS.GET_XBUTTON_WPARAM(mouseInput.MouseData);
                    wheelDelta = (ushort)xbutton;
                    switch (xbutton)
                    {
                    case Win32.MACROS.XBUTTONS.XBUTTON1:
                        CurrentMK |= Win32.Windows.MK.MK_XBUTTON1;
                        break;

                    case Win32.MACROS.XBUTTONS.XBUTTON2:
                        CurrentMK |= Win32.Windows.MK.MK_XBUTTON2;
                        break;

                    default:
                        Debug.WriteLine("UnsupportedButtonDown in MouseData(" + xbutton + ") for " + this.DisplayName);
                        break;
                    }
                }
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_XUP:
                wm = Win32.WM.XBUTTONUP;
                isButtonUpEvent = true;
                {
                    var xbutton = Win32.MACROS.GET_XBUTTON_WPARAM(mouseInput.MouseData);
                    wheelDelta = (ushort)xbutton;
                    switch (xbutton)
                    {
                    case Win32.MACROS.XBUTTONS.XBUTTON1:
                        CurrentMK = (CurrentMK | Win32.Windows.MK.MK_XBUTTON1) ^ Win32.Windows.MK.MK_XBUTTON1;
                        break;

                    case Win32.MACROS.XBUTTONS.XBUTTON2:
                        CurrentMK = (CurrentMK | Win32.Windows.MK.MK_XBUTTON2) ^ Win32.Windows.MK.MK_XBUTTON2;
                        break;

                    default:
                        Debug.WriteLine("UnsupportedButtonUp in MouseData(" + xbutton + ") for " + this.DisplayName);
                        break;
                    }
                }
                break;

            case Win32.SendInputApi.MouseEventFlags.MOUSEEVENTF_WHEEL:
                wheelDelta = Win32.MACROS.HIWORD(mouseInput.MouseData);
                wm         = Win32.WM.MOUSEWHEEL;
                break;

            default:
                return;
            }

            mouseInput.MouseData = Win32.MACROS.MAKEWPARAM((ushort)CurrentMK, wheelDelta);
            // only use VIQ for "mouse clone" events
            if (!useVIQ)
            {
                Win32.SendInputApi.SendInputViaMSParams(mouseInput.Flags, mouseInput.Time, (int)mouseInput.Point.X, (int)mouseInput.Point.Y, mouseInput.MouseData);
                return;
            }

            // no target window? can't use
            if (WindowHandle == IntPtr.Zero)
            {
                Debug.WriteLine("NoWindowHandle Failed OnMouseInputReceived, Input Loss for " + this.DisplayName);
                return;
            }

            // can't resolve VIQ? can't use
            IntPtr windowInputQueue = WindowInputQueue;

            if (windowInputQueue == IntPtr.Zero)
            {
                Debug.WriteLine("NoWindowInputQueue Failed OnMouseInputReceived, Input Loss for " + this.DisplayName);
                return;
            }

            // denormalize coordinates
            Win32.Windows.RECT clientRect;
            Win32.Windows.GetClientRect(WindowHandle, out clientRect);
            int lPointX = (int)(((double)clientRect.Width / (double)65536) * mouseInput.Point.X);
            int lPointY = (int)(((double)clientRect.Height / (double)65536) * mouseInput.Point.Y);

            // prep action
            Action action = () =>
            {
                Debug.WriteLine("MouseVIQAction for " + this.DisplayName);
                OnMouseEvent_Action((int)mouseInput.Point.X, (int)mouseInput.Point.Y, lPointX, lPointY, wm, mouseInput.MouseData, isButtonUpEvent);
            };

            // resolve VIQ
            IntPtr foregroundWindowHandle;
            IntPtr foregroundInputQueue;

            if (!TryResolveViq(out foregroundInputQueue, out foregroundWindowHandle, DateTime.Now.AddMilliseconds(1000).Ticks))
            {
                Debug.WriteLine("TryResolveVIQ Failed OnMouseInputReceived, Input Loss for " + this.DisplayName);
                return;
            }

            ActionViaViq(action, foregroundInputQueue, "OnMouseInputReceived");
        }