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 }