Юникод и SetWindowsHookEx - PullRequest
       0

Юникод и SetWindowsHookEx

0 голосов
/ 11 апреля 2020

Я изучаю Win32 API и C ++, и я хотел сделать простой кейлоггер. Вот что я придумал:

#include <Windows.h>
#include <string>
#include <iostream>
#include <sstream>

using namespace std;

LRESULT CALLBACK kbLog1(int code, WPARAM wParam, LPARAM lParam);

void initKbLogger();
void kbLog2(int code, WPARAM wParam, LPARAM lParam);

HHOOK keyHook;

void Hworld() {
    initKbLogger();
}

void initKbLogger() {
    keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, kbLog1, NULL, NULL);
    bool caps;

    if ((GetKeyState(VK_CAPITAL) & 0x0001) != 0) {
        caps = true;
    }

    MSG msg;

    while (GetMessage(&msg, NULL, NULL, NULL) != 0);

    UnhookWindowsHookEx(keyHook);

}


// from https://stackoverflow.com/a/3999597
// will convert LPCWSTR to std::string
std::string utf8_encode(const std::wstring& wstr)
{
    if (wstr.empty()) return std::string();
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
    std::string strTo(size_needed, 0);
    WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
    return strTo;
}


// main hook fn, supposed to run CallNextHookEx no matter what happens in kbLog2
LRESULT CALLBACK kbLog1(int code, WPARAM wParam, LPARAM lParam) {
    OutputDebugStringA("heya");
    kbLog2(code, wParam, lParam);
    OutputDebugStringA("heya2");
    return CallNextHookEx(keyHook, code, wParam, lParam);
}

void kbLog2(int code, WPARAM wParam, LPARAM lParam) {
    if ((code != 0) || (wParam != WM_KEYDOWN)) {
        return;
    }

    LPKBDLLHOOKSTRUCT kbHookData = (LPKBDLLHOOKSTRUCT)lParam;
    BYTE keyboard_state[256];

    GetKeyboardState(keyboard_state);

    WCHAR wChar[4];

    int ret = ToUnicode((UINT)kbHookData->vkCode, kbHookData->scanCode, keyboard_state, wChar, 4, 0);

    if (ret == -1) {
        return;
    }

    string lol = utf8_encode(wChar);

    std::ostringstream out;
    out << wChar;

    string ss = "hello, you typed the following key: " + lol + " " + out.str();

    MessageBoxA(0, ss.c_str(), "Heya", 0);
}

Однако проблема в том, что этот код не может отображать акцентированные символы, которые я печатаю на клавиатуре. Например, нажатие «A» работает просто отлично, но нажатие «é» не отображает реальный символ. Что не так? Я предполагаю, что что-то не так с преобразованием vkCode в строку, но я не вижу, что я сделал неправильно ... Любая помощь? Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...