случайный ввод потерянного ключа на крючках

#c #windows #hook #hid #interception

#c #Windows #перехват #скрытый

Вопрос:

у меня есть HID usb rfid-считыватель, который работает как клавиатура, я не хочу помещать текстовое поле в свою форму (WPF), чтобы получать из нее текст, потому что у меня другие требования. вместо этого я пытаюсь фиксировать события нажатия клавиши и обрабатывать их. для этого я попробовал три разных метода :

Перехват Windows (c ) это самый простой пример testcase, иллюстрирующий проблему

 #include <iostream>
#include <fstream>
#include <Windows.h>
#pragma comment(lib, "user32.lib")

HHOOK keyboardHook{ NULL };
DWORD lastkey = 0;

LRESULT CALLBACK MyLowLevelKeyBoardProc(const int nCode, const WPARAM wParam, const LPARAM lParam)
{

    KBDLLHOOKSTRUCT *kb = (KBDLLHOOKSTRUCT *)lParam;

    switch (wParam)
    {

    case WM_KEYUP:
        if (lastkey == 13)
           system("cls");
        std::cout << "KeyUp event : " << kb->vkCode   << std::endl;
        lastkey = kb->vkCode;
        break;
    }

    return CallNextHookEx(keyboardHook, nCode, wParam, lParam);
}


int main(int argc, char* argv[])
{
    keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, MyLowLevelKeyBoardProc, NULL, 0);


    if (keyboardHook == NULL) {
        std::cout << "Keyboard hook failed!" << std::endl;
    }


    while (GetMessage(NULL, NULL, 0, 0));
    return 0;
}
  

Raw input API

при обработке сообщения WM_INPUT (слишком много кода для отображения)

библиотека перехвата oblita

самое интересное решение, которое я буду использовать, если исправлю проблему

 #include "stdafx.h"
#include "C:DevWPFInterceptionlibraryinterception.h"

#include "C:DevWPFInterceptionInterception-1.0.0samplesutils.h"
#include <string>
#include <iostream>

enum ScanCode
{
    SCANCODE_X = 0x2D,
    SCANCODE_Y = 0x15,
    SCANCODE_ESC = 0x01
};

int main()
{

    using namespace std;

    InterceptionContext context;
    InterceptionDevice device;
    InterceptionStroke stroke;

    wchar_t hardware_id[500];
    string buffer = "";
    //raise_process_priority();

    context = interception_create_context();


    interception_set_filter(context, interception_is_keyboard, INTERCEPTION_FILTER_KEY_UP | INTERCEPTION_FILTER_KEY_UP);



    while (interception_receive(context, device = interception_wait(context), amp;stroke, 1) > 0)
    {
        if (interception_is_keyboard(device))
        {
            InterceptionKeyStroke amp;keystroke = *(InterceptionKeyStroke *)amp;stroke;

            if (keystroke.code == SCANCODE_ESC) break;


        size_t length = interception_get_hardware_id(context, device, hardware_id, sizeof(hardware_id));


        if (wcsstr(hardware_id, L"04F3amp;PID_0009") == 0)
           interception_send(context, device, amp;stroke, 1); // Real Keyboard
        else
        {
            // RFID reader
            if (keystroke.code == 28)
            {
                std::cout << buffer << endl;
                  buffer = "";
            }
            else
                buffer = buffer   std::to_string(keystroke.code);


        }
        }
    }

    interception_destroy_context(context);

    return 0;
}
  

все три метода вызвали у меня одну и ту же проблему :

некоторые ключи случайным образом теряются во время чтения, вместо 10 символов у меня есть только 8/9.

если я использую rfid-считыватель в blocnote, ни один символ не теряется, поэтому проблем со считывателем нет.

итак, мой вопрос: как гарантировать, что Windows не потеряет сообщение / ключ при перехватах, даже если операция чтения может занять 10 секунд.

спасибо и хорошего дня.

Комментарии:

1. Я не вижу никаких проблем с методом перехвата Windows.

2. я тоже 🙂 но, как я уже сказал, у меня случайный потерянный символ из считывателя rfid, кстати, я на win 8.1

3. Почему вы все равно подключаете ввод с клавиатуры, вместо того, чтобы просто обрабатывать сообщения с клавиатуры?

4. я должен различать ключи, которые поступают от считывателя rfid, и которые поступают с реальной клавиатуры, обрабатывать первые и предотвращать их распространение (используя библиотеку перехвата)

5. Итак, тогда используйте необработанный ввод. Поскольку вы не показали этот код, мы не можем помочь вам это исправить.