我正在尝试创建一个可以使用全局键绑定执行某些功能的Electron node.js应用程序。不幸的是,Electron中的全局按键绑定API不适用于游戏,因此我需要创建一个本地节点模块来侦听这些低级按键事件。
所以我正在使用node-gyp与Visual Studio 2015和Nan一起编译项目,以提供Node和C ++之间的通信。我已经设法使项目的两个方面分别工作(低级键绑定和node.js <-> nan通讯),但是我在合并它们时遇到了麻烦。我也承认我对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):错误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):注意:转换失去了限定词
格式:
'常量Nan :: AsyncProgressWorker :: ExecutionProgress *'
'Nan :: AsyncProgressWorker :: ExecutionProgress *'
我设法通过将关键字const添加到私有成员* executionProgress;来解决这一问题。但是我不明白为什么会解决这个问题,因为一旦设置了const变量,就不应该对其进行更改。为什么会编译?
问题2:这是很特殊的:
.. \ binding.cc(22):错误C3867:'KeyboardEventWorker :: HookCallback':非标准语法;使用“&”创建指向成员[C:\ Users \ eksrow \ gdrive \ projects \ vscode \ node-native-hello-world \ build \ binding.vcxproj]的指针
我在网上查找了许多示例,它们都具有相同的语法:
我看不到我的代码和他们在那行代码之间的区别。
如果我按照编译器所说的去做,并在该行中添加一个“&”号,则会产生完全不同的错误:
.. \ binding.cc(22):错误C2276:'&':对绑定的成员函数表达式[C:\ Users \ eksrow \ gdrive \ projects \ vscode \ node-native-hello-world \ build \ binding进行非法操作.vcxproj] .. \ binding.cc(22):错误C2660:'SetWindowsHookExA':函数未使用3个参数[C:\ Users \ eksrow \ gdrive \ project s \ vscode \ node-native-hello-world \ build \ binding.vcxproj]
对于问题#1,您正确地将const
限定符标识为问题。
const
声明后可以分配给成员变量的原因是因为const
in的放置const AsyncProgressWorker::ExecutionProgress *executionProgress
。这是指向常量AsyncProgressWorker :: ExecutionProgress的变量指针。这意味着您可以更改指针的值(例如,如上面的示例中那样重新分配它),但是不能更改其指向的数据。这个问题的最高答案很好地解释了这个概念。
对于问题2,错误是由于尝试将类的成员函数作为函数回调传递而引起的。这根本是不可能的(嗯,没有解决方法...请参阅下文)-成员方法与函数不同,这是所SetWindowsHookEx
期望的。您可以使您的回调函数static
,但随后将无法访问该_hook
成员。
这是一个外部页面,带有(非常hack-y)解决方法,可以解决此确切问题。它应该允许您以SetWindowsHookEx
当前尝试使用的方式使用。但是,我建议您重新考虑应用程序的挂接方式,而不是查看是否可以将单个全局函数或静态成员函数注册为应用程序的回调。
与您的问题无关:除非您在示例中省略了代码,否则您切勿解开设置的钩子SetWindowsHookEx
。看一下MSDN forUnhookWindowsHookEx
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句