示例#1
0
        private static bool OnMouseInputReceived(WinAPI.WM wm, WinAPI.WindowHook.MSLLHOOKSTRUCT hookStruct)
        {
            // ignore injected input
            if (hookStruct.flags.HasFlag(WinAPI.WindowHook.LLMHF.INJECTED))
            {
                return(false);
            }

            MouseInput mouseInputEventArgs = MouseInput.CreateFrom(wm, hookStruct);

            if (Performance.IsPerformanceEnabled)
            {
                MouseInputPerformance.Count(Convert.ToInt64(mouseInputEventArgs.Time));
            }
            try
            {
                if (MouseInputReceived != null)
                {
                    MouseInputReceived(null, mouseInputEventArgs);
                    return(mouseInputEventArgs.Handled);
                }
            }
            catch (Exception ex)
            {
                ex.Log();
            }
            return(false);
        }
示例#2
0
 public static MouseInput CreateFrom(WinAPI.WM wm, Mubox.WinAPI.WindowHook.MSLLHOOKSTRUCT hookStruct)
 {
     return(new MouseInput
     {
         WM = wm,
         Point = new System.Windows.Point(hookStruct.pt.X, hookStruct.pt.Y),
         MouseData = hookStruct.mouseData,
         Time = hookStruct.time,
     });
 }
示例#3
0
        public static KeyboardInput CreateFrom(WinAPI.WM wParam, Mubox.WinAPI.WindowHook.KBDLLHOOKSTRUCT hookStruct)
        {
            KeyboardInput e = new KeyboardInput();

            e.VK    = hookStruct.vkCode;
            e.Scan  = hookStruct.scanCode;
            e.Flags = hookStruct.flags;
            e.Time  = hookStruct.time;
            e.WM    = wParam;
            return(e);
        }
        private static unsafe IntPtr MenuCallback(IntPtr wnd, WinAPI.WM msg, IntPtr wparam, IntPtr lparam)
        {
            WinAPI.IContextMenu2 contextMenu2;
            IntPtr result;

            switch (msg)
            {
            case WinAPI.WM.CREATE: {
                WinAPI.SetWindowLongPtr(wnd, WinAPI.GWL.GWL_USERDATA, ((WinAPI.CREATESTRUCT *)lparam)->lpCreateParams);
                result = WinAPI.DefWindowProc(wnd, msg, wparam, lparam);
            }
            break;

            case WinAPI.WM.INITMENUPOPUP: {
                contextMenu2 =
                    (WinAPI.IContextMenu2)Marshal.GetObjectForIUnknown(WinAPI.GetWindowLongPtr(wnd, WinAPI.GWL.GWL_USERDATA));
                contextMenu2.HandleMenuMsg((uint)msg, wparam, lparam);
                result = IntPtr.Zero;
            }
            break;

            case WinAPI.WM.DRAWITEM:
            case WinAPI.WM.MEASUREITEM: {
                contextMenu2 =
                    (WinAPI.IContextMenu2)Marshal.GetObjectForIUnknown(WinAPI.GetWindowLongPtr(wnd, WinAPI.GWL.GWL_USERDATA));
                contextMenu2.HandleMenuMsg((uint)msg, wparam, lparam);
                result = IntPtr.Zero + 1;
            }
            break;

            default:
                result = WinAPI.DefWindowProc(wnd, msg, wparam, lparam);
                break;
            }
            return(result);
        }
