2

Windows APIのSendInput()呼び出しを使用して、キーボードイベントをシミュレートしています。次のスニペット(無関係な詳細は省略)は、一連の文字を送信するために完全に機能します。

wchar_t txt = ...;
INPUT *input = ...;
size_t nInput = 0;

for (unsigned int j = 0; j < length; j++) {
    input[nInput].ki.wVk = 0;
    input[nInput].ki.wScan = txt[j];
    input[nInput].ki.dwFlags = KEYEVENTF_UNICODE;
    nInput++;
    input[nInput].ki.wVk = 0;
    input[nInput].ki.wScan = txt[j];
    input[nInput].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
    nInput++;
}
SendInput(nInput, input, sizeoF(INPUT));

現在、修飾子を使用して1回のキー押下を送信しようとしています。次のコードを試しました。

bool control, alt shift;
wchar_t chr;

if (control) {
    input[nInput].ki.wVk = VK_CONTROL;
    input[nInput].ki.dwFlags = 0;
    nInput++;
}
if (alt) {
    input[nInput].ki.wVk = VK_MENU;
    input[nInput].ki.dwFlags = 0;
    nInput++;
}
if (shift) {
    input[nInput].ki.wVk = VK_SHIFT;
    input[nInput].ki.dwFlags = 0;
    nInput++;
}

input[nInput].ki.wVk = 0;
input[nInput].ki.wScan = chr;
input[nInput].ki.dwFlags = KEYEVENTF_UNICODE;
nInput++;
input[nInput].ki.wVk = 0;
input[nInput].ki.wScan = chr;
input[nInput].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
nInput++;

if (shift) {
    input[nInput].ki.wVk = VK_SHIFT;
    input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
    nInput++;
}
if (alt) {
    input[nInput].ki.wVk = VK_MENU;
    input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
    nInput++;
}
if (control) {
    input[nInput].ki.wVk = VK_CONTROL;
    input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
    nInput++;
}
SendInput(nInput, input, sizeof(INPUT));

ただし、修飾子は通過しないようです。つまり、たとえばcontroltrueに設定されていても、イベントシーケンスは単純なキー押下として受信されます。

4

2 に答える 2

3

Paxの答えはうまくいきませんでしたが、それは私を正しい解決策に導きました。つまりKEYEVENTF_UNICODE、個々のキーを押すために使用するのではなく、文字を仮想キーコードに変換し、その方法で送信します。関連するコードは次のとおりです。

SHORT virtKey = VkKeyScan((TCHAR) chr);
input[nInput].ki.wVk = LOBYTE(virtKey);
input[nInput].ki.dwFlags = 0;
nInput++;
input[nInput].ki.wVk = LOBYTE(virtKey);
input[nInput].ki.dwFlags = KEYEVENTF_KEYUP;
nInput++;

英語以外のキーボードレイアウトにマップされている非ASCIIUnicode文字に対してこれがどのように機能するか、およびアプリのレイアウトセットが前面のアプリケーションのレイアウトセットと異なる場合にどうなるかについてはテストしていません。

于 2009-03-19T12:28:59.383 に答える
2

あなたの問題を示している可能性がある唯一のコードは、スキャンコードをki構造体にも設定しています。

修飾子セクションを次のように変更してみてください。

if (control) {
    input[nInput].ki.wVk = VK_CONTROL;
    input[nInput].ki.dwFlags = 0;
    input[nInput].ki.wScan = MapVirtualKey(VK_CONTROL, 0); 
    nInput++;
}
if (alt) {
    input[nInput].ki.wVk = VK_MENU;
    input[nInput].ki.dwFlags = 0;
    input[nInput].ki.wScan = MapVirtualKey(VK_MENU, 0); 
    nInput++;
}
if (shift) {
    input[nInput].ki.wVk = VK_SHIFT;
    input[nInput].ki.dwFlags = 0;
    input[nInput].ki.wScan = MapVirtualKey(VK_SHIFT, 0); 
    nInput++;
}

そして、それが役立つかどうかを確認してください。

それでもうまくいかない場合は、代わりにをに設定dwFlagsしてみてください(修飾キーのみ)。KEYEVENTF_SCANCODE0

また、キーアップ イベントについても同様に行いinput[nInput].typeますINPUT_KEYBOARD。あなたのコードはこれを示していません。

参考までに、このページにありました。

于 2009-03-19T11:50:40.287 に答える