mirror of
https://gitlab.com/kelteseth/ScreenPlay.git
synced 2024-11-22 10:42:29 +01:00
Fix windows mouse hook
This commit is contained in:
parent
8e40cce1a1
commit
1af521facc
@ -1,4 +1,28 @@
|
||||
#include "windowsintegration.h"
|
||||
#include <atomic>
|
||||
|
||||
WindowsIntegration* WindowsIntegration::instance = nullptr;
|
||||
|
||||
WindowsIntegration::WindowsIntegration()
|
||||
: m_mouseHook(NULL)
|
||||
, m_keyboardHook(NULL)
|
||||
, m_mouseEventHandler(nullptr)
|
||||
, m_keyboardEventHandler(nullptr)
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
WindowsIntegration::~WindowsIntegration()
|
||||
{
|
||||
unhookAll();
|
||||
instance = nullptr;
|
||||
}
|
||||
|
||||
void WindowsIntegration::unhookAll()
|
||||
{
|
||||
unhookMouse();
|
||||
unhookKeyboard();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns scaling factor as reported by Windows.
|
||||
@ -377,64 +401,7 @@ BOOL MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPAR
|
||||
|
||||
void WindowsIntegration::setMouseEventHandler(MouseEventHandler handler)
|
||||
{
|
||||
m_mouseEventHandler = handler;
|
||||
}
|
||||
|
||||
LRESULT __stdcall WindowsIntegration::MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Initialize mouse event variables
|
||||
DWORD mouseButton = 0;
|
||||
UINT type = WM_MOUSEMOVE;
|
||||
POINT p {};
|
||||
|
||||
if (nCode >= 0) {
|
||||
switch (wParam) {
|
||||
case WM_LBUTTONDOWN:
|
||||
mouseButton = MK_LBUTTON;
|
||||
type = WM_LBUTTONDOWN;
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
mouseButton = MK_LBUTTON;
|
||||
type = WM_LBUTTONUP;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
mouseButton = MK_RBUTTON;
|
||||
type = WM_RBUTTONDOWN;
|
||||
break;
|
||||
default:
|
||||
type = WM_MOUSEMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetCursorPos(&p)) {
|
||||
// Check if the callback function is set and call it
|
||||
if (m_mouseEventHandler) {
|
||||
m_mouseEventHandler(mouseButton, type, p);
|
||||
}
|
||||
|
||||
} else {
|
||||
return CallNextHookEx(m_mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
return CallNextHookEx(m_mouseHook, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
void WindowsIntegration::setupWindowMouseHook()
|
||||
{
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
if (!(m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, hInstance, 0))) {
|
||||
OutputDebugStringW(L"Failed to install mouse hook!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsIntegration::setupWindowKeyboardHook()
|
||||
{
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
if (!(m_keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookCallback, hInstance, 0))) {
|
||||
OutputDebugStringW(L"Failed to install keyboard hook!");
|
||||
return;
|
||||
}
|
||||
m_mouseEventHandler = std::move(handler);
|
||||
}
|
||||
|
||||
void WindowsIntegration::setKeyboardEventHandler(KeyboardEventHandler handler)
|
||||
@ -442,31 +409,133 @@ void WindowsIntegration::setKeyboardEventHandler(KeyboardEventHandler handler)
|
||||
m_keyboardEventHandler = std::move(handler);
|
||||
}
|
||||
|
||||
LRESULT __stdcall WindowsIntegration::KeyboardHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
void WindowsIntegration::setupWindowMouseHook()
|
||||
{
|
||||
if (nCode >= 0) {
|
||||
KBDLLHOOKSTRUCT* kbStruct = (KBDLLHOOKSTRUCT*)lParam;
|
||||
bool keyDown = wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN;
|
||||
// Check if the callback function is set and call it
|
||||
if (m_keyboardEventHandler) {
|
||||
m_keyboardEventHandler(kbStruct->vkCode, keyDown);
|
||||
}
|
||||
// First unhook any existing hook
|
||||
unhookMouse();
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
m_mouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, hInstance, 0);
|
||||
|
||||
if (!m_mouseHook) {
|
||||
DWORD error = GetLastError();
|
||||
OutputDebugStringW(L"Failed to install mouse hook!");
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsIntegration::setupWindowKeyboardHook()
|
||||
{
|
||||
// First unhook any existing hook
|
||||
unhookKeyboard();
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandle(NULL);
|
||||
m_keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookCallback, hInstance, 0);
|
||||
|
||||
if (!m_keyboardHook) {
|
||||
DWORD error = GetLastError();
|
||||
OutputDebugStringW(L"Failed to install keyboard hook!");
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowsIntegration::MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode >= 0 && instance) {
|
||||
instance->processMouseEvent(wParam, lParam);
|
||||
}
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WindowsIntegration::KeyboardHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode >= 0 && instance) {
|
||||
instance->processKeyboardEvent(wParam, lParam);
|
||||
}
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
void WindowsIntegration::processMouseEvent(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!m_mouseEventHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
static POINT lastPoint = {};
|
||||
DWORD mouseButton = 0;
|
||||
UINT type = WM_MOUSEMOVE;
|
||||
POINT p {};
|
||||
|
||||
if (!GetCursorPos(&p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter duplicate mouse move events
|
||||
if (wParam == WM_MOUSEMOVE) {
|
||||
if (lastPoint.x == p.x && lastPoint.y == p.y) {
|
||||
return;
|
||||
}
|
||||
lastPoint = p;
|
||||
}
|
||||
|
||||
switch (wParam) {
|
||||
case WM_LBUTTONDOWN:
|
||||
mouseButton = MK_LBUTTON;
|
||||
type = WM_LBUTTONDOWN;
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
mouseButton = MK_LBUTTON;
|
||||
type = WM_LBUTTONUP;
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
mouseButton = MK_RBUTTON;
|
||||
type = WM_RBUTTONDOWN;
|
||||
break;
|
||||
default:
|
||||
type = WM_MOUSEMOVE;
|
||||
}
|
||||
|
||||
try {
|
||||
m_mouseEventHandler(mouseButton, type, p);
|
||||
} catch (...) {
|
||||
OutputDebugStringW(L"Exception in mouse event handler!");
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsIntegration::processKeyboardEvent(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!m_keyboardEventHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
KBDLLHOOKSTRUCT* kbStruct = (KBDLLHOOKSTRUCT*)lParam;
|
||||
bool keyDown = (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN);
|
||||
m_keyboardEventHandler(kbStruct->vkCode, keyDown);
|
||||
} catch (...) {
|
||||
OutputDebugStringW(L"Exception in keyboard event handler!");
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsIntegration::unhookMouse()
|
||||
{
|
||||
if (m_mouseHook != NULL) {
|
||||
UnhookWindowsHookEx(m_mouseHook);
|
||||
m_mouseHook = NULL;
|
||||
if (m_mouseHook) {
|
||||
HHOOK hookToUnhook = m_mouseHook;
|
||||
m_mouseHook = NULL; // Clear member first
|
||||
|
||||
if (!UnhookWindowsHookEx(hookToUnhook)) {
|
||||
DWORD error = GetLastError();
|
||||
OutputDebugStringW(L"Failed to unhook mouse hook!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WindowsIntegration::unhookKeyboard()
|
||||
{
|
||||
if (m_keyboardHook != NULL) {
|
||||
UnhookWindowsHookEx(m_keyboardHook);
|
||||
m_keyboardHook = NULL;
|
||||
if (m_keyboardHook) {
|
||||
HHOOK hookToUnhook = m_keyboardHook;
|
||||
m_keyboardHook = NULL; // Clear member first
|
||||
|
||||
if (!UnhookWindowsHookEx(hookToUnhook)) {
|
||||
DWORD error = GetLastError();
|
||||
OutputDebugStringW(L"Failed to unhook keyboard hook!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,6 +67,12 @@ static KeyboardEventHandler m_keyboardEventHandler;
|
||||
|
||||
class WindowsIntegration {
|
||||
public:
|
||||
WindowsIntegration();
|
||||
~WindowsIntegration();
|
||||
|
||||
// Prevent copying
|
||||
WindowsIntegration(const WindowsIntegration&) = delete;
|
||||
WindowsIntegration& operator=(const WindowsIntegration&) = delete;
|
||||
struct SpanResult {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
@ -94,17 +100,36 @@ public:
|
||||
HWND windowHandle() const;
|
||||
HWND windowHandleWorker() const;
|
||||
void setWindowHandle(HWND windowHandle);
|
||||
void setupWindowMouseHook();
|
||||
void unhookMouse();
|
||||
void setMouseEventHandler(MouseEventHandler handler);
|
||||
static LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void setupWindowMouseHook();
|
||||
void setupWindowKeyboardHook();
|
||||
// Unhook methods
|
||||
void unhookMouse();
|
||||
void unhookKeyboard();
|
||||
void unhookAll();
|
||||
|
||||
void setKeyboardEventHandler(KeyboardEventHandler handler);
|
||||
static LRESULT __stdcall KeyboardHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
void setMouseEventHandler(MouseEventHandler handler);
|
||||
|
||||
// Status check methods
|
||||
bool isMouseHookInstalled() const { return m_mouseHook != NULL; }
|
||||
bool isKeyboardHookInstalled() const { return m_keyboardHook != NULL; }
|
||||
|
||||
private:
|
||||
void processMouseEvent(WPARAM wParam, LPARAM lParam);
|
||||
void processKeyboardEvent(WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static LRESULT __stdcall KeyboardHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
static WindowsIntegration* instance;
|
||||
HWND m_windowHandle {};
|
||||
HWND m_windowHandleWorker {};
|
||||
// Hook handles
|
||||
HHOOK m_mouseHook;
|
||||
HHOOK m_keyboardHook;
|
||||
// Event handlers
|
||||
MouseEventHandler m_mouseEventHandler;
|
||||
KeyboardEventHandler m_keyboardEventHandler;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user