节点 webkit WinAPI
Posted
技术标签:
【中文标题】节点 webkit WinAPI【英文标题】:Node-webkit WinAPI 【发布时间】:2013-01-25 18:44:46 【问题描述】:我正在为 Windows(Vista、7、...)开发简单的 node-webkit 应用程序,我需要使用一些 WinAPI 函数,特别是 RegisterHotKey
和 SendInput
,来绑定系统范围的热键并基于击键在那。 node-webkit没有提供这样的API,所以我想用node-ffi来调用那个函数。
我是WinAPI开发的新手,看了一些MSDN手册,发现大部分例子都是创建窗口、消息循环、消息处理过程等。所以我不太明白,如何实现从node-webkit正确调用WinAPI,而不创建单独的窗口?
Node-ffi tutorial 没有涵盖这种情况,所以我找到了node Windows 库,但它似乎只是通过节点实现 Windows 应用程序。
有没有办法在不创建 Windows 应用程序的情况下实现本机调用?这样做的正确方法是什么?
【问题讨论】:
你看过这里吗:***.com/questions/9624536/…。 josh3736 的回答与您相关。 我认为修改 node-webkit 以添加您的 API 的方式更简单更好。如果您愿意,我可以合并您的代码。 【参考方案1】:我编写了一个节点脚本,它使用ffi
、ref
和ref-struct
模块在Windows 上捕获热键。由于ffi
和ref
是本机附加组件,因此我在让它们在打包的.exe 中工作时遇到了一些问题。如需更多信息,请参阅我不久前打开的github issue。
不管怎样,代码如下:
var FFI = require('ffi'),
ref = require('ref'),
Struct = require('ref-struct');
/* First, create the necessary data structures that'll be used
by our windows api calls. */
var pointStruct = Struct(
'x': 'long',
'y': 'long'
);
var msgStruct = Struct(
'hwnd': 'int32',
'message': 'int32',
'wParam': 'int32',
'lParam': 'int32',
'time': 'int32',
'pt': pointStruct
);
var msgStructPtr = ref.refType(msgStruct);
/* Second, register the functions we'd like to use by providing
their method signatures. */
var user32 = new FFI.Library('user32',
'RegisterHotKey': [
'bool', ['int32', 'int', 'int32', 'int32']
],
'GetMessageA': [
'bool', [msgStructPtr, 'int32', 'int32', 'int32']
]
/* You may prefer to use PeekMessageA which has the same
signature as GetMessageA, but is non-blocking. I haven't
tested it, though.
);
/* Third, register your hotkeys. I wanted to control a media player,
so these keys reflect that. */
var ALT = 0x0001,
CTRL = 0x0002,
SHIFT = 0x0004;
var MEDIA_NEXT = 0xB0,
MEDIA_PREV = 0xB1,
MEDIA_STOP = 0xB2,
MEDIA_PLAY_PAUSE = 0xB3,
MEDIA_LAUNCH = 0xB5;
var PERIOD = 0xBE,
COMMA = 0xBC,
EQUAL = 0xBB,
DIVIDE = 0xBF,
SQUOTE = 0xDE,
PAGEUP = 0x21,
PAGEDOWN = 0x22;
registrations = [];
registrations.push(user32.RegisterHotKey(0, 1, 0, MEDIA_NEXT));
registrations.push(user32.RegisterHotKey(0, 1, 0, MEDIA_PREV));
registrations.push(user32.RegisterHotKey(0, 1, 0, MEDIA_STOP));
registrations.push(user32.RegisterHotKey(0, 1, 0, MEDIA_PLAY_PAUSE));
registrations.push(user32.RegisterHotKey(0, 1, 0, MEDIA_LAUNCH));
registrations.push(user32.RegisterHotKey(0, 1, CTRL, PERIOD));
registrations.push(user32.RegisterHotKey(0, 1, CTRL, COMMA));
registrations.push(user32.RegisterHotKey(0, 1, CTRL, EQUAL));
registrations.push(user32.RegisterHotKey(0, 1, CTRL, DIVIDE));
registrations.push(user32.RegisterHotKey(0, 1, CTRL | ALT, PAGEUP));
registrations.push(user32.RegisterHotKey(0, 1, CTRL | ALT, PAGEDOWN));
// an array of booleans telling us which registrations failed/succeeded
console.log(registrations);
/* Fourth, wait for new hotkey events from the message queue. */
var myMsg = new msgStruct;
while (user32.GetMessageA(myMsg.ref(), 0, 0, 0))
var key = myMsg.lParam >> 16;
switch (key)
case MEDIA_NEXT: console.log('media next'); break;
case MEDIA_PREV: console.log('media prev'); break;
case MEDIA_STOP: console.log('media stop'); break;
case MEDIA_PLAY_PAUSE: console.log('media play/pause'); break;
case MEDIA_LAUNCH: console.log('media launch'); break;
case PERIOD: console.log('next'); break;
case COMMA: console.log('previous'); break;
case EQUAL: console.log('play/pause'); break;
case DIVIDE: console.log('info'); break;
case PAGEUP: console.log('volume up'); break;
case PAGEDOWN: console.log('volume down'); break;
default: console.log('undefined hotkey', key, key.toString(16));
如果您希望它与 node-webkit 一起使用,请确保使用 nw-gyp
构建所有本机插件,并将 --target
设置为您的 node-webkit 版本(在我的情况下为 0.5.1):
# Make sure you run this command in the following directories (where the binding.gyp files are):
# node_modules/ffi/
# node_modules/ffi/node_modules/ref/
# node_modules/ref/
$ nw-gyp clean configure --target=v0.5.1 build
查看 MSDN 文档以了解使用的方法签名和结构。希望这会有所帮助!
【讨论】:
【参考方案2】:node-ffi 的替代方法是使用 iohook npm 模块:https://github.com/wilix-team/iohook
Node.js 全局键盘和鼠标监听器。
此模块可以通过 javascript/TypeScript 应用程序内外的原生钩子处理键盘和鼠标事件。
可以在here 找到其他一些替代方案。 (但是,在我看来,其他的并没有那么好;例如,大多数都不再维护了。)
【讨论】:
以上是关于节点 webkit WinAPI的主要内容,如果未能解决你的问题,请参考以下文章