首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Node-webkit WinAPI

Node-webkit WinAPI
EN

Stack Overflow用户
提问于 2013-02-10 22:59:42
回答 2查看 4.8K关注 0票数 12

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

我是WinAPI开发的新手,所以我读过一些MSDN手册,但发现大多数示例都是创建窗口、消息循环、消息处理过程等。所以我不太理解,如何在不创建单独窗口的情况下,正确地实现从node-webkit调用WinAPI?

Node-ffi tutorial没有涵盖这种情况,所以我找到了node Windows库,但它似乎只是通过node来实现应用程序。

有没有办法在不创建windows应用程序的情况下实现本机调用?那么正确的方法是什么呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-06-24 02:12:12

我编写了一个节点脚本,使用ffirefref-struct模块捕获windows上的热键。由于ffiref是本机附加组件,我在让它们在打包的.exe中工作时遇到了一些问题。有关更多信息,请参阅我不久前打开的这个github issue

不管怎样,下面是代码:

代码语言:javascript
复制
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):

代码语言:javascript
复制
# 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文档以了解所使用的方法签名和结构。希望这能有所帮助!

票数 18
EN

Stack Overflow用户

发布于 2019-10-10 10:00:55

node-ffi的另一种选择是使用iohook npm模块:https://github.com/wilix-team/iohook

Node.js全局键盘和鼠标侦听程序。

这个模块可以通过JavaScript/TypeScript应用程序内外的本地钩子来处理键盘和鼠标事件。

可以在here中找到一些其他的替代方案。(然而,在我看来,其他的就不那么好了;例如,大多数都不再需要维护。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14799035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档