2009-03-19 11 views
2

Ich verwende den Windows API-Aufruf SendInput(), um Tastaturereignisse zu simulieren. Der folgende Ausschnitt (irrelevante Details weggelassen) funktioniert perfekt für eine Folge von Zeichen zu senden:Wie kbd Modifikatoren mit SendInput() angeben?

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)); 

Jetzt einzelne Tastenanschläge zu senden, mit Modifikatoren Ich versuche. Ich habe versucht, den folgenden Code:

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)); 

jedoch Modifikatoren scheinen nicht durch zu erhalten, das heißt, auch wenn, sagen control auf true gesetzt ist, wird die Ereignisfolge als einfacher Tastendruck erhalten.

Antwort

3

Pax's answer hat nicht funktioniert, aber es führte mich zur richtigen Lösung. Kurz gesagt: Verwenden Sie nicht KEYEVENTF_UNICODE für einzelne Tasten, sondern konvertieren Sie das Zeichen in einen virtuellen Schlüsselcode und senden Sie es so. Hier ist der relevante Code:

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++; 

Ich habe nicht getestet, wie das funktioniert für Nicht-ASCII-Unicode-Zeichen, die auf nicht-englische Tastaturlayouts abgebildet werden, und was passiert, wenn das Layout für meine app gesetzt unterscheidet sich von der Layout-Set für die Anwendung in der Front.

+0

@David, Sie sollten diese Antwort wahrscheinlich annehmen, sonst wird SO Sie weiterhin mit "Haben Sie daran gedacht, eine Antwort auf diese Frage zu akzeptieren" stören. – paxdiablo

+0

@Pax: Sicher, ich mache das, aber zuerst wollte ich anderen eine Chance geben, meine Antwort zu verbessern oder auf meine Fehler hinzuweisen. –

2

Das einzige Stück Code, das ich gefunden habe, das auf Ihr Problem hinweisen könnte, setzt den Scan-Code in der ki Struktur.

Versuchen Sie Modifikator Abschnitte sich zu ändern:

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++; 
} 

und sehen, ob das hilft.

Wenn das immer noch nicht funktioniert, versuchen Sie dwFlags auf KEYEVENTF_SCANCODE anstelle von 0 (nur für die Modifikatortasten).

Tun Sie es auch für die Tastenereignisse und ich gehe davon aus, dass Sie input[nInput].type auf INPUT_KEYBOARD setzen, ja? Dein Code zeigt dies nicht an.

Als Referenz wurde es auf this page gefunden.

+0

"Sie setzen den Eingang [nInput] .type auf INPUT_KEYBOARD" - ja, natürlich. –

+0

Nicht "natürlich", ich nehme nie etwas an, was nicht klar gesagt wird (und manchmal zweifle ich sogar an denen :-). Wie auch immer, hast du die Scancodes probiert? – paxdiablo

+0

Fair genug :-) Wie auch immer, die Scan-Codes haben nicht geholfen, aber die Seite, auf die Sie verwiesen haben, führte mich zur Lösung. Ich werde es als Antwort posten. +1, und danke! –