/ src / settings-ui / Settings.UI.Library / HotkeySettingsControlHook.cs
HotkeySettingsControlHook.cs
 1  // Copyright (c) Microsoft Corporation
 2  // The Microsoft Corporation licenses this file to you under the MIT license.
 3  // See the LICENSE file in the project root for more information.
 4  
 5  using System;
 6  
 7  using PowerToys.Interop;
 8  
 9  namespace Microsoft.PowerToys.Settings.UI.Library
10  {
11      public delegate void KeyEvent(int key);
12  
13      public delegate bool IsActive();
14  
15      public delegate bool FilterAccessibleKeyboardEvents(int key, UIntPtr extraInfo);
16  
17      public class HotkeySettingsControlHook : IDisposable
18      {
19          private const int WmKeyDown = 0x100;
20          private const int WmKeyUp = 0x101;
21          private const int WmSysKeyDown = 0x0104;
22          private const int WmSysKeyUp = 0x0105;
23  
24          private KeyboardHook _hook;
25          private KeyEvent _keyDown;
26          private KeyEvent _keyUp;
27          private IsActive _isActive;
28          private bool disposedValue;
29  
30          private FilterAccessibleKeyboardEvents _filterKeyboardEvent;
31  
32          public HotkeySettingsControlHook(KeyEvent keyDown, KeyEvent keyUp, IsActive isActive, FilterAccessibleKeyboardEvents filterAccessibleKeyboardEvents)
33          {
34              _keyDown = keyDown;
35              _keyUp = keyUp;
36              _isActive = isActive;
37              _filterKeyboardEvent = filterAccessibleKeyboardEvents;
38              _hook = new KeyboardHook(HotkeySettingsHookCallback, IsActive, FilterKeyboardEvents);
39              _hook.Start();
40          }
41  
42          private bool IsActive()
43          {
44              return _isActive();
45          }
46  
47          private void HotkeySettingsHookCallback(KeyboardEvent ev)
48          {
49              switch (ev.message)
50              {
51                  case WmKeyDown:
52                  case WmSysKeyDown:
53                      _keyDown(ev.key);
54                      break;
55                  case WmKeyUp:
56                  case WmSysKeyUp:
57                      _keyUp(ev.key);
58                      break;
59              }
60          }
61  
62          private bool FilterKeyboardEvents(KeyboardEvent ev)
63          {
64  #pragma warning disable CA2020 // Prevent from behavioral change
65              return _filterKeyboardEvent(ev.key, (UIntPtr)ev.dwExtraInfo);
66  #pragma warning restore CA2020 // Prevent from behavioral change
67          }
68  
69          protected virtual void Dispose(bool disposing)
70          {
71              if (!disposedValue)
72              {
73                  if (disposing)
74                  {
75                      // Dispose the KeyboardHook object to terminate the hook threads
76                      _hook.Dispose();
77                  }
78  
79                  disposedValue = true;
80              }
81          }
82  
83          public bool GetDisposedState() => disposedValue;
84  
85          public void Dispose()
86          {
87              Dispose(disposing: true);
88              GC.SuppressFinalize(this);
89          }
90      }
91  }