Настройка низкоуровневых хуков WinAPI с помощью Node.js ffi-napi - PullRequest
1 голос
/ 11 февраля 2020

Я пытаюсь реализовать простую программу для Windows, которая перехватывает события мыши низкого уровня в Node.js (TypeScript), используя ffi-napi и WinAPI.

Вот мой код:

import * as ffi from 'ffi-napi';
import * as ref from 'ref-napi';
import { types } from 'ref-napi';

const StructType = require('ref-struct-di')(ref);

/* Types */
const LONG = types.long;
const ULONG = types.ulong;
const INT = types.int;
const UINT = types.uint;
const DWORD = ULONG;
const BOOL = INT;

const HANDLE = types.uint64;
const HHOOK = HANDLE;
const HWND = HANDLE;
const HINSTANCE = HANDLE;

const WPARAM = types.uint64;
const LPARAM = types.int64;
const LRESULT = types.int64;

const HOOKPROC = 'pointer';

/* Necessary structs */

const POINT = StructType({
    x: LONG,
    y: LONG
});

const MSG = StructType({
    hwnd: HWND,
    message: UINT,
    wParam: WPARAM,
    lParam: LPARAM,
    time: DWORD,
    pt: POINT,
    lPrivate: DWORD
});

type WindowsHookCallback = (nCode: number, wParam: number, lParam: number) => number;

/* User32 bindings */

const u32 = ffi.Library('user32', {
    'SetWindowsHookExW': [HHOOK, [INT, HOOKPROC, HINSTANCE, DWORD]],
    'UnhookWindowsHookEx': [BOOL, [HHOOK]],
    'CallNextHookEx': [LRESULT, [HHOOK, INT, WPARAM, LPARAM]],
    'GetMessageW': [BOOL, [MSG, HWND, UINT, UINT]],
    'TranslateMessage': [BOOL, [MSG]],
    'DispatchMessageW': [LRESULT, [MSG]]
});

/* Some wrappers for them next */

function SetWindowsHookEx(idHook: number, lpfn: WindowsHookCallback, hmod: number, dwThreadId: number): number {
    const callback = ffi.Callback(LRESULT, [INT, WPARAM, LPARAM], lpfn);
    return u32.SetWindowsHookExW(idHook, callback, hmod, dwThreadId);
}

function UnhookWindowsHookEx(hhk: number): number {
    return u32.UnhookWindowsHookEx(hhk);
}

function CallNextHookEx(hhk: number, nCode: number, wParam: number, lParam: number): number {
    return u32.CallNextHookEx(hhk, nCode, wParam, lParam);
}

function GetMessageW(lpMsg: any, hWnd: number, wMsgFilterMin: number, wMsgFilterMax: number): number {
    return u32.GetMessageW(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax);
}

function TranslateMessage(lpMsg: any): number {
    return u32.TranslateMessage(lpMsg);
}

function DispatchMessageW(lpMsg: any): number {
    return u32.DispatchMessageW(lpMsg);
}

/* Necessary consts */

const
    WM_LBUTTONDOWN = 0x0201,
    WM_LBUTTONUP = 0x0202;
    WH_MOUSE_LL = 14;

let hHook= 0;

/* Callback for our low level hook */

function MouseHookCallback(nCode: number, wParam: number, lParam: number): number {
    if (nCode >= 0) {
        if (wParam === WM_LBUTTONDOWN) {
            console.log('Left Button Down');
        } else if (wParam === WM_LBUTTONUP) {
            console.log('Left Button Up');
        }
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

/* Set the hook */
hHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, 0, 0);

/* Message loop */
let msg = new MSG();
while (GetMessageW(msg.ref(), 0, 0, 0)) {
    TranslateMessage(msg.ref());
    DispatchMessageW(msg.ref());
}

Хорошо распознает щелчки мышью, но прерывается, когда мышь перемещается более чем на несколько пикселей. Я не могу выяснить, где проблема. Может ли кто-нибудь, кто работал с узлом ffi-napi, объяснить, пожалуйста?

Я написал ту же программу на C:

#include <stdio.h>
#include <Windows.h>

HHOOK hHook;

LRESULT CALLBACK MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam) {
    if (nCode >= 0) {
        if (wParam == WM_LBUTTONDOWN) {
            printf("Left Button Down\n");
        }
        else if (wParam == WM_LBUTTONUP) {
            printf("Left Button Up\n");
        }
    }
    return CallNextHookEx(hHook, nCode, wParam, lParam);
}

int main()
{
    hHook = SetWindowsHookExW(WH_MOUSE_LL, MouseHookCallback, 0, 0);

    MSG msg;
    while (GetMessageW(&msg, 0, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessageW(&msg);
    }
}

, но она отлично работает и не создает sh, если Я перемещаю мышь на любое расстояние.

...