Как декодировать KBDLLHOOKSTRUCT из lParam с помощью koffi в Node.js?

Я пытаюсь преобразовать программу перехвата клавиатуры C++ в Node.js, используя библиотеку koffi. В C++ я обычно приводил параметр lParam к указателю KBDLLHOOKSTRUCT следующим образом:

KBDLLHOOKSTRUCT *pKeyBoard = (KBDLLHOOKSTRUCT *)lParam;

Вот полный C++

#include <windows.h>
#include <iostream>

// Global variable to store the hook handle
HHOOK hKeyboardHook;

// Callback function for handling keyboard events
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    std::cout << nCode << std::endl;
    std::cout << wParam << std::endl;
    std::cout << lParam << std::endl;
    if (nCode >= 0)
    { // The keyboard message is being processed
        if (wParam == WM_KEYDOWN)
        { // A key was pressed down
            KBDLLHOOKSTRUCT *pKeyBoard = (KBDLLHOOKSTRUCT *)lParam;
            DWORD vkCode = pKeyBoard->vkCode;
            std::cout << "Key pressed: " << vkCode << std::endl;

            // If the ESC key is pressed, exit the application
            if (vkCode == VK_ESCAPE)
            {
                PostQuitMessage(0);
            }
        }
    }
    return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}

int main()
{
    // Set a global keyboard hook
    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, 0);

    if (hKeyboardHook == NULL)
    {
        std::cerr << "Failed to install hook!" << std::endl;
        return 1;
    }

    std::cout << "Hook installed successfully!" << std::endl;

    // Message loop
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // Unhook when no longer needed
    UnhookWindowsHookEx(hKeyboardHook);

    return 0;
}

Это позволяет мне получить доступ к коду виртуального ключа (и другим данным) из структуры KBDLLHOOKSTRUCT.

Как я могу добиться того же в Node.js, используя koffi? Ниже мой текущий код:

import koffi from "koffi"
import * as D from "win32-def/def"

const HHOOK = koffi.pointer("HHOOK", koffi.opaque())
const HINSTANCE = koffi.pointer("HINSTANCE", D.INT)

const LRESULT = koffi.alias("LRESULT", D.LONG_PTR)
const WPARAM = koffi.alias("WPARAM", D.ULONG_PTR)
const LPARAM = koffi.alias("LPARAM", D.LONG_PTR)

const KBDLLHOOKSTRUCT = koffi.struct("KBDLLHOOKSTRUCT", {
  vkCode: "DWORD",
  scanCode: "DWORD",
  flags: "DWORD",
  time: "DWORD",
  dwExtraInfo: "ULONG_PTR",
})
export const HOOKPROC = koffi.proto("HOOKPROC", "LRESULT", ["int", "WPARAM", "LPARAM"])

export const SetWindowsHookExA = user32.func("SetWindowsHookExA", "HHOOK", [D.INT, koffi.pointer(HOOKPROC), HINSTANCE, "DWORD"])

const WH_KEYBOARD_LL = 13

export const installMouseHook = () => {
  if (!hHook) {
    const hInstance = GetModuleHandle(null)
    hHook = SetWindowsHookExA(WH_KEYBOARD_LL, onHookProc, null, 0)
    if (!hHook) {
      throw new Error("Failed to install keyboard hook")
    }
    console.info("Keyboard hook installed.")
  }
}

// Hook callback function
const onHookProc = koffi.register((nCode, wParam, lParam) => {
  console.info(nCode, wParam, lParam)

  let kb = koffi.decode(lParam, "KBDLLHOOKSTRUCT") // <====not work
  let kb1= koffi.as(lParam, "KBDLLHOOKSTRUCT") //<====not work

  return CallNextHookEx(hHook, nCode, wParam, lParam)
}, koffi.pointer(HOOKPROC))

Я пробовал использовать koffi.decode и koffi.as, но мне не удалось правильно преобразовать lParam для доступа к структуре KBDLLHOOKSTRUCT в Node.js.

Любое руководство будет оценено по достоинству!

Поскольку код не пытается отклонить ввод, нет смысла устанавливать дорогостоящий перехватчик. Используйте необработанный ввод для целей мониторинга.

IInspectable 23.08.2024 08:13

@IInspectable Я хочу добиться того, чтобы когда пользователь нажимал клавишу «A», программа обнаруживала это, перехватывала ввод и вместо этого меняла его на клавишу «B». Это форма функции сопоставления клавиатуры.

newer 23.08.2024 16:46
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После многочисленных попыток я наконец нашел решение.

const LPARAM = koffi.pointer("LPARAM", D.LPARAM)
let info = koffi.decode(lParam, "KBDLLHOOKSTRUCT")
console.info(`Key pressed: ${JSON.stringify(info)}`)
//Key pressed: {"vkCode":65,"scanCode":30,"flags":128,"time":85736828,"dwExtraInfo":0}


Другие вопросы по теме