2017-02-04 5 views
1

以下のコードで: - :SHIFT + 又はSHIFT + を押してもGetKeyStateがToUnicodeExの動作を変更したのはなぜですか?

KEY:a 
KEY:b 
KEY:2 

-

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; 

出力のみのような小文字を示します

Bu T以下のコードで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:@ 

ToUnicodeToAsciiExToAsciiで試したところ、t彼は上記と同じ状況です。

フックをhook.dllという別のDLLファイルに使用し、コンソールアプリケーションにリンクしました。

だから私の質問は:なぜGetKeyState機能が Lockキー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

関連する問題