Exemple #1
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,
                    });
                }
            }
        }
Exemple #2
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,
                    });
                }
            }
        }