使用node-nan在一个node.js模块中设置WindowsHookEx

我正在尝试创build一个Electron node.js应用程序,它可以使用全局键绑定执行某些function。 Electron中的全局键绑定API在游戏中不起作用,所以我需要创build一个监听这些低级别键事件的本地节点模块。

所以我使用node-gyp来编译visual studio 2015和nan的项目来提供节点和c ++之间的通信。 我已经设法让这个项目的两个方面分别工作(低级别的键绑定和node.js < – > nan通信),但是我很难将它们结合起来。 我也承认我有很less的经验与c + +(我没有写一个单一的c + +程序)。

#include "node_modules/nan/nan.h" using namespace std; using namespace Nan; HHOOK _hook; KBDLLHOOKSTRUCT kbdStruct; class KeyboardEventWorker : public AsyncProgressWorker { public: KeyboardEventWorker(Callback *callback, Callback *progress) : AsyncProgressWorker(callback), progress(progress) {} ~KeyboardEventWorker() {} LRESULT CALLBACK HookCallback(int nCode,WPARAM wParam,LPARAM lParam) { executionProgress->Send(reinterpret_cast<const char*>(nCode), sizeof(nCode)); return CallNextHookEx(_hook, nCode, wParam, lParam); } void Execute (const AsyncProgressWorker::ExecutionProgress& progress) { executionProgress = &progress; //PROBLEM #1 _hook = SetWindowsHookEx(13, HookCallback, NULL, 0); //PROBLEM #2 SleepEx(INFINITE, true); } void HandleProgressCallback(const char *data, size_t size) { HandleScope scope; v8::Local<v8::Value> argv[] = { New<v8::Integer>(*reinterpret_cast<int*>(const_cast<char*>(data))) }; progress->Call(1, argv); } private: Callback *progress; AsyncProgressWorker::ExecutionProgress *executionProgress; }; NAN_METHOD(DoProgress) { Callback *progress = new Callback(info[0].As<v8::Function>()); Callback *callback = new Callback(info[1].As<v8::Function>()); AsyncQueueWorker(new KeyboardEventWorker(callback, progress)); } NAN_MODULE_INIT(Init) { Set(target , New<v8::String>("init").ToLocalChecked() , New<v8::FunctionTemplate>(DoProgress)->GetFunction()); } NODE_MODULE(asyncprogressworker, Init) 

问题1:为了能够发送消息到node.js,我需要复制AsyncProgressWorker :: ExecutionProgress的指针,并使它可以被整个类使用,所以当HookCallback触发它时可以发送消息到node.js 。

编译器不喜欢这个

.. \ binding.cc(21):error C2440:'=':不能从'const Nan :: AsyncProgressWorker :: ExecutionProgress *'转换为'Nan::AsyncProgressWorker :: ExecutionProgress *'[C:\ Users \ eksrow \ gdrive \ projects \ vscode \ node-native-hello-world \ build \ bindin g.vcxproj]。

.. \ binding.cc(21):注意:转换失去限定符

格式:

'const Nan :: AsyncProgressWorker :: ExecutionProgress *'

'Nan :: AsyncProgressWorker :: ExecutionProgress *'

这一个我设法通过添加关键字const到私有成员* executionProgress ;. 但我不明白为什么会修复它,constvariables一旦设置就不应该被改变。 为什么这个编译?

问题2:这个非常奇特:

.. \ binding.cc(22):错误C3867:'KeyboardEventWorker :: HookCallback':非标准语法; 用'&'创build一个指向成员[C:\ Users \ eksrow \ gdrive \ projects \ vscode \ node-native-hello-world \ build \ binding.vcxproj]

我在网上查了很多例子,它们都有相同的语法:

  1. SetWindowsHookEx#1
  2. SetWindowsHookEx#2

我无法看到我的代码和他们的代码之间的区别。

如果我按照编译器的说法进行操作,并为该行添加“&”符号,则会出现完全不同的错误:

.. \ binding.cc(22):error C2276:'&':对绑定成员函数expression式[C:\ Users \ eksrow \ gdrive \项目\ vscode \ node-native-hello-world \ build \ binding .vcxproj] .. \ binding.cc(22):error C2660:'SetWindowsHookExA':函数不需要3个参数[C:\ Users \ eksrow \ gdrive \ project s \ vscode \ node-native-hello-world \ build \ binding.vcxproj]

对于问题#1 ,您正确地将const限定符标识为问题。

你可以在声明后赋给const成员variables的原因是constconst AsyncProgressWorker::ExecutionProgress *executionProgress 。 这是一个常量AsyncProgressWorker :: ExecutionProgress的variables指针。 这意味着你可以改变指针的值(例如,按照上面的例子重新赋值),但是你不能改变它指向的数据。 这个问题的最好答案对这个概念有很好的解释。

对于问题2 ,错误是由于尝试将类的成员函数作为函数callback来传递的。 这是根本不可能的(好吧,没有解决方法…见下文) – 一个成员方法是不一样的函数,这是什么SetWindowsHookEx期待。 你可以使你的callback函数是static ,但是不能访问_hook成员。

这是一个外部页面 ,用于解决这个确切的问题(非常黑客)的解决方法。 它应该允许您以您当前正在尝试使用它的方式使用SetWindowsHookEx 。 不过,我build议重新考虑你的应用程序挂钩的方式,而是看看是否有一种方法来注册一个全局函数或静态成员函数作为你的应用程序的callback。

与您的问题无关:除非您在示例中省略了代码,否则不会解除SetWindowsHookEx设置的挂钩。 看看UnhookWindowsHookEx的MSDN 。