#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. Итак, тогда используйте необработанный ввод. Поскольку вы не показали этот код, мы не можем помочь вам это исправить.