2017-02-04 44 views
1

在下面的代碼: -爲什麼GetKeyState改變了ToUnicodeEx的行爲?

BYTE ks[256]; 
auto keyboard_layout = GetKeyboardLayout(0); 
GetKeyboardState(ks); 
auto w = WCHAR(malloc(1)); 
ToUnicodeEx(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC), ks, LPWSTR(&w), 1, 0, keyboard_layout); 
wcout << "KEY:" << w << endl; 

輸出僅示出了小寫字母,例如: -

KEY:a 
KEY:b 
KEY:2 

按壓SHIFT + SHIFT即使 +

Bu噸在下面的代碼添加GetKeyState(VK_SHIFT)和/或GetKeyState(VK_CAPITAL): - 壓制SHIFT當

auto shifted = false; 
auto caps = false; 
if (GetKeyState(VK_SHIFT) < 0) 
{ 
    shifted = true; 
    cout << "Shifted!" << endl; 
} 
if (GetKeyState(VK_CAPITAL) < 0) 
{ 
    shifted = true; 
    cout << "Caps!" << endl; 
} 
BYTE ks[256]; 
auto keyboard_layout = GetKeyboardLayout(0); 
GetKeyboardState(ks); 
auto w = WCHAR(malloc(1)); 
ToUnicodeEx(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC), ks, LPWSTR(&w), 1, 0, keyboard_layout); 
wcout << "KEY:" << w << endl; 

代碼的行爲直接更改 + SHIFT + 到

KEY:A 
KEY:B 
KEY:@ 

我在ToUnicode,ToAsciiExToAscii上試過這個,它們顯示t他和上面的情況一樣。

我在一個名爲hook.dll的獨立DLL文件中使用了WH_KEYBOARD鉤子,並與控制檯應用程序鏈接。

所以我的問題是:爲什麼GetKeyState功能啓用SHIFT的檢測大寫鎖定鍵?另外,

+1

函數GetKeyState(不能在控制檯模式過程中可靠地工作。它返回鍵盤的* buffered *狀態,即鍵被按下時的狀態。當應用程序調用GetMessage()時,該控件模式應用程序不會更新。但它有時會更新,但確切的觸發對我來說從未明顯。考慮用GetAsyncKeyState()合成你自己的鍵盤狀態,或者做一下工作。 –

回答

4

使用auto w = WCHAR(malloc(1))是錯誤的。 malloc()動態分配一個字節塊,而不是字符。 WCHAR大小爲2個字節,但您只分配1個字節。無論如何你不使用指針,這並不重要。您正在將指針指向單個WCHAR,截斷指針值。然後,您在通過&wToUnicodeEx()時將忽略該值,因爲它將覆蓋w的值。因爲你沒有調用free()來釋放它,所以你正在泄漏分配的內存。

你不需要malloc()都:

WCHAR w; 
ToUnicodeEx(..., &w, 1, ...); 
wcout << "KEY:" << w << endl; 

然而,ToUnicodeEx()有可能返回多於2個字符,所以你應該分配額外的空間來考慮這一點。只需使用本地固定陣列,就像您爲GetKeyboardState()一樣。並且要注意返回值,它包含重要的信息。

至於關鍵的狀態,既然你叫GetKeyboardState(),你不需要使用GetKeyState()

嘗試更多的東西是這樣的:)

BYTE ks[256]; 
auto keyboard_layout = GetKeyboardLayout(0); 
GetKeyboardState(ks); 

if (ks[VK_SHIFT] & 0x80) wcout << L"Shifted!" << endl; 
if (ks[VK_CAPITAL] & 0x80) wcout << L"Caps!" << endl; 

WCHAR w[5] = {}; 
int ret = ToUnicodeEx(wParam, MapVirtualKey(wParam, MAPVK_VK_TO_VSC), ks, w, 4, 0, keyboard_layout); 
switch (ret) 
{ 
case -1: 
    wcout << L"DEAD KEY:" << w << endl; 
    break; 
case 0: 
    wcout << L"NO TRANSLATION" << endl; 
    break; 
case 1: 
    wcout << L"KEY:" << w << endl; 
    break; 
case 2: 
case 3: 
case 4: 
    w[ret] = 0; 
    wcout << L"KEYS:" << w << endl; 
    break; 
} 
+0

對於記憶泄漏,我忘了改變它。但問題仍然存在,因爲'GetKeyState'在按shift或caps時啓用了所有的鍵盤輸入。即使你輸入了'GetKeyState(0)'什麼值 – AlkindiX

相關問題