2017-08-16 6 views
0

Beim Aufrufen des WINAPI-Befehls GetKeyboardState(aByteArray) aus einer WPF-Anwendung (und vermutlich auch anderen Anwendungen) wird der Schlüssel SHIFT nur dann korrekt erkannt, wenn die Anwendung den Fokus hat. Wenn die Anwendung keinen Fokus hat, ist aByteArray[VK_SHIFT]0 nach dem Methodenaufruf.WINAPI GetKeyboardState Verhalten von GetKeyState geändert, wenn die Anwendung nicht im Fokus ist?

Wenn jedoch GetKeyState(aVKCode) unmittelbar vor GetKeyboardState(aByteArray), für jeden Wert von aVKCode genannt, auch wenn der Rückgabewert verworfen wird, dann GetKeyboardState(aByteArray) den korrekten Nicht-Null-Zustand der gehaltenen SHIFT Schlüssel zur Verfügung stellen wird, wenn die Anwendung nicht im Fokus ist .

Dieses Verhalten ist kontraintuitive und scheint viele Programmierer Trauer verursacht haben. Ich glaube, dass es relevante Informationen in der Dokumentation zu GetKeyboardState der wie folgt lautet:

Der Status ändert sich wie ein Faden Tastaturmeldungen aus seiner Nachrichtenwarteschlange entfernt. Der Status ändert sich nicht, wenn Tastaturnachrichten in die Nachrichtenwarteschlange des Threads gesendet werden, noch ändert er sich, wenn Tastaturnachrichten an Nachrichtenwarteschlangen anderer Threads gesendet oder aus diesen abgerufen werden.

Potentiell interagiert GetKeyState() mit der Nachrichtenwarteschlange in der Weise, dass es vor dem GetKeyboardState() um GetKeyboardState() aufgerufen werden muß, wie gewünscht zu verhalten. Allerdings bin ich nicht vertraut mit dem Konzept der Nachrichtenwarteschlange und wie Elemente von Windows hinzugefügt und entfernt werden, und so dachte ich, ich würde hier fragen. Kann jemand erklären, warum ein Anruf zu GetKeyboardState() allein den Schlüssel SHIFT, der ohne Anwendungsfokus gehalten wird, nicht erfassen kann?

+0

(Tastatur) Eingabe wird virtualisiert pro Thread (oder Gruppe von Eingängen an den Eingängen). Jeder Thread behält seine eigenen Tastaturstatusinformationen bei. Wenn Sie eine Taste drücken, während ein Fenster im Besitz eines Threads über den Eingabefokus verfügt, wird der Tastaturstatus in keinem anderen Thread aktualisiert (außer bei denen, die an diesen Thread angehängt sind). Weitere Details unter [Asynchrone Eingabe vs synchrone Eingabe, eine kurze Einführung] (https://blogs.msdn.microsoft.com/oldnewthing/20130604-00/?p=4173). – IInspectable

Antwort

1

GetKeyState ist immer der letzten verarbeiteten Nachricht eines Threads zugeordnet. Wenn Sie GetKeyState in einem Nachrichtenhandler verwenden, erhalten Sie den Keystate, wenn diese Nachricht in die Nachrichtenwarteschlange gestellt wurde.

Wenn die Nachrichtenverarbeitung verzögert wird, ist gewährleistet, dass jede Nachricht vom Programmierer verarbeitet werden kann und er die Schlüsselzustände in diesem Moment erkennen kann. I.E .: "War die Umschalttaste gedrückt, als der Mausklick erfolgte?"

Nur die Verwendung GetKeyState kann einen Status oder eine Nachricht überspringen, wenn andere Nachrichten dazwischen verarbeitet wurden.

Um die aktuellen Tastenzustand erkennen Sie GetAsyncKeyState

Die Funktionen sind gut dokumentiert verwenden müssen.

Schließlich: Weder GetKeyState noch GetAsyncKeyState ist eine gute Möglichkeit zu erkennen, ob die Umschalttaste innerhalb eines Programms gedrückt wurde. Verarbeiten Sie Nachrichten und erkennen Sie WM_KEYDOWN.

+0

Danke für die Information. Der Code, den ich sehe, verwendet WM_KEYDOWN, um Tastatureingaben zu erkennen, und wenn der Schlüssel aus dieser Nachricht alphanumerisch ist, suche ich mit GetKeyState, ob Shift oder Capslock ausgefallen ist, damit der Schlüssel WM_KEYDOWN in ASCII konvertiert werden kann. Daher möchte ich das Verhalten in den ersten beiden Absätzen beschrieben. Der Grund, warum ich GetKeyState gewählt habe, ist, dass die Shift- und/oder Caps-Lock-Tasten gedrückt werden können, bevor ich mit der Verarbeitung von WM_KEYDOWN-Nachrichten beginne, und ich möchte trotzdem diese Fälle erkennen können. In diesem Szenario, welche Methode würden Sie verwenden? – Anthony

Verwandte Themen