跨平台 Node.js C++ 模块: 监听鼠标中键点击事件
跨平台 Node.js C++ 模块: 监听鼠标中键点击事件
这是一个跨平台的 Node.js C++ 模块,用于监听 PC 端鼠标中键按下的事件。它支持 Windows、Linux 和 macOS 系统,并通过 Node.js 注册事件来回调 JavaScript 代码。
模块功能
- 接收鼠标中键按下的事件。
- 兼容 Windows、Linux 和 macOS 系统。
- 通过 Node.js 注册事件并回调 JavaScript 代码。
- 提供
addMiddleMouseClickListener函数来注册事件。 - 提供
removeMiddleMouseClickListener函数来移除注册的事件。 - 允许多次注册事件,当鼠标中键按下时一次调用所有注册的回调函数。
- 如果没有注册事件,则不响应鼠标中键按下事件。
模块代码
#include <node.h>
#include <uv.h>
#if defined(_WIN32) || defined(WIN32)
#include <windows.h>
#include <iostream>
#elif defined(__linux__)
#include <X11/Xlib.h>
#include <iostream>
#elif defined(__APPLE__)
#include <ApplicationServices/ApplicationServices.h>
#include <iostream>
#endif
using namespace v8;
uv_async_t async;
void MouseListener(uv_async_t *handle) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
Local<Value> callback = Local<Function>::New(isolate, *(static_cast<Function**>(handle->data)));
callback->Call(isolate->GetCurrentContext()->Global(), 0, nullptr);
}
#if defined(_WIN32) || defined(WIN32)
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION && wParam == WM_MBUTTONDOWN) {
uv_async_send(&async);
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
void AddMiddleMouseClickListener(const FunctionCallbackInfo<Value>& args) {
HHOOK hook = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, NULL, 0);
if (hook == NULL) {
return;
}
async.data = &args[0];
}
void RemoveMiddleMouseClickListener(const FunctionCallbackInfo<Value>& args) {
UnhookWindowsHookEx(NULL);
}
#elif defined(__linux__)
Display *display;
XEvent event;
void *MouseThread(void *arg) {
while(true) {
XNextEvent(display, &event);
if (event.type == ButtonPress && event.xbutton.button == Button2) {
uv_async_send(&async);
}
}
}
void AddMiddleMouseClickListener(const FunctionCallbackInfo<Value>& args) {
display = XOpenDisplay(NULL);
if (display == NULL) {
return;
}
XSelectInput(display, DefaultRootWindow(display), ButtonPressMask);
pthread_t thread;
pthread_create(&thread, NULL, MouseThread, NULL);
async.data = &args[0];
}
void RemoveMiddleMouseClickListener(const FunctionCallbackInfo<Value>& args) {
XCloseDisplay(display);
}
#elif defined(__APPLE__)
CGEventRef eventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
if (type == kCGEventOtherMouseDown && CGEventGetIntegerValueField(event, kCGMouseEventButtonNumber) == 2) {
uv_async_send(&async);
}
return event;
}
void AddMiddleMouseClickListener(const FunctionCallbackInfo<Value>& args) {
CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault, kCGEventOtherMouseDown, eventCallback, NULL);
CFRunLoopSourceRef runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
async.data = &args[0];
}
void RemoveMiddleMouseClickListener(const FunctionCallbackInfo<Value>& args) {
// Not supported
}
#endif
void Init(Handle<Object> exports) {
NODE_SET_METHOD(exports, 'addMiddleMouseClickListener', AddMiddleMouseClickListener);
NODE_SET_METHOD(exports, 'removeMiddleMouseClickListener', RemoveMiddleMouseClickListener);
uv_async_init(uv_default_loop(), &async, MouseListener);
}
NODE_MODULE(mouse_listener, Init);
代码解释
- 代码使用了平台相关的 API 来监听鼠标中键点击事件:
- Windows: 使用
SetWindowsHookEx和WH_MOUSE_LL钩子函数。 - Linux: 使用 X11 库的
XNextEvent函数。 - macOS: 使用
CGEventTapCreate函数。
- Windows: 使用
- 使用
uv_async_init和uv_async_send通知 Node.js 事件循环线程,从而回调注册的 JavaScript 函数。
调用示例
const mouseListener = require('./build/Release/mouse_listener');
function onMiddleMouseClick() {
console.log('Middle mouse button clicked!');
}
mouseListener.addMiddleMouseClickListener(onMiddleMouseClick);
setTimeout(() => {
mouseListener.removeMiddleMouseClickListener();
}, 5000);
注意事项
- 该模块需要在 Electron 应用程序中使用。
- 在 Linux 系统中,该模块需要使用 X11 库。
- 在 macOS 系统中,
removeMiddleMouseClickListener函数目前不支持移除事件监听。 - 该模块使用了
uv_async_init和uv_async_send来通知 Node.js 事件循环线程,因此在调用回调函数时需要确保当前线程是 Node.js 的事件循环线程。
总结
这是一个跨平台的 Node.js C++ 模块,用于监听鼠标中键点击事件。它支持 Windows、Linux 和 macOS 系统,并通过 Node.js 注册事件来回调 JavaScript 代码。该模块可以使用在 Electron 应用程序中,为用户提供更丰富的交互体验。
原文地址: https://www.cveoy.top/t/topic/okEe 著作权归作者所有。请勿转载和采集!