GetAsyncKeyState oder GetKeyState



  • Ich habe folgenden Codeschnipsel:

    // Wurde eine Taste gedrückt?
    	if ((pMsg->message == WM_KEYDOWN) /*&& (WINVER_98 == GetWinVer())*/)
    	{
    		UINT  nKeyCode = pMsg->wParam; // virtual key code of the key pressed
    		//	if (GetAsyncKeyState(VK_CONTROL))
    		if (GetKeyState(VK_CONTROL))
    		{
    			//	if (GetAsyncKeyState(VK_SHIFT))
    			if (GetKeyState(VK_SHIFT))
    			{
    				// Strg + Shift + ...
    				switch (nKeyCode)
    

    Wenn ich den so habe und im Programm F5 drücke, läuft der durch den Zweig, wo er nur rein soll, wenn ich Strg + Shift festhalte. 😮
    Nehme ich GetAsyncKeyState, klappt das - aber irgendwas anderes zickte, sonst hätte ich das wohl nicht geändert. 🙄

    Kann mir bitte jemand den Unterschied der beiden Funktionen erklären?
    Das in der MSDN liest sich so gleich. 😕



  • mit GetKeyState() kriegste den status der taste, die gerade aus der message queue geholt wurde (z.b. bei WM_KEYDOWN u.ä.)
    GetAsyncKeyState() holt den zeitnahen tastenstatus vom tastaturtreiber und verhält sich etwas zickig, weil sie ein statisches flag hat. ich glaube man musste sie mindestens zweimal hintereinander aufrufen, um den keystatus einzusamplen...
    🙂


  • Mod

    Für Deinen Fall ist GeKeyState das einzig richtige (ich vermute mal es handelt sich um PreTRanslateMessage). Hier wird der Status der Keys reported, der anlag, als Du die entsprechende Fensternachricht angefangen hast zu bearbeiten.
    Und das ist ja das was Du möchtest. Gerade in PreTranslateMessage. Sollte der User in der Zwischenzeit die entsprechenden Tasten losgelassen haben, oder die Nachricht vrzögert ankommen würde GetAsynchKeystate den neuen Status liefern.

    Die Verwendung von GetAsnchKeyState ist sehr eingeschränkt. Ich habe dafür noch nie Verwendung gehabt. GetKeyState ist in der Nachrichtenbehandlung die einzig korrekte Funktion!
    Anders sieht es aus, wenn man Ereignisse pollen will und keine Nachrichtenschleife hat...



  • Martin Richter schrieb:

    Für Deinen Fall ist GeKeyState das einzig richtige (ich vermute mal es handelt sich um PreTRanslateMessage). Hier wird der Status der Keys reported, der anlag, als Du die entsprechende Fensternachricht angefangen hast zu bearbeiten.

    Ja, es ist PreTranslateMessage. (Sorry hatte ich vergessen zu schreiben.)
    Wenn GetKeyState das Richtige ist, warum macht es dann falsche Ergebnisse? 😕
    Ich glaube, du hattest mich damals auch auf die Funktion aufmerksam gemacht, weil ich Probleme mit genau dieser Funktion hatte. (Die ist eine Hilfslösung, weil unter Win98 der Acceleratortable ignoriert wird.)

    Ich habe das Programm offen, es wartet auf eine Aktion von mir.
    Ich nehme die Hände von der Tastatur (damit ich nix aus versehen drücke) und drücke dann F5.
    Und der rennt in den Zweig, als wenn ich Strg und Shift gedrückt hätte. Hab ich aber nicht. 🙄

    Und das Spiel kann ich auf zwei PCs mit einmal Win98 und einmal Win2K reproduzieren.



  • estartu schrieb:

    if (GetKeyState(VK_CONTROL))
    {
      ...
    

    probier stattdessen mal

    if (GetKeyState(VK_CONTROL) & 0x8000)
    {
      ...
    

  • Mod

    Jo! Entweder wie geschrieben:

    if (GetKeyState(VK_CONTROL) & 0x8000)
    

    oder auch:

    if (GetKeyState(VK_CONTROL)<0)
    


  • ten schrieb:

    probier stattdessen mal

    if (GetKeyState(VK_CONTROL) & 0x8000)
    {
      ...
    

    Ah, jetzt geht es.

    Nur das in der MSDN iritiert mich:

    The return value specifies the status of the specified virtual key, as follows:

    • If the high-order bit is 1, the key is down; otherwise, it is up.
    • If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key, is toggled if it is turned on. The key is off and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is toggled, and off when the key is untoggled.

    Der untere Punkt ist nur für Caps-Lock, Rollen und Num-Lock interessant. Also bei allen anderen Tasten 0?
    Der obere gilt für alle. Das ist ja auch das, mit dem ich jetzt das Ergebnis vergleiche.

    Wenn das hintere Bit aber nun 0 ist und das vordere 0 sein sollte (weil ich die Taste ja nicht drücke), wieso kommt da was anderes raus als 0? 😕


  • Mod

    estartu schrieb:

    Wenn das hintere Bit aber nun 0 ist und das vordere 0 sein sollte (weil ich die Taste ja nicht drücke), wieso kommt da was anderes raus als 0? 😕

    Sagen wir es mal so:
    Hier wird nur die vVrwendung dieser beiden Bits erklärt. Es heißt nicht das die anderen nicht 1 sein dürfen. 🕶


Log in to reply