Skip to content

Instantly share code, notes, and snippets.

@Youka
Created February 7, 2016 23:02
Show Gist options
  • Select an option

  • Save Youka/015684ad9a6999456fb7 to your computer and use it in GitHub Desktop.

Select an option

Save Youka/015684ad9a6999456fb7 to your computer and use it in GitHub Desktop.
Global key listener (Windows)
#include <thread>
#include <atomic>
#include <functional>
#include <windows.h>
static thread_local const std::function<void(WPARAM,DWORD)>* LLKP_data;
static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){
if(nCode == HC_ACTION)
(*LLKP_data)(wParam, reinterpret_cast<PKBDLLHOOKSTRUCT>(lParam)->vkCode);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
class GlobalKeyListener : protected std::thread{
private:
std::atomic_bool stop = ATOMIC_VAR_INIT(false);
public:
GlobalKeyListener(const std::function<void(WPARAM,DWORD)> receiver) : std::thread([this,receiver](){
const HHOOK hook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0);
if(hook){
LLKP_data = &receiver;
MSG msg;
while(!this->stop){
const auto timer_id = SetTimer(NULL, 0, 200, NULL);
GetMessage(&msg, NULL, 0, 0);
KillTimer(NULL, timer_id);
if(msg.message != WM_TIMER){
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
UnhookWindowsHookEx(hook);
}else
this->stop = true;
}){}
bool Running() const{
return !this->stop;
}
~GlobalKeyListener(){
this->stop = true;
this->join();
}
};
#include <iostream>
int main(){
GlobalKeyListener gkl([](WPARAM wParam, DWORD vkCode){
std::cout << '\n' << wParam << ' ' << vkCode << std::endl;
});
std::cin.get();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment