From f2a7c39abecc88c0ec04fa2709edf4abdd01eb52 Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Tue, 29 Oct 2019 18:11:35 +0100 Subject: [PATCH] Allowing mouse events --- native/ppt/src/KeyboardHook.h | 14 ++- native/ppt/src/Win32KeyboardHook.cpp | 147 ++++++++++++++------------- 2 files changed, 89 insertions(+), 72 deletions(-) diff --git a/native/ppt/src/KeyboardHook.h b/native/ppt/src/KeyboardHook.h index 6eaf5e2..1e7255e 100644 --- a/native/ppt/src/KeyboardHook.h +++ b/native/ppt/src/KeyboardHook.h @@ -11,7 +11,8 @@ #endif class KeyboardHook { #if defined(WIN32) - friend LRESULT CALLBACK keyboard_hook_callback(int, WPARAM, LPARAM); + friend LRESULT CALLBACK _keyboard_hook_callback(int, WPARAM, LPARAM); + friend LRESULT CALLBACK _mouse_hook_callback(int, WPARAM, LPARAM); #endif public: struct KeyType { @@ -63,9 +64,14 @@ class KeyboardHook { long end_id = 0; #elif defined(WIN32) typedef UINT KeyID; - HHOOK hook_id = nullptr; - bool _hook_callback(int, WPARAM, LPARAM); - #endif + HHOOK keyboad_hook_id{nullptr}; + HHOOK mouse_hook_id{nullptr}; + + bool keyboard_hook_callback(int, WPARAM, LPARAM); + bool mouse_hook_callback(int, WPARAM, LPARAM); + #endif + + void trigger_key_event(const enum KeyEvent::type&, const std::string& /* key */); std::map map_key; std::map map_special; diff --git a/native/ppt/src/Win32KeyboardHook.cpp b/native/ppt/src/Win32KeyboardHook.cpp index 720e910..6711128 100644 --- a/native/ppt/src/Win32KeyboardHook.cpp +++ b/native/ppt/src/Win32KeyboardHook.cpp @@ -1,11 +1,12 @@ #include #include +#include #include "KeyboardHook.h" using namespace std; typedef KBDLLHOOKSTRUCT KeyboardHookStruct; -LRESULT CALLBACK keyboard_hook_callback(int, WPARAM, LPARAM); +typedef MSLLHOOKSTRUCT MouseHookStruct; std::map hook_handles; KeyboardHook::KeyboardHook() {} @@ -14,6 +15,21 @@ KeyboardHook::~KeyboardHook() { this->detach(); } +void KeyboardHook::trigger_key_event(const enum KeyEvent::type& type, const std::string &key) { + if(!this->callback_event) return; + + auto event = make_shared(); + event->type = type; + event->code = key; + + event->key_alt = this->map_special[KeyType::KEY_ALT]; + event->key_ctrl = this->map_special[KeyType::KEY_CTRL]; + event->key_windows = this->map_special[KeyType::KEY_WIN]; + event->key_shift = this->map_special[KeyType::KEY_SHIFT]; + + this->callback_event(event); +} + bool KeyboardHook::attach() { assert(!this->_attached); this->active = true; @@ -36,13 +52,38 @@ void KeyboardHook::detach() { this->_attached = false; } +LRESULT _keyboard_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) { + auto handle = hook_handles[this_thread::get_id()]; + assert(handle); + auto consume = handle->keyboard_hook_callback(nCode, event, ptr_keyboard); + if(consume) + return 1; + return CallNextHookEx(nullptr, nCode, event, ptr_keyboard); +} + +LRESULT _mouse_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) { + auto handle = hook_handles[this_thread::get_id()]; + assert(handle); + auto consume = handle->mouse_hook_callback(nCode, event, ptr_keyboard); + if(consume) + return 1; + return CallNextHookEx(nullptr, nCode, event, ptr_keyboard); +} + void KeyboardHook::poll_events() { hook_handles[this_thread::get_id()] = this; - this->hook_id = SetWindowsHookEx(WH_KEYBOARD_LL, keyboard_hook_callback, GetModuleHandle(nullptr), 0); - if(!this->hook_id) { - cerr << "Failed to register hook!" << endl; + this->keyboad_hook_id = SetWindowsHookEx(WH_KEYBOARD_LL, _keyboard_hook_callback, GetModuleHandle(nullptr), 0); + if(!this->keyboad_hook_id) { + cerr << "Failed to register keyboard hook" << endl; return; } + + this->mouse_hook_id = SetWindowsHookEx(WH_MOUSE_LL, _mouse_hook_callback, GetModuleHandle(nullptr), 0); + if(!this->keyboad_hook_id) { + UnhookWindowsHookEx(this->keyboad_hook_id); + cerr << "Failed to register mouse hook" << endl; + return; + } MSG msg; while(!GetMessage(&msg, nullptr, 0, 0) && this->active) { @@ -50,19 +91,10 @@ void KeyboardHook::poll_events() { DispatchMessage(&msg); } - UnhookWindowsHookEx(this->hook_id); + UnhookWindowsHookEx(this->keyboad_hook_id); hook_handles[this_thread::get_id()] = nullptr; } -LRESULT keyboard_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) { - auto handle = hook_handles[this_thread::get_id()]; - assert(handle); - auto consume = handle->_hook_callback(nCode, event, ptr_keyboard); - if(consume) - return 1; - return CallNextHookEx(nullptr, nCode, event, ptr_keyboard); -} - inline std::string key_code(DWORD code, bool extended = false) { auto scan_code = MapVirtualKey(code, MAPVK_VK_TO_VSC); if(extended) @@ -78,7 +110,7 @@ inline std::string key_code(DWORD code, bool extended = false) { inline std::string key_code(KeyboardHookStruct* keyboard) { return key_code(keyboard->vkCode, (keyboard->flags & LLKHF_EXTENDED) > 0); -} +} using KeyType = KeyboardHook::KeyType; //https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes @@ -104,7 +136,7 @@ inline KeyType::value key_type(DWORD vk_code) { } } -bool KeyboardHook::_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) { +bool KeyboardHook::keyboard_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) { auto keyboard = (KeyboardHookStruct*) ptr_keyboard; if(event == WM_KEYDOWN || event == WM_SYSKEYDOWN) { auto& state = this->map_key[keyboard->vkCode]; @@ -112,45 +144,14 @@ bool KeyboardHook::_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) state = true; auto type = key_type(keyboard->vkCode); - if(type != KeyType::KEY_NORMAL) + if(type != KeyType::KEY_NORMAL) this->map_special[type] = true; else this->map_special[type] = keyboard->vkCode; - if (this->callback_event) { - if(!typed) { - auto e = make_shared(); - e->type = KeyboardHook::KeyEvent::PRESS; - if(type == KeyType::KEY_NORMAL) { - e->code = key_code(keyboard); - } else { - e->code = key_code(this->map_special[KeyType::KEY_NORMAL], false); - } - - e->key_alt = this->map_special[KeyType::KEY_ALT]; - e->key_ctrl = this->map_special[KeyType::KEY_CTRL]; - e->key_windows = this->map_special[KeyType::KEY_WIN]; - e->key_shift = this->map_special[KeyType::KEY_SHIFT]; - - this->callback_event(e); - } - { - auto e = make_shared(); - e->type = KeyboardHook::KeyEvent::TYPE; - if(type == KeyType::KEY_NORMAL) { - e->code = key_code(keyboard); - } else { - e->code = key_code(this->map_special[KeyType::KEY_NORMAL], false); - } - - e->key_alt = this->map_special[KeyType::KEY_ALT]; - e->key_ctrl = this->map_special[KeyType::KEY_CTRL]; - e->key_windows = this->map_special[KeyType::KEY_WIN]; - e->key_shift = this->map_special[KeyType::KEY_SHIFT]; - - this->callback_event(e); - } - } + if(!typed) + this->trigger_key_event(KeyEvent::PRESS, type == KeyType::KEY_NORMAL ? key_code(keyboard) : key_code(this->map_special[KeyType::KEY_NORMAL], false)); + this->trigger_key_event(KeyEvent::TYPE, type == KeyType::KEY_NORMAL ? key_code(keyboard) : key_code(this->map_special[KeyType::KEY_NORMAL], false)); } else if(event == WM_KEYUP || event == WM_SYSKEYUP) { auto& state = this->map_key[keyboard->vkCode]; if(!state) return false; //Duplicate @@ -160,26 +161,36 @@ bool KeyboardHook::_hook_callback(int nCode, WPARAM event, LPARAM ptr_keyboard) if(type != KeyType::KEY_NORMAL) this->map_special[type] = false; else if(this->map_special[KeyType::KEY_NORMAL] == keyboard->vkCode) - this->map_special[KeyType::KEY_NORMAL] = 0xFF; + this->map_special[KeyType::KEY_NORMAL] = 0; - if (this->callback_event) { - auto e = make_shared(); - e->type = KeyboardHook::KeyEvent::RELEASE; - if(type == KeyType::KEY_NORMAL) { - e->code = key_code(keyboard); - } else { - e->code = key_code(this->map_special[KeyType::KEY_NORMAL], false); - } - - e->key_alt = this->map_special[KeyType::KEY_ALT]; - e->key_ctrl = this->map_special[KeyType::KEY_CTRL]; - e->key_windows = this->map_special[KeyType::KEY_WIN]; - e->key_shift = this->map_special[KeyType::KEY_SHIFT]; - - this->callback_event(e); - } + this->trigger_key_event(KeyEvent::RELEASE, type == KeyType::KEY_NORMAL ? key_code(keyboard) : key_code(this->map_special[KeyType::KEY_NORMAL], false)); } //Consume the event: return 1 return false; +} + +bool KeyboardHook::mouse_hook_callback(int nCode, WPARAM event, LPARAM ptr_mouse) { + auto mouse = (MouseHookStruct*) ptr_mouse; + if(event == WM_RBUTTONDOWN) + this->trigger_key_event(KeyEvent::PRESS, "MOUSE1"); + else if(event == WM_RBUTTONUP) + this->trigger_key_event(KeyEvent::RELEASE, "MOUSE1"); + if(event == WM_LBUTTONDOWN) + this->trigger_key_event(KeyEvent::PRESS, "MOUSE2"); + else if(event == WM_LBUTTONUP) + this->trigger_key_event(KeyEvent::RELEASE, "MOUSE2"); + if(event == WM_MBUTTONDOWN) + this->trigger_key_event(KeyEvent::PRESS, "MOUSE3"); + else if(event == WM_MBUTTONUP) + this->trigger_key_event(KeyEvent::RELEASE, "MOUSE3"); + else if(event == WM_XBUTTONDOWN || event == WM_XBUTTONUP) { + auto x_index = GET_XBUTTON_WPARAM(mouse->mouseData); + this->trigger_key_event(event == WM_XBUTTONDOWN ? KeyEvent::PRESS : KeyEvent::RELEASE, "MOUSEX" + std::to_string(x_index)); + } + else if(event == WM_MOUSEMOVE) + ; + else + cout << "Unknown event: " << event << endl; + return false; } \ No newline at end of file