/ src / common / interop / KeyboardHook.h
KeyboardHook.h
 1  #pragma once
 2  #include "KeyboardHook.g.h"
 3  #include <mutex>
 4  #include <unordered_set>
 5  
 6  namespace winrt::PowerToys::Interop::implementation
 7  {
 8      struct KeyboardHook : KeyboardHookT<KeyboardHook>
 9      {
10          // KeyboardHook() = default;
11  
12          KeyboardHook(winrt::PowerToys::Interop::KeyboardEventCallback const& keyboardEventCallback, winrt::PowerToys::Interop::IsActiveCallback const& isActiveCallback, winrt::PowerToys::Interop::FilterKeyboardEvent const& filterKeyboardEvent);
13          void Start();
14          void Close();
15  
16      private:
17          winrt::PowerToys::Interop::KeyboardEventCallback keyboardEventCallback;
18          winrt::PowerToys::Interop::IsActiveCallback isActiveCallback;
19          winrt::PowerToys::Interop::FilterKeyboardEvent filterKeyboardEvent;
20  
21          // This class used to be C++/CX, which meant it ran on .NET runtime and was able to send function pointer for delegates as hook procedures for SetWindowsHookEx which kept an object reference.
22          // There doesn't seem to be a way to do this outside of the .NET runtime that allows us to get a proper C-style function.
23          // The alternative when porting to C++/winrt is to keep track of every instance and use a single proc instead of one per object. This should also make it lighter.
24          static std::mutex instancesMutex;
25          static std::unordered_set<KeyboardHook*> instances;
26          static inline HHOOK hookHandle = nullptr;
27          static LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);
28      };
29  }
30  namespace winrt::PowerToys::Interop::factory_implementation
31  {
32      struct KeyboardHook : KeyboardHookT<KeyboardHook, implementation::KeyboardHook>
33      {
34      };
35  }