示例#5
0
        private void Process(KeyboardInput keyboardInput)
        {
            if (!UpdatePressedKeys(keyboardInput.VK, keyboardInput.Scan, keyboardInput.Flags, keyboardInput.Time))
            {
                return;
            }

            switch ((WinAPI.VK)keyboardInput.VK)
            {
            case WinAPI.VK.Control:
            case WinAPI.VK.LeftControl:
            case WinAPI.VK.RightControl:
                if ((keyboardInput.Flags & WinAPI.WindowHook.LLKHF.UP) == WinAPI.WindowHook.LLKHF.UP)
                {
                    CurrentMK = (CurrentMK | WinAPI.Windows.MK.MK_CONTROL) ^ WinAPI.Windows.MK.MK_CONTROL;
                }
                else
                {
                    CurrentMK |= WinAPI.Windows.MK.MK_CONTROL;
                }
                break;

            case WinAPI.VK.Shift:
            case WinAPI.VK.LeftShift:
            case WinAPI.VK.RightShift:
                if ((keyboardInput.Flags & WinAPI.WindowHook.LLKHF.UP) == WinAPI.WindowHook.LLKHF.UP)
                {
                    CurrentMK = (CurrentMK | WinAPI.Windows.MK.MK_SHIFT) ^ WinAPI.Windows.MK.MK_SHIFT;
                }
                else
                {
                    CurrentMK |= WinAPI.Windows.MK.MK_CONTROL;
                }
                break;
            }

            var vk    = keyboardInput.VK;
            var flags = keyboardInput.Flags;
            var scan  = keyboardInput.Scan;
            var time  = keyboardInput.Time;
            var cas   = keyboardInput.CAS;

            var wParam = (uint)vk;

            WinAPI.WM wm     = (((flags & WinAPI.WindowHook.LLKHF.UP) == WinAPI.WindowHook.LLKHF.UP) ? WinAPI.WM.KEYUP : WinAPI.WM.KEYDOWN);         // TODO SYSKEYDOWN via Win32.WindowHook.LLKHF.AltKey ?
            uint      lParam = 0x01;

            if (wm == WinAPI.WM.KEYUP)
            {
                lParam |= 0xC0000000;                 // TODO: this may need to change on 64bit platforms, not clear
            }

            uint scanCode = scan;

            if (scanCode > 0)
            {
                lParam |= ((scanCode & 0xFF) << 16);                 // TODO: this may need to change on 64bit platforms, not clear
            }

            if ((flags & WinAPI.WindowHook.LLKHF.UP) != WinAPI.WindowHook.LLKHF.UP)
            {
                // async Win32.GetKeyboardState or similar to capture actual/current CAS states
                if ((cas & WinAPI.CAS.CONTROL) != 0)
                {
                    Process(new KeyboardInput
                    {
                        VK    = WinAPI.VK.Control,
                        Flags = (WinAPI.WindowHook.LLKHF) 0,
                        Scan  = (uint)WinAPI.SendInputApi.MapVirtualKey(WinAPI.VK.Control, WinAPI.SendInputApi.MAPVK.MAPVK_VK_TO_VSC),
                        Time  = time,
                        CAS   = (WinAPI.CAS) 0,
                    });
                }
                if ((cas & WinAPI.CAS.ALT) != 0)
                {
                    Process(new KeyboardInput
                    {
                        VK    = WinAPI.VK.Menu,
                        Flags = (WinAPI.WindowHook.LLKHF) 0,
                        Scan  = (uint)WinAPI.SendInputApi.MapVirtualKey(WinAPI.VK.Menu, WinAPI.SendInputApi.MAPVK.MAPVK_VK_TO_VSC),
                        Time  = time,
                        CAS   = (WinAPI.CAS) 0,
                    });
                    flags |= WinAPI.WindowHook.LLKHF.ALTDOWN;
                }
                if ((cas & WinAPI.CAS.SHIFT) != 0)
                {
                    Process(new KeyboardInput
                    {
                        VK    = WinAPI.VK.Shift,
                        Flags = (WinAPI.WindowHook.LLKHF) 0,
                        Scan  = (uint)WinAPI.SendInputApi.MapVirtualKey(WinAPI.VK.Shift, WinAPI.SendInputApi.MAPVK.MAPVK_VK_TO_VSC),
                        Time  = time,
                        CAS   = (WinAPI.CAS) 0,
                    });
                }
            }

            // NOTE: some apps may actually rely on keyboard state, AttachInputThread will clobber keyboard state. now that we don't continually attach/detach we should be able to set keyboard correctly
            // TODO: this should be a game profile level option - some games exhibit 'double entry' of input when this is called
            WinAPI.SetKeyboardState(this.pressedKeys);

            /* REMOVED: key state becomes invalid for at least one game with this implemented - need to put it into an option if it needs to be re-added - was never noticed because for a while LeftMenu was not being translated into 'Menu' and this code was not executing
             * if (this.pressedKeys[(int)WinAPI.VK.Menu] == 0x80 || keyboardInput.VK == WinAPI.VK.Menu)
             * {
             * switch (wm)
             * {
             * case WinAPI.WM.KEYDOWN:
             * wm = WinAPI.WM.SYSKEYDOWN;
             * break;
             *
             * case WinAPI.WM.KEYUP:
             * wm = WinAPI.WM.SYSKEYUP;
             * break;
             * }
             * }
             * else
             * {
             * switch (wm)
             * {
             * case WinAPI.WM.SYSKEYDOWN:
             * wm = WinAPI.WM.KEYDOWN;
             * break;
             *
             * case WinAPI.WM.SYSKEYUP:
             * wm = WinAPI.WM.KEYUP;
             * break;
             * }
             * }
             */
            WinAPI.Windows.SendMessage(ClientWindowHandle, wm, new UIntPtr(wParam), new UIntPtr(lParam));

            // if keydown, translate message
            // TODO: this should be a game profile option - some games may exhibit 'double entry' of input when this is called, most games don't function correctly without it
            if (wm == WinAPI.WM.KEYDOWN || wm == WinAPI.WM.SYSKEYDOWN)
            {
                var msg = new WinAPI.Windows.MSG();
                msg.hwnd    = ClientWindowHandle;
                msg.lParam  = lParam;
                msg.message = wm;
                msg.pt      = new WinAPI.Windows.POINT();
                msg.time    = WinAPI.SendInputApi.GetTickCount();
                msg.wParam  = (int)vk;
                WinAPI.Windows.TranslateMessage(ref msg);
                //WinAPI.Windows.GetMessage(out msg, ClientWindowHandle, Mubox.WinAPI.WM.CHAR, WinAPI.WM.UNICHAR);
                //WinAPI.Windows.SendMessage(ClientWindowHandle, wm, new UIntPtr(wParam), new UIntPtr(lParam));
            }

            // TODO: this expression should probably be checking for == UP, but the individual key states need to be refactored to check current state first)
            // NOTE: if subsequent keys still rely on this state, it will be re-set as expected because of the sister CASE code above
            if ((flags & WinAPI.WindowHook.LLKHF.UP) != WinAPI.WindowHook.LLKHF.UP)
            {
                if ((cas & WinAPI.CAS.CONTROL) != 0)
                {
                    Process(new KeyboardInput
                    {
                        VK    = WinAPI.VK.Control,
                        Flags = WinAPI.WindowHook.LLKHF.UP,
                        Scan  = (uint)WinAPI.SendInputApi.MapVirtualKey(WinAPI.VK.Control, WinAPI.SendInputApi.MAPVK.MAPVK_VK_TO_VSC),
                        Time  = time,
                        CAS   = (WinAPI.CAS) 0,
                    });
                }
                if ((cas & WinAPI.CAS.ALT) != 0)
                {
                    Process(new KeyboardInput
                    {
                        VK    = WinAPI.VK.Menu,
                        Flags = WinAPI.WindowHook.LLKHF.UP,
                        Scan  = (uint)WinAPI.SendInputApi.MapVirtualKey(WinAPI.VK.Menu, WinAPI.SendInputApi.MAPVK.MAPVK_VK_TO_VSC),
                        Time  = time,
                        CAS   = (WinAPI.CAS) 0,
                    });
                }
                if ((cas & WinAPI.CAS.SHIFT) != 0)
                {
                    Process(new KeyboardInput
                    {
                        VK    = WinAPI.VK.Shift,
                        Flags = WinAPI.WindowHook.LLKHF.UP,
                        Scan  = (uint)WinAPI.SendInputApi.MapVirtualKey(WinAPI.VK.Shift, WinAPI.SendInputApi.MAPVK.MAPVK_VK_TO_VSC),
                        Time  = time,
                        CAS   = (WinAPI.CAS) 0,
                    });
                }
            }
        }
