2013-02-10 34 views
10

Tôi đang phát triển ứng dụng node-webkit đơn giản cho Windows (Vista, 7,…) và tôi cần sử dụng một số chức năng WinAPI, cụ thể là: RegisterHotKeySendInput, để liên kết các phím nóng trên toàn hệ thống và thực hiện tổ hợp phím trong vấn đề này. Không có API nào được cung cấp bởi node-webkit, vì vậy tôi đã nghĩ sử dụng node-ffi để gọi các chức năng đó.Node-webkit WinAPI

Tôi mới tham gia phát triển WinAPI, vì vậy tôi đã đọc một số hướng dẫn sử dụng MSDN, nhưng thấy rằng hầu hết các ví dụ tạo cửa sổ, vòng lặp tin nhắn, thủ tục xử lý tin nhắn v.v. Vì vậy, tôi không hiểu khá rõ, làm thế nào để thực hiện một cách chính xác gọi đến WinAPI từ nút-webkit, mà không cần tạo cửa sổ riêng biệt?

Node-ffi tutorial không đề cập đến trường hợp đó, vì vậy tôi đã tìm thấy thư viện node Windows, nhưng có vẻ như nó chỉ triển khai ứng dụng Windows bằng nút.

Có cách nào để thực hiện cuộc gọi gốc mà không cần tạo ứng dụng windows không? Cách chính xác để làm điều đó là gì?

+1

Bạn đã xem tại đây: http://stackoverflow.com/questions/9624536/create-a-node-js-native-extension-on-windows. Câu trả lời của josh3736 phù hợp với bạn. – user568109

+1

Tôi nghĩ cách sửa đổi nút-webkit để thêm API của bạn dễ dàng hơn và tốt hơn. Tôi có thể tìm cách hợp nhất mã của bạn nếu bạn sẽ đóng góp. –

Trả lời

17

Tôi đã viết tập lệnh nút chụp các phím nóng trên cửa sổ bằng các mô-đun ffi, refref-struct. Tôi đã có một số vấn đề khiến họ làm việc trong một gói .exe kể từ ffiref là các tiện ích gốc. Để biết thêm thông tin, hãy xem điều này github issue Tôi đã mở một lúc trước.

Anyways, đây là các mã:

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)); 
    } 
} 

Nếu bạn muốn điều này để làm việc với nút-webkit, hãy chắc chắn bạn xây dựng tất cả các bản add-ons với nw-gyp với --target thiết lập để các phiên bản của node- webkit (0.5.1 trong trường hợp của tôi):

# 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 

Xem lại tài liệu MSDN để hiểu chữ ký và cấu trúc của phương thức được sử dụng. Hi vọng điêu nay co ich!

Các vấn đề liên quan