2009-03-19 3 views
2

J'utilise l'appel Windows API SendInput() pour simuler des événements de clavier. L'extrait suivant (détails non pertinents omis) fonctionne parfaitement pour envoyer une séquence de caractères:Comment spécifier les modificateurs kbd avec 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)); 

Maintenant, je suis en train d'envoyer des touches individuelles, avec des modificateurs. J'ai essayé le code suivant:

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

Cependant, les modificateurs ne semblent pas passer à travers, à savoir, même si, disent control est à true, la séquence d'événements est reçue comme une simple pression de touche.

Répondre

3

Pax's answer n'a pas fonctionné, mais cela m'a conduit à la bonne solution. En bref: n'utilisez pas KEYEVENTF_UNICODE pour des pressions de touches individuelles, mais convertissez le caractère en un code de clé virtuel et envoyez-le comme ça. Voici le code correspondant:

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

Je ne l'ai pas testé comment cela fonctionne pour les caractères unicode non-ASCII, qui sont mis en correspondance avec les dispositions de clavier non anglais, et ce qui se passe lorsque la mise en page prévue pour mon application est différente de la jeu de mise en page pour l'application à l'avant.

+0

@David, vous devriez probablement accepter cette réponse sinon SO continuera à vous déranger avec "avez-vous pensé à accepter une réponse à cette question". – paxdiablo

+0

@Pax: bien sûr, je vais le faire, mais d'abord je voulais donner aux autres une chance d'améliorer ma réponse ou de signaler mes erreurs. –

2

Le seul morceau de code que j'ai trouvé qui peut indiquer votre problème définit également le code de balayage dans la structure ki.

Essayez de changer vos sections de modification requise:

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

et voir si cela aide.

Si cela ne fonctionne toujours pas, essayez de régler le dwFlags sur KEYEVENTF_SCANCODE au lieu de 0 (uniquement pour les touches de modification).

Également le faire pour les événements key-up aussi bien et je suppose que vous définissez input[nInput].type à INPUT_KEYBOARD, oui? Votre code ne l'indique pas. Pour référence, il a été trouvé sur this page.

+0

"vous définissez l'entrée [nInput] .type à INPUT_KEYBOARD" - oui, bien sûr. –

+0

Pas "bien sûr", je ne suppose jamais rien qui n'est pas clairement indiqué (et parfois je doute même ceux :-). De toute façon, avez-vous essayé les codes de balayage? – paxdiablo

+0

Assez juste :-) Quoi qu'il en soit, les codes de balayage n'a pas aidé, mais la page que vous avez référée m'a conduit à la solution. Je l'afficherai comme une réponse. +1, et merci! –