示例#6
0
        private static bool OnKeyboardInputReceived(WinAPI.WM wParam, WinAPI.WindowHook.KBDLLHOOKSTRUCT hookStruct)
        {
            // ignore injected input
            if (hookStruct.flags.HasFlag(WinAPI.WindowHook.LLKHF.INJECTED))
            {
                return(false);
            }

            // coerce specialized left/right shift-state to generalized shift-state
            if (MuboxConfigSection.Default.Profiles.ActiveProfile.EnableCASFix)
            {
                switch ((WinAPI.VK)hookStruct.vkCode)
                {
                case WinAPI.VK.LeftShift:
                case WinAPI.VK.RightShift:
                    hookStruct.vkCode = WinAPI.VK.Shift;
                    break;

                case WinAPI.VK.LeftMenu:
                case WinAPI.VK.RightMenu:
                    hookStruct.vkCode = WinAPI.VK.Menu;
                    break;

                case WinAPI.VK.LeftControl:
                case WinAPI.VK.RightControl:
                    hookStruct.vkCode = WinAPI.VK.Control;
                    break;
                }
            }

            // ignore "global desktop keys"
            Mubox.Configuration.KeySetting globalKeySetting = null;
            if (Mubox.Configuration.MuboxConfigSection.Default.Profiles.ActiveProfile.Keys.TryGetKeySetting((WinAPI.VK)hookStruct.vkCode, out globalKeySetting) && (globalKeySetting.SendToDesktop))
            {
                return(false);
            }

            // update pressed keys
            if (!UpdatePressedKeys(hookStruct) && Mubox.Configuration.MuboxConfigSection.Default.IsCaptureEnabled && !Mubox.Configuration.MuboxConfigSection.Default.DisableRepeatKeyFiltering)
            {
                return(true);
            }

            // count
            if (Performance.IsPerformanceEnabled)
            {
                KeyboardInputPerformance.Count(Convert.ToInt64(hookStruct.time));
            }

            // handle high-level
            if (KeyboardInputReceived != null)
            {
                KeyboardInput keyboardInputEventArgs = KeyboardInput.CreateFrom(wParam, hookStruct);
                {
                    Mubox.Configuration.KeySetting keySetting = globalKeySetting;
                    if (Mubox.Configuration.MuboxConfigSection.Default.Profiles.ActiveProfile != null)
                    {
                        Mubox.Configuration.ClientSettings activeClient = Mubox.Configuration.MuboxConfigSection.Default.Profiles.ActiveProfile.ActiveClient;
                        if (activeClient != null)
                        {
                            activeClient.Keys.TryGetKeySetting((WinAPI.VK)keyboardInputEventArgs.VK, out keySetting);
                        }
                        if (keySetting != null)
                        {
                            keyboardInputEventArgs.VK  = keySetting.OutputKey;
                            keyboardInputEventArgs.CAS = keySetting.OutputModifiers;
                        }
                    }
                }
                OnKeyboardInputReceivedInternal(keyboardInputEventArgs);
                return(keyboardInputEventArgs.Handled);
            }

            return(false);
        }