2016-12-13 2 views
-1

Ich arbeite an einem Projekt, bei dem ich einen Super Nintendo Controller nahm und ihn mit einem Arduino steuerte. Der Arduino liest die Taste drückt auf den Controller und sendet es über eine serielle Verbindung.Simulationsschlüssel wird in C und WINAPI gehalten

Ich arbeite an einem Empfängerprogramm, das von der seriellen Schnittstelle liest und dann Tastenbetätigungen in Windows simuliert, damit ich den Controller in anderen Programmen verwenden kann.

Die Sache ist, ich habe so ziemlich alles runter. Außer es gibt ein Problem. Meine simulierten Tasten drücken nicht wirklich gedrückt. Hier

ist der Code für die A-Taste (Tasten sind aktiv niedrig, so dass sie ‚falsch‘, wenn sie gedrückt wird)

if(!(buttonState.state_word & B_A)) 
{ 
    /* If previous state is not pressed, and current is pressed, simulate a keypress */ 
    if(prevState.state_word & B_A) 
     keybd_event(0x41, 0x41,KEYEVENTF_EXTENDEDKEY | 0,0); 
} 
else if(buttonState.state_word & B_A) 
{ 
    /* If previous state is pressed, and current is not pressed, simulate a key release */ 
    if(!(prevState.state_word & B_A)) 
     keybd_event(0x41, 0x41,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0); 
} 

Wenn ich A auf dem SNES Controller drücken, ein A im Notizblock erscheint , beispielsweise. Und wenn ich die A-Taste auf der SNES-Controller halten, wird ein einzelnes A im Editor angezeigt, aber das Terminal wird drucken, dass der Schlüssel gehalten wird, wie ich es programmiert habe.

Wenn die Taste zum ersten Mal gedrückt wird, wird der Tastendruck simuliert. Wenn es gedrückt wird, werden keine Anrufe mehr getätigt, um einen Tastendruck zu simulieren. Und dann, wenn die SNES-Taste losgelassen wird, wird der Tastendruck ebenfalls freigegeben.

Da es diese Zeit zwischen dem Keydown und dem Keyup gibt, warum wird nur ein einzelner Buchstabe gedruckt, und nicht so, als ob die Tastatur gedrückt und wiederholt gedruckt wird?

+0

Wann wird 'prevState' aktualisiert? –

+0

Es klingt, als ob die Tasten "typatisch" sein sollen. Ich weiß nicht, ob das mit simulierten Tastaturereignissen in Windows funktioniert. –

+0

müssen Sie den Status der Schaltflächen überhaupt nicht beibehalten. Wenn Sie ein fernes Ereignis (Keydown oder Keyup) haben, brauchen Sie den direkten Aufruf 'keybd_event' ohne irgendwelche Prüfungen und Bedingungen. – RbMm

Antwort

0

Danke an alle, die geantwortet haben.

Ich landete einen anderen Ansatz, diesmal mit SendInput, und jetzt funktioniert es wie ein Charme.

Aus dem Grund, während ich Zustand behalte, war die Art, wie ich es sah, wenn die Taste gedrückt gehalten wird, möchte ich nicht jedes Mal einen weiteren Tastendruck simulieren, wenn der Controller abgefragt wird. Also behalte ich den Status, so dass, wenn die Taste gedrückt wird, und das nächste Mal, wenn es abgefragt wird, immer noch gedrückt wird, werde ich keinen weiteren Tastendruck erzeugen. Es wird nur erzeugt, wenn der letzte Zustand des Controllers zeigte, dass er nicht gedrückt wurde.

while(1) 
{ 
    prevState = buttonState; 
    ReadFile( hCOM, 
       &buttonState.state_word, 
       2, 
       &bytesRead, 
       NULL); 

    for(i = 0; i < 12; i++) 
    { 
     if(!(buttonState.state_word & (1 << i))) 
     { 
      /* If previous state is not pressed, and current is pressed, simulate a keypress */ 
      if(prevState.state_word & (1 << i)) 
      { 
       in[i].ki.dwFlags = KEYEVENTF_SCANCODE; 
       SendInput(1,&in[i],sizeof(INPUT)); 
      } 
     } 
     else if(buttonState.state_word & (1 << i)) 
     { 
      /* If previous state is pressed, and current is not pressed, simulate a key release */ 
      if(!(prevState.state_word & (1 << i))) 
      { 
       in[i].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP; 
       SendInput(1,&in[i],sizeof(INPUT)); 
      } 
     } 
    } 

} 
+0

Das klingt wie ein Hobby-Projekt, aber wenn Sie es professionell machen möchten, sollten Sie ReadFile() für ReadFileEx() austauschen und Windows "asynchrone I/O" verwenden. Das bedeutet wiederum, dass der Thread nicht 100% CPU verbraucht, wie es bei Ihrem aktuellen Programm der Fall ist. – Lundin

+0

@Lundin: Löst synchrone I/O das Problem, das Sie erstellt haben, nicht bereits, indem Sie asynchron gehen? – IInspectable

+0

@Intspectable Was meinst du? – Lundin