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); }
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, }); }
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); }
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, }); } } }
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); }