Node-webkit WinAPI

我正在为Windows(Vista,7,…)开发简单的node-webkit应用程序,我需要使用一些WinAPI函数,特别是RegisterHotKeySendInput来绑定系统范围的热键,并根据这些热键进行击键。 没有node-webkit提供的API,所以我想用node-ffi来调用这个函数。

我是WinAPI开发新手,所以我已经阅读了一些MSDN手册,但是发现大部分示例都创build窗口,消息循环,消息处理过程等等。 所以我不太明白,如何实现从node-webkit正确调用WinAPI,而不创build单独的窗口?

Node-ffi教程不包括这种情况,所以我find了节点Windows库,但似乎只是通过节点来实现Windows应用程序。

有没有办法实现本地调用而不创buildWindows应用程序? 什么是正确的方法来做到这一点?

我写了一个节点脚本,它使用ffirefref-struct模块捕获窗口上的热键。 我有一些问题,让他们在一个打包的.exe工作,因为ffiref是本地插件。 有关更多信息,请参阅我之前打开的这个github问题 。

无论如何,这是代码:

 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构build了所有的本地插件,其中--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文档以了解所使用的方法签名和结构。 希望这可以帮助!