2013-02-10 4 views
10

Windows 용 (Vista, 7, ...) Windows 용 간단한 노드 웹킷 응용 프로그램을 개발 중이며 시스템 전체 단축키를 바인딩하고 키 입력을 기반으로 일부 WinAPI 기능, 특히 RegisterHotKeySendInput을 사용해야합니다. 그걸로. node-webkit에서 제공하는 API는 없기 때문에 node-ffi을 사용하여 해당 함수를 호출 할 생각입니다.노드 - 웹킷 WinAPI

WinAPI 개발이 처음이므로 일부 MSDN 설명서를 읽었지만 대부분의 예제에서는 창, 메시지 루프, 메시지 처리 절차 등을 생성합니다. 그래서 나는 꽤 잘 이해하지 못한다. 어떻게 별도의 창을 만들지 않고 노드 -wekit에서 WinAPI를 올바르게 호출하는 방법을 구현할 수 있을까?

Node-ffi tutorial은이 케이스를 다루지 않으므로 node Windows 라이브러리를 찾았지만 노드를 통해 Windows 응용 프로그램을 구현 한 것으로 보입니다.

Windows 응용 프로그램을 만들지 않고 기본 전화를 구현할 수있는 방법이 있습니까? 그렇게하는 올바른 방법은 무엇입니까?

+1

여기를 보셨습니까? http://stackoverflow.com/questions/9624536/create-a-node-js-native-extension-on-windows. josh3736의 대답은 당신과 관련이 있습니다. – user568109

+1

여러분의 API를 추가하기 위해 node-webkit을 수정하는 방법이 더 쉽고 빠르다고 생각합니다. 기여한다면 코드를 병합 할 수 있습니다. –

답변

17

ffi, refref-struct 모듈을 사용하여 창에 단축기를 캡처하는 노드 스크립트를 작성했습니다. ffiref은 기본 추가 기능이므로 패키지화 된 .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)); 
    } 
} 

이이 노드 웹킷과 함께 작동하도록하려는 경우 노드 - 버전에 --target 세트 nw-gyp 모든 네이티브 추가 기능을 구축해야합니다 웹킷 (내 경우 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 문서를 검토하십시오. 희망이 도움이!