### Full Listing for Key Combination Detection Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md This comprehensive example demonstrates defining combinations, actions, assigning them, and installing the global event listener. ```CSharp //1. Define key combinations var undo = Combination.FromString("Control+Z"); var fullScreen = Combination.FromString("Shift+Alt+Enter"); //2. Define actions Action actionUndo = DoSomething; Action actionFullScreen = () => { Console.WriteLine("You Pressed FULL SCREEN"); }; void DoSomething() { Console.WriteLine("You pressed UNDO"); } //3. Assign actions to key combinations var assignment = new Dictionary { {undo, actionUndo}, {fullScreen, actionFullScreen} }; //4. Install listener Hook.GlobalEvents().OnCombination(assignment); ``` -------------------------------- ### Assign Actions and Start Listening for Combinations Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md Assign actions to key combinations using a dictionary and install the listener using `Hook.GlobalEvents().OnCombination`. Use `Hook.AppEvents()` to limit listening to the current application. ```CSharp var assignment = new Dictionary { {undo, actionUndo}, {fullScreen, actionFullScreen} }; Hook.GlobalEvents().OnCombination(assignment); ``` -------------------------------- ### Assign Actions and Start Listening for Sequences Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md Map sequences to actions using a dictionary and install the listener using `Hook.GlobalEvents().OnSequence`. The longest matching sequence will fire if there are overlaps. ```CSharp var assignment = new Dictionary { {exitVim, ()=>Console.WriteLine("No!")}, {rename, ()=>Console.WriteLine("rename2")}, {exitReally, ()=>Console.WriteLine("Ok.")}, }; Hook.GlobalEvents().OnSequence(assignment); ``` -------------------------------- ### Install MouseKeyHook via NuGet Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/README.md Use the nuget command-line tool to install the MouseKeyHook library. ```bash nuget install MouseKeyHook ``` -------------------------------- ### Subscribe to Key Combinations with OnCombination Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Sets up global keyboard shortcuts by mapping key combinations to specific actions. Supports defining actions directly or using method references. Includes examples for single keys, multi-key sequences, and combinations with modifiers. ```csharp using System; using System.Collections.Generic; using System.Windows.Forms; using Gma.System.MouseKeyHook; public class OnCombinationExample { public void SetupShortcuts() { // Define key combinations and their actions var shortcuts = new Dictionary { { Combination.FromString("Control+Z"), () => Console.WriteLine("Undo!") }, { Combination.FromString("Control+Shift+Z"), () => Console.WriteLine("Redo!") }, { Combination.FromString("Control+S"), () => Console.WriteLine("Save!") }, { Combination.FromString("Control+C"), () => Console.WriteLine("Copy!") }, { Combination.FromString("Control+V"), () => Console.WriteLine("Paste!") }, { Combination.FromString("Alt+F4"), () => Console.WriteLine("Close!") }, // Multi-key combinations (non-modifier keys) { Combination.FromString("A+B+C"), () => Console.WriteLine("ABC combo!") }, // Using builder API { Combination.TriggeredBy(Keys.F).With(Keys.E).With(Keys.D), () => Console.WriteLine("DEF combo!") }, // Single key as combination { Combination.FromString("Escape"), () => Console.WriteLine("Escape pressed!") } }; // Install the combination listener Hook.GlobalEvents().OnCombination(shortcuts); Console.WriteLine("Shortcuts active. Press combinations to trigger actions."); } // With reset action (called when non-matching key is pressed) public void SetupWithReset() { var shortcuts = new Dictionary { { Combination.FromString("Control+Z"), () => Console.WriteLine("Undo!") } }; Action resetAction = () => Console.WriteLine("Reset - unrecognized key"); Hook.GlobalEvents().OnCombination(shortcuts, resetAction); } // Compact inline setup public void CompactSetup() { Hook.GlobalEvents().OnCombination(new Dictionary { { Combination.FromString("Control+Z"), Undo }, { Combination.FromString("Control+S"), () => Save("document.txt") }, { Combination.FromString("Escape"), Application.Exit } }); } private void Undo() => Console.WriteLine("Undo action"); private void Save(string filename) => Console.WriteLine($"Saving {filename}"); } // Output when pressing Ctrl+Z: // Undo! ``` -------------------------------- ### Setup HotKeySet with Events Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Demonstrates creating a HotKeySet for Ctrl+Shift+A and subscribing to its DownOnce, DownHold, and Up events. The hot key set can be enabled or disabled. ```csharp using System; using System.Windows.Forms; using Gma.System.MouseKeyHook.HotKeys; public class HotKeySetExample { public void SetupHotKeySet() { // Create a HotKeySet for Ctrl+Shift+A var hotKeySet = new HotKeySet(new[] { Keys.Control, Keys.Shift, Keys.A }) { Name = "Select All Enhanced", Description = "Custom select all with modifiers" }; // Event fired once when all keys are first pressed together hotKeySet.OnHotKeysDownOnce += (sender, e) => { Console.WriteLine($"HotKey activated at {e.Time}"); Console.WriteLine("Performing action..."); }; // Event fired continuously while keys are held down hotKeySet.OnHotKeysDownHold += (sender, e) => { Console.WriteLine($"HotKey still held at {e.Time}"); }; // Event fired when keys are released (set becomes inactive) hotKeySet.OnHotKeysUp += (sender, e) => { Console.WriteLine($"HotKey released at {e.Time}"); }; // Check if currently activated Console.WriteLine($"Is activated: {hotKeySet.HotKeysActivated}"); // Enable/disable the hot key set hotKeySet.Enabled = true; } // Using exclusive-or for interchangeable keys public void SetupWithExclusiveOr() { // Allow either LShift or RShift var hotKeySet = new HotKeySet(new[] { Keys.T, Keys.LShiftKey, Keys.RShiftKey }); // Register LShiftKey and RShiftKey as interchangeable // Now pressing T+LShift OR T+RShift will both activate the set Keys primaryKey = hotKeySet.RegisterExclusiveOrKey( new[] { Keys.LShiftKey, Keys.RShiftKey }); Console.WriteLine($"Primary key for shift: {primaryKey}"); // LShiftKey hotKeySet.OnHotKeysDownOnce += (sender, e) => { Console.WriteLine("T + (any Shift) pressed!"); }; // Later, unregister if needed // hotKeySet.UnregisterExclusiveOrKey(Keys.LShiftKey); } } // Output when pressing Ctrl+Shift+A: // HotKey activated at 1/15/2024 10:30:45 AM // Performing action... // (while holding) // HotKey still held at 1/15/2024 10:30:45 AM // HotKey still held at 1/15/2024 10:30:46 AM // (on release) // HotKey released at 1/15/2024 10:30:46 AM ``` -------------------------------- ### Complete Global Hook Application in C# Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt This snippet demonstrates a full application setup for global mouse and keyboard hooks. It includes subscribing to events, registering key combinations and sequences, handling events, and proper cleanup. Ensure the 'System.Windows.Forms' namespace is available for 'Application.Run()'. ```csharp using System; using System.Collections.Generic; using System.Threading; using System.Windows.Forms; using Gma.System.MouseKeyHook; public class CompleteExample { private static IKeyboardMouseEvents s_GlobalHook; private static AutoResetEvent s_WaitHandle = new AutoResetEvent(false); public static void Main() { // Subscribe to global events Subscribe(); // Run message loop to receive Windows messages Console.WriteLine("Application started. Press Escape to exit."); Application.Run(); // Cleanup Unsubscribe(); Console.WriteLine("Application terminated."); } private static void Subscribe() { s_GlobalHook = Hook.GlobalEvents(); // Basic key logging s_GlobalHook.KeyPress += (sender, e) => { Console.Write(e.KeyChar); }; // Extended mouse events with suppression s_GlobalHook.MouseDownExt += (sender, e) => { Console.WriteLine($"\nMouse: {e.Button} at ({e.X}, {e.Y})"); // Suppress specific actions if (e.Button == MouseButtons.XButton1) { e.Handled = true; Console.WriteLine("XButton1 suppressed"); } }; // Key combinations var shortcuts = new Dictionary { { Combination.FromString("Control+Shift+M"), () => Console.WriteLine("\n[Mute toggled]") }, { Combination.FromString("Control+Shift+U"), () => Console.WriteLine("\n[Unmute toggled]") }, { Combination.FromString("Escape"), () => Application.Exit() } }; s_GlobalHook.OnCombination(shortcuts); // Key sequences var sequences = new Dictionary { { Sequence.FromString("Control+K,Control+C"), () => Console.WriteLine("\n[Code commented]") }, { Sequence.FromString("Control+K,Control+U"), () => Console.WriteLine("\n[Code uncommented]") } }; s_GlobalHook.OnSequence(sequences); Console.WriteLine("Shortcuts registered:"); Console.WriteLine(" Ctrl+Shift+M - Toggle mute"); Console.WriteLine(" Ctrl+Shift+U - Toggle unmute"); Console.WriteLine(" Ctrl+K, Ctrl+C - Comment code"); Console.WriteLine(" Ctrl+K, Ctrl+U - Uncomment code"); Console.WriteLine(" Escape - Exit application"); Console.WriteLine(" XButton1 - Suppressed (won't reach other apps)"); Console.WriteLine(); } private static void Unsubscribe() { s_GlobalHook?.Dispose(); } } ``` -------------------------------- ### Subscribe to Extended Mouse Events Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Subscribe to extended mouse events to get additional data like timestamps and button states. Set e.Handled = true to suppress events from reaching other applications. ```csharp using System; using System.Windows.Forms; using Gma.System.MouseKeyHook; public class ExtendedMouseEventsExample { public void Subscribe() { var hook = Hook.GlobalEvents(); // Extended MouseDown event with suppression capability hook.MouseDownExt += (sender, e) => { Console.WriteLine($"MouseDownExt: {e.Button}"); Console.WriteLine($" Position: ({e.X}, {e.Y})"); Console.WriteLine($" Timestamp: {e.Timestamp}"); Console.WriteLine($" IsMouseButtonDown: {e.IsMouseButtonDown}"); Console.WriteLine($" Clicks: {e.Clicks}"); // Suppress middle mouse button clicks from reaching other apps if (e.Button == MouseButtons.Middle) { e.Handled = true; Console.WriteLine(" Middle click suppressed!"); } }; // Extended MouseUp event hook.MouseUpExt += (sender, e) => { Console.WriteLine($"MouseUpExt: {e.Button}, IsMouseButtonUp: {e.IsMouseButtonUp}"); }; // Extended MouseWheel event hook.MouseWheelExt += (sender, e) => { Console.WriteLine($"MouseWheelExt: Delta={e.Delta}, WheelScrolled={e.WheelScrolled}"); // Optionally suppress wheel events // e.Handled = true; }; // Horizontal wheel support hook.MouseHWheelExt += (sender, e) => { Console.WriteLine($"Horizontal Wheel: Delta={e.Delta}, IsHorizontalWheel={e.IsHorizontalWheel}"); }; // Drag events hook.MouseDragStarted += (sender, e) => Console.WriteLine($"Drag started at ({e.X}, {e.Y})"); hook.MouseDragFinished += (sender, e) => Console.WriteLine($"Drag finished at ({e.X}, {e.Y})"); } } // Output when clicking middle button: // MouseDownExt: Middle // Position: (500, 300) // Timestamp: 12345678 // IsMouseButtonDown: True // Clicks: 1 // Middle click suppressed! ``` -------------------------------- ### Create Key Combinations with Combination Class Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Demonstrates creating key combinations using string parsing and a fluent builder API. Shows how to access combination properties like TriggerKey, Chord, and ChordLength. ```csharp using System; using System.Windows.Forms; using Gma.System.MouseKeyHook; public class CombinationExample { public void CreateCombinations() { // Create combinations from strings (trigger key is last) var undo = Combination.FromString("Control+Z"); var redo = Combination.FromString("Control+Shift+Z"); var fullScreen = Combination.FromString("Shift+Alt+Enter"); var save = Combination.FromString("Control+S"); // Create combinations using fluent builder API var undoBuilder = Combination.TriggeredBy(Keys.Z).With(Keys.Control); var copyBuilder = Combination.TriggeredBy(Keys.C).Control(); var pasteBuilder = Combination.TriggeredBy(Keys.V).Control(); var selectAll = Combination.TriggeredBy(Keys.A).Control(); // Complex combinations with multiple modifiers var complexCombo = Combination.TriggeredBy(Keys.F) .With(Keys.E) .With(Keys.D); var withModifiers = Combination.TriggeredBy(Keys.H) .Alt() .Shift(); // Access combination properties Console.WriteLine($"Undo TriggerKey: {undo.TriggerKey}"); // Z Console.WriteLine($"Undo Chord: {string.Join("+", undo.Chord)}"); // Control Console.WriteLine($"Undo ChordLength: {undo.ChordLength}"); // 1 Console.WriteLine($"Undo ToString: {undo}"); // Control+Z // Order of modifiers doesn't matter (except trigger must be last) var combo1 = Combination.FromString("Shift+Alt+Enter"); var combo2 = Combination.FromString("Alt+Shift+Enter"); Console.WriteLine($"Equivalent: {combo1.Equals(combo2)}"); // True } } ``` -------------------------------- ### Reactive Keyboard Event Handling Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Demonstrates setting up global hooks, filtering key events, and debouncing input streams using Reactive Extensions. ```csharp using System; using System.Reactive.Linq; using System.Threading; using System.Windows.Forms; using Gma.System.MouseKeyHook; using MouseKeyHook.Rx; public class ReactiveExample { public void SetupReactiveHook() { var hook = Hook.GlobalEvents(); // Get observable stream of key down events IObservable keyDownStream = hook.KeyDownObservable(); // Subscribe to all key presses keyDownStream.Subscribe(key => Console.WriteLine($"Key down: {key}")); // Filter for specific keys keyDownStream .Where(key => key == Keys.Space) .Subscribe(_ => Console.WriteLine("Space pressed!")); // Debounce rapid key presses (e.g., for search-as-you-type) keyDownStream .Throttle(TimeSpan.FromMilliseconds(300)) .Subscribe(key => Console.WriteLine($"Debounced: {key}")); } public void DetectCombinationsReactive() { var hook = Hook.GlobalEvents(); // Define combinations to detect var triggers = new[] { Combination.FromString("Control+Q"), Combination.TriggeredBy(Keys.H).Alt().Shift(), Combination.TriggeredBy(Keys.E).With(Keys.Q).With(Keys.W) }; // Match any combination from the list hook.KeyDownObservable() .Matching(triggers) .Subscribe(matched => { Console.WriteLine($"Matched combination: {matched}"); }); // Match only the longest combination when multiple match hook.KeyDownObservable() .MatchingLongest(triggers) .Subscribe(matched => { Console.WriteLine($"Longest match: {matched}"); }); } public void WithKeyboardState() { var hook = Hook.GlobalEvents(); // Get key events with current keyboard state hook.KeyDownObservable() .WithState() .Subscribe(keyWithState => { Console.WriteLine($"Key: {keyWithState.KeyCode}"); // KeyWithState contains both key and KeyboardState snapshot }); } public void KeyUpDownEvents() { var hook = Hook.GlobalEvents(); // Combined up/down events stream hook.UpDownEvents() .Subscribe(keyEvent => { var direction = keyEvent.Kind == KeyEventKind.Down ? "DOWN" : "UP"; Console.WriteLine($"{keyEvent.Key} {direction}"); }); } } // Output when pressing Ctrl+Q: // Key down: ControlKey // Key down: Q // Matched combination: Control+Q ``` -------------------------------- ### Global Keyboard and Mouse Event Hooking Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Create a global event facade to capture keyboard and mouse events from all applications system-wide. Subscribe to events like KeyDown, KeyPress, KeyUp, MouseDown, MouseMove, and MouseWheel. Ensure to dispose of the hook when done to release resources. ```csharp using System; using System.Windows.Forms; using Gma.System.MouseKeyHook; public class GlobalHookExample { private IKeyboardMouseEvents m_GlobalHook; public void Subscribe() { // Create global hook to capture events from all applications m_GlobalHook = Hook.GlobalEvents(); // Subscribe to keyboard events m_GlobalHook.KeyDown += (sender, e) => Console.WriteLine($"KeyDown: {e.KeyCode}"); m_GlobalHook.KeyPress += (sender, e) => Console.WriteLine($"KeyPress: {e.KeyChar}"); m_GlobalHook.KeyUp += (sender, e) => Console.WriteLine($"KeyUp: {e.KeyCode}"); // Subscribe to mouse events m_GlobalHook.MouseDown += (sender, e) => Console.WriteLine($"MouseDown: {e.Button} at ({e.X}, {e.Y})"); m_GlobalHook.MouseMove += (sender, e) => Console.WriteLine($"MouseMove: ({e.X}, {e.Y})"); m_GlobalHook.MouseWheel += (sender, e) => Console.WriteLine($"MouseWheel: Delta={e.Delta}"); } public void Unsubscribe() { // Always dispose when done to release the hook m_GlobalHook.Dispose(); } } // Output when typing "Hi" and clicking: // KeyDown: ShiftKey // KeyDown: H // KeyPress: H // KeyUp: H // KeyUp: ShiftKey // KeyDown: I // KeyPress: i // KeyUp: I // MouseDown: Left at (500, 300) ``` -------------------------------- ### Define Actions for Key Combinations Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md Define actions as methods with no arguments and void return type, or as lambda expressions. These actions will be executed when their corresponding key combinations are detected. ```CSharp Action actionUndo = DoSomething; Action actionFullScreen = () => { Console.WriteLine("You Pressed FULL SCREEN"); }; void DoSomething() { Console.WriteLine("You pressed UNDO"); } ``` -------------------------------- ### Subscribe to Key Sequences with OnSequence Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Use Hook.GlobalEvents().OnSequence to subscribe to a dictionary of key sequences and their associated actions. The longest matching sequence takes priority. ```csharp using System; using System.Collections.Generic; using System.Windows.Forms; using Gma.System.MouseKeyHook; public class OnSequenceExample { public void SetupSequences() { var sequences = new Dictionary { // Vim-style exit { Sequence.FromString("Shift+Z,Z"), () => Console.WriteLine("Vim exit (ZZ)") }, // ReSharper-style refactoring { Sequence.FromString("Control+R,R"), () => Console.WriteLine("Rename refactoring") }, // VS Code-style shortcuts { Sequence.FromString("Control+K,Control+C"), () => Console.WriteLine("Comment selection") }, { Sequence.FromString("Control+K,Control+U"), () => Console.WriteLine("Uncomment selection") }, { Sequence.FromString("Control+K,Control+F"), () => Console.WriteLine("Format document") }, // Multi-key escape sequence { Sequence.FromString("Escape,Escape,Escape"), () => Console.WriteLine("Triple escape - exiting") }, // Simple sequences { Sequence.FromString("Control+Z,B"), () => Console.WriteLine("Ctrl+Z followed by B") }, { Sequence.FromString("Control+Z,Z"), () => Console.WriteLine("Ctrl+Z followed by Z") } }; // Install the sequence listener Hook.GlobalEvents().OnSequence(sequences); Console.WriteLine("Sequences active:"); foreach (var seq in sequences.Keys) Console.WriteLine($" {seq}"); } // Longest sequence wins when overlapping public void OverlappingSequences() { // If user types A, B, C: // - "B,C" matches // - "A,B,C" also matches // Only "A,B,C" action fires (longest match wins) var sequences = new Dictionary { { Sequence.FromString("B,C"), () => Console.WriteLine("Short sequence BC") }, { Sequence.FromString("A,B,C"), () => Console.WriteLine("Long sequence ABC") } }; Hook.GlobalEvents().OnSequence(sequences); } } // Output when pressing Ctrl+K, then Ctrl+C: // Comment selection ``` -------------------------------- ### Configure HotKeySetsListener and Bindings Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/MouseKeyHook/HotKeys/ReadMe.txt Initializes the mouse and keyboard hook managers and defines hotkey sets with specific key combinations and event handlers. ```csharp //HotKeySetsListener inherits KeyboardHookListener private readonly HotKeySetsListener m_KeyboardHookManager; private readonly MouseHookListener m_MouseHookManager; public TestFormHookListeners() { InitializeComponent(); //m_KeyboardHookManager = new KeyboardHookListener(new GlobalHooker()); //m_KeyboardHookManager.Enabled = true; m_MouseHookManager = new MouseHookListener( new GlobalHooker() ) { Enabled = true }; HotKeySetCollection hkscoll = new HotKeySetCollection(); m_KeyboardHookManager = new HotKeySetsListener( hkscoll, new GlobalHooker() ) { Enabled = true }; BuildHotKeyTests( hkscoll ); } private void BuildHotKeyTests( HotKeySetCollection hkscoll ) { //Hot Keys are enabled by default. Use the Enabled property to adjust. hkscoll.Add( BindHotKeySet( new[] { Keys.T, Keys.LShiftKey }, null, OnHotKeyDownOnce1, OnHotKeyDownHold1, OnHotKeyUp1, "test1" ) ); hkscoll.Add( BindHotKeySet( new[] { Keys.T, Keys.LControlKey, Keys.RControlKey }, new[] { Keys.LControlKey, Keys.RControlKey }, OnHotKeyDownGeneral2, OnHotKeyDownGeneral2, OnHotKeyUp1, "test2" ) ); } ``` -------------------------------- ### Define Key Sequences from String Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md Use `Sequence.FromString` to define sequences of key combinations. Sequences are comma-separated strings of combination strings. ```CSharp var exitVim = Sequnce.FromString("Shift+Z,Z"); var rename = Sequnce.FromString("Control+R,R"); var exitReally = Sequnce.FromString("Escape,Escape,Escape"); ``` -------------------------------- ### Subscribe to Global Mouse and Keyboard Events in C# Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/README.md Initialize the global event hook and subscribe to mouse down and key press events. Ensure to use Hook.GlobalEvents() for application-wide hooks. ```csharp private IKeyboardMouseEvents m_GlobalHook; public void Subscribe() { // Note: for the application hook, use the Hook.AppEvents() instead m_GlobalHook = Hook.GlobalEvents(); m_GlobalHook.MouseDownExt += GlobalHookMouseDownExt; m_GlobalHook.KeyPress += GlobalHookKeyPress; } ``` -------------------------------- ### Register Exclusive-Or Keys Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Shows how to register multiple keys (e.g., LShiftKey and RShiftKey) to be treated as interchangeable within a HotKeySet. This allows the hot key to be triggered by any of the registered keys. ```csharp // Allow either LShift or RShift var hotKeySet = new HotKeySet(new[] { Keys.T, Keys.LShiftKey, Keys.RShiftKey }); // Register LShiftKey and RShiftKey as interchangeable // Now pressing T+LShift OR T+RShift will both activate the set Keys primaryKey = hotKeySet.RegisterExclusiveOrKey( new[] { Keys.LShiftKey, Keys.RShiftKey }); Console.WriteLine($"Primary key for shift: {primaryKey}"); // LShiftKey hotKeySet.OnHotKeysDownOnce += (sender, e) => { Console.WriteLine("T + (any Shift) pressed!"); }; // Later, unregister if needed // hotKeySet.UnregisterExclusiveOrKey(Keys.LShiftKey); ``` -------------------------------- ### Application-Level Keyboard and Mouse Event Hooking Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Create an application-level event facade to capture keyboard and mouse events only when your application has focus. Subscribe to events like KeyPress, MouseClick, and MouseDoubleClick. Remember to dispose of the hook when finished. ```csharp using System; using System.Windows.Forms; using Gma.System.MouseKeyHook; public class AppHookExample { private IKeyboardMouseEvents m_AppHook; public void Subscribe() { // Create application-level hook (only captures when app has focus) m_AppHook = Hook.AppEvents(); m_AppHook.KeyPress += (sender, e) => Console.WriteLine($"App KeyPress: {e.KeyChar}"); m_AppHook.MouseClick += (sender, e) => Console.WriteLine($"App MouseClick: {e.Button} at ({e.X}, {e.Y})"); m_AppHook.MouseDoubleClick += (sender, e) => Console.WriteLine($"App DoubleClick: {e.Button}"); } public void Unsubscribe() { m_AppHook.Dispose(); } } ``` -------------------------------- ### Define Key Combinations using Trigger Methods Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md Alternatively, define key combinations using chained methods like `TriggeredBy` and `With`. The last key specified is the trigger key. ```CSharp var undo2 = Combination.TriggeredBy(Keys.Z).With(Keys.Control); ``` -------------------------------- ### Handle HotKey Events Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/MouseKeyHook/HotKeys/ReadMe.txt Provides helper methods to log hotkey triggers and handle specific event types like ONCE, HOLD, and UP. ```csharp private void GeneralHotKeyEvent( object sender, DateTime timeTriggered, string eventType ) { HotKeySet hks = sender as HotKeySet; string kstring = String.Join( ", ", hks.HotKeys ); Log( String.Format( "{0}: {2} {1} - {3}\r\n", timeTriggered.TimeOfDay, eventType, hks.Name, kstring ) ); } private void OnHotKeyDownGeneral2( object sender, HotKeyArgs e ) { GeneralHotKeyEvent( sender, e.Time, "ONCE/HOLD" ); } private void OnHotKeyDownOnce1( object sender, HotKeyArgs e ) { GeneralHotKeyEvent( sender, e.Time, "ONCE" ); } private void OnHotKeyDownHold1( object sender, HotKeyArgs e ) { GeneralHotKeyEvent( sender, e.Time, "HOLD" ); } private void OnHotKeyUp1( object sender, HotKeyArgs e ) { GeneralHotKeyEvent( sender, e.Time, "UP" ); } ``` -------------------------------- ### Short Form for Key Combination Detection Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md A concise version combining action definition and assignment within the `OnCombination` call. ```CSharp void DoSomething() { Console.WriteLine("You pressed UNDO"); } Hook.GlobalEvents().OnCombination(new Dictionary { {Combination.FromString("Control+Z"), DoSomething}, {Combination.FromString("Shift+Alt+Enter"), () => { Console.WriteLine("You Pressed FULL SCREEN"); }} }); ``` -------------------------------- ### Bind HotKeySet with Exclusive OR Keys Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/MouseKeyHook/HotKeys/ReadMe.txt Creates a HotKeySet and registers optional keys that act as an OR condition. Requires the XOR keys to be a subset of the primary key collection. ```csharp private static HotKeySet BindHotKeySet( IEnumerable ks, IEnumerable xorKeys, HotKeySet.HotKeyHandler onEventDownOnce, HotKeySet.HotKeyHandler onEventDownHold, HotKeySet.HotKeyHandler onEventUp, string name ) { //Declare ALL Keys that will be available in this set, including any keys you want to register as an either/or subset HotKeySet hks = new HotKeySet( ks ); //Indicates that the keys in this array will be treated as an OR rather than AND: LShiftKey or RShiftKey //The keys MUST be a subset of the ks Keys array. if ( hks.RegisterExclusiveOrKey( xorKeys ) == Keys.None ) //Keys.None indicates an error { MessageBox.Show( null, @"Unable to register subset: " + String.Join( ", ", xorKeys ), @"Subset registration error", MessageBoxButtons.OK, MessageBoxIcon.Error ); } hks.OnHotKeysDownOnce += onEventDownOnce; //The first time the key is down hks.OnHotKeysDownHold += onEventDownHold; //Fired as long as the user holds the hot keys down but is not fired the first time. hks.OnHotKeysUp += onEventUp; //Whenever a key from the set is no longer being held down hks.Name = ( name ?? String.Empty ); return hks; } ``` -------------------------------- ### Define Key Combinations from String Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/keycomb.md Use `Combination.FromString` to define key combinations. The string format is 'Key1+Key2+TriggerKey'. Keys are case-insensitive and can be any member of the `Keys` enum. ```CSharp var undo = Combination.FromString("Control+Z"); var fullScreen = Combination.FromString("Shift+Alt+Enter"); ``` -------------------------------- ### Subscribe to Key Down Text Event Source: https://context7.com/gmamaladze/globalmousekeyhook/llms.txt Use the KeyDownTxt event to capture keyboard input, which provides both key event data and the resulting character output. ```csharp using System; using Gma.System.MouseKeyHook; public class KeyDownTxtExample { public void Subscribe() { var hook = Hook.GlobalEvents(); // KeyDownTxt provides both key event data and character output hook.KeyDownTxt += (sender, e) => { Console.WriteLine($"KeyDownTxt:"); Console.WriteLine($" KeyCode: {e.KeyEvent.KeyCode}"); Console.WriteLine($" ScanCode: {e.KeyEvent.ScanCode}"); Console.WriteLine($" Timestamp: {e.KeyEvent.Timestamp}"); Console.WriteLine($" IsKeyDown: {e.KeyEvent.IsKeyDown}"); Console.WriteLine($" IsExtendedKey: {e.KeyEvent.IsExtendedKey}"); Console.WriteLine($" Chars: \"{e.Chars}\""); }; } } // Output when pressing 'A': // KeyDownTxt: // KeyCode: A // ScanCode: 30 // Timestamp: 12345678 // IsKeyDown: True // IsExtendedKey: False // Chars: "a" ``` -------------------------------- ### Handle Key Press Events in C# Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/README.md This event handler is triggered on each key press and logs the character of the pressed key. ```csharp private void GlobalHookKeyPress(object sender, KeyPressEventArgs e) { Console.WriteLine("KeyPress: \t{0}", e.KeyChar); } ``` -------------------------------- ### Unsubscribe from Global Mouse and Keyboard Events in C# Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/README.md Unsubscribe from all registered mouse and keyboard events and dispose of the global hook object to release resources. ```csharp public void Unsubscribe() { m_GlobalHook.MouseDownExt -= GlobalHookMouseDownExt; m_GlobalHook.KeyPress -= GlobalHookKeyPress; //It is recommened to dispose it m_GlobalHook.Dispose(); } ``` -------------------------------- ### Handle Mouse Down Events in C# Source: https://github.com/gmamaladze/globalmousekeyhook/blob/vNext/README.md This event handler captures mouse down events, logging the button pressed and the system timestamp. It also demonstrates how to suppress specific mouse button actions. ```csharp private void GlobalHookMouseDownExt(object sender, MouseEventExtArgs e) { Console.WriteLine("MouseDown: \t{0}; \t System Timestamp: \t{1}", e.Button, e.Timestamp); // uncommenting the following line will suppress the middle mouse button click // if (e.Buttons == MouseButtons.Middle) { e.Handled = true; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.