From 5e95937ae9f2662c835bce1f9c9da77d956aa183 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Tue, 26 Aug 2025 20:42:50 +0200 Subject: [PATCH] Implement alt to toggle to previous window(s) --- DD2Switcher/DD2Switcher.csproj | 1 + DD2Switcher/KeyboardHook.cs | 64 ++++++++++++++++++++++++++++++++++ DD2Switcher/Program.cs | 49 +++++++++++++------------- 3 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 DD2Switcher/KeyboardHook.cs diff --git a/DD2Switcher/DD2Switcher.csproj b/DD2Switcher/DD2Switcher.csproj index 35acb00..24f1ef7 100644 --- a/DD2Switcher/DD2Switcher.csproj +++ b/DD2Switcher/DD2Switcher.csproj @@ -57,6 +57,7 @@ Form1.cs + diff --git a/DD2Switcher/KeyboardHook.cs b/DD2Switcher/KeyboardHook.cs new file mode 100644 index 0000000..b2a2258 --- /dev/null +++ b/DD2Switcher/KeyboardHook.cs @@ -0,0 +1,64 @@ +using System; +using System.Diagnostics; +using System.Windows.Forms; +using System.Runtime.InteropServices; + +class KeyboardHook { + private const int WH_KEYBOARD_LL = 13; + private const int WM_KEYDOWN = 0x0104; + private const int WM_KEYUP = 0x0101; + private static LowLevelKeyboardProc _proc = HookCallback; + private static IntPtr _hookID = IntPtr.Zero; + + public static int previousEvent = 0; + public static event EventHandler KeyDown; + public static event EventHandler KeyUp; + + public static void Start() { + _hookID = SetHook(_proc); + } + + public static void Stop() { + UnhookWindowsHookEx(_hookID); + } + + private static IntPtr SetHook(LowLevelKeyboardProc proc) { + using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = + curProcess.MainModule) { + return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0); + } + } + + private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam); + + private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) { + if (nCode >= 0) { + int vkCode = Marshal.ReadInt32(lParam); + int pero = (int)wParam * 1000 + vkCode; + if (pero != previousEvent) { + if (wParam == (IntPtr)WM_KEYDOWN) { + KeyDown?.Invoke(null, vkCode); + } else if (wParam == (IntPtr)WM_KEYUP) { + KeyUp?.Invoke(null, vkCode); + } + previousEvent = pero; + } else { + Console.WriteLine("Same event"); + } + } + return CallNextHookEx(_hookID, nCode, wParam, lParam); + } + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + [return:MarshalAs(UnmanagedType.Bool)] + private static extern bool UnhookWindowsHookEx(IntPtr hhk); + + [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + private static extern IntPtr GetModuleHandle(string lpModuleName); +} \ No newline at end of file diff --git a/DD2Switcher/Program.cs b/DD2Switcher/Program.cs index dd4f075..fc1eb2b 100644 --- a/DD2Switcher/Program.cs +++ b/DD2Switcher/Program.cs @@ -13,10 +13,10 @@ namespace DD2Switcher { private static int ActiveIndex = -1; private static int PreviousIndex = -1; private static bool AltPressed = false; - private static Timer AltTimer; private static readonly IntPtr defaultAffinity = new(0xFF000000); private static readonly IntPtr fullAffinity = new(0xFFFFFFFF); + private static readonly KeyboardHook keyboardHook = new(); [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); @@ -151,6 +151,7 @@ namespace DD2Switcher { Console.WriteLine($"Added {process.ProcessName} to tracked windows at index {firstNullIndex}"); } + // TODO: Restore this // private static void TrackWows() { // CleanWindows(); // var processes = Process.GetProcesses().OrderBy(p => p.Id).ToList(); @@ -257,14 +258,6 @@ namespace DD2Switcher { } } - private static void OnAltTimer() { - if (AltPressed) { - AltPressed = false; - AltTimer.Stop(); - TabToPrevious(); - } - } - private static bool IsCapsLockOn() { return (GetKeyState(0x14) & 1) == 1; } @@ -282,10 +275,28 @@ namespace DD2Switcher { Process.GetCurrentProcess().Kill(); } - AltTimer = new Timer(OnAltTimer, null, Timeout.Infinite, Timeout.Infinite); + bool onlyAlt = false; + KeyboardHook.Start(); + KeyboardHook.KeyDown += (sender, e) => { + Console.WriteLine($"Key down: {e}"); + if (e == 164 && !onlyAlt) { + Console.WriteLine("Only alt"); + onlyAlt = true; + } else { + Console.WriteLine("Not only alt"); + onlyAlt = false; + } + }; + KeyboardHook.KeyUp += (sender, e) => { + Console.WriteLine($"Key up: {e}"); + if (e == 164 && onlyAlt) { // Left alt + Console.WriteLine("Tab to previous"); + onlyAlt = false; + TabToPrevious(); + } + }; HotKeyManager.RegisterHotKey(Keys.Capital, KeyModifiers.NoRepeat); - HotKeyManager.RegisterHotKey(Keys.Menu, KeyModifiers.NoRepeat); // Register main number keys (0-9) for (int i = 0; i < 10; i++) HotKeyManager.RegisterHotKey(Keys.D0 + i, KeyModifiers.Alt); @@ -301,17 +312,6 @@ namespace DD2Switcher { // return; // } - if (e.Key == Keys.Menu && e.Modifiers == KeyModifiers.NoRepeat) { - AltPressed = true; - AltTimer.Change(150, Timeout.Infinite); - return; - } - - if (e.Modifiers == KeyModifiers.Alt) { - AltPressed = false; - AltTimer.Stop(); - } - int index; if (e.Key >= Keys.D0 && e.Key <= Keys.D9) { index = e.Key - Keys.D0; @@ -330,8 +330,9 @@ namespace DD2Switcher { } } - Console.CancelKeyPress += (sender, e) => { Process.GetCurrentProcess().Kill(); }; - while (true) System.Threading.Thread.Sleep(100000); + // Console.CancelKeyPress += (sender, e) => { Process.GetCurrentProcess().Kill(); }; + Application.Run(); + KeyboardHook.Stop(); } } }