GetKeyState soll nur einmal ausgeführt werden

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Takafusa.

    GetKeyState soll nur einmal ausgeführt werden

    Guten Tag. Ich habe ein sehr simples Problem, welches ich gerade nicht lösen kann.

    C#-Quellcode

    1. bool isPressedKeyPageUp = false;
    2. private void timer1_Tick(object sender, EventArgs e)
    3. {
    4. if (Keyboard.GetKeyStates(Key.PageUp) == KeyStates.Down && !isPressedKeyPageUp)
    5. {
    6. lblCount.Text = (int.Parse(lblCount.Text) + 1).ToString();
    7. isPressedKeyPageUp = true;
    8. }
    9. else if (Keyboard.GetKeyStates(Key.PageUp) == KeyStates.None && isPressedKeyPageUp)
    10. {
    11. isPressedKeyPageUp = false;
    12. }
    13. }


    Dieser Code soll einfach nur einen Label Text + 1 rechnen aber nur einmal wenn die Taste "Page Up" runtergedrückt wurde. Es klappt auch teilweise, nur kommt jetzt das Problem: Beim nicht mehr drücken des Keys, wird der nächste klick auf Page Up einfach ignoriert. Der Klick danach jedoch geht wieder. Also muss ich immer zwei mal auf Page Up klicken, damit der Counter einmal +1 geht. Der Code läuft über einen Timer der jede Millisekunde ausgelöst wird (zu Testzwecken). Ich finde im Internet auch Lösungen, aber die Lösung scheint bei mir nicht zu klappen (isPressedKeyPageUp als Flag nutzen).

    Was mache ich falsch?
    Das funktioniert so nicht weil, die KeyStates Enum hat 3 Felder.

    None -> 0 -> Die Taste wird nicht gedrückt.
    Down -> 1 -> Die Taste wird gedrückt.
    Toggled -> 2 -> Die Taste wird umgeschaltet.

    Das läuft dann so ab
    ...
    None
    [KeyDown]'hier wird die Taste gedrückt.
    Down & Toggled 'bit für down ist gesetzt und für toggled
    [KeyUp]
    Toggled 'bit für down ist nicht gesetzt, aber für toggled
    [KeyDown]
    Down 'bit für down ist gesetzt, für toggled nicht
    [KeyUp]
    None 'bit für down ist nicht gesetzt, auch nicht für toggled
    ...

    Wie du siehst ist dann nur nach jedem 2. KeyUp KeyStates == None

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Takafusa“ ()

    @CensoredAlpaca Warum verwendest Du nicht KeyDown() und Co?
    Oder arbeitest Du mit WPF?
    Dann solltest Du Deinen Thread verschieben lassen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Takafusa Hmm.. Ja, ich verstehe nun. Ich werde gleich mal schauen ob ich das mit deiner Hilfe hinkriege. Falls nicht, kannst du mir einen logischeren Code zur Verfügung stellen?

    Edit: Okay, ich habe absolut keine Ahnung wie ich das mit GetKeyState umsetzen soll. Gibt es keine einfacheren Methoden?

    @RodFromGermany Nein, diesmal arbeite ich mit WinForms. Das KeyDown Event kann ich meines Wissens nicht benutzen, da ich vorhabe Tastenschläge außerhalb der Form zu empfangen. Deshalb ist das in einem Timer drinnen (auch wenn ich das nicht so schön finde).

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „CensoredAlpaca“ ()

    Edit @CensoredAlpaca, ach was solls, hier so funktioniert das.

    C#-Quellcode

    1. KeyStates keyStates = Keyboard.GetKeyStates(Key.PageUp);
    2. if ((keyStates & KeyStates.Down) > 0 && !isPressedKeyPageUp)
    3. {
    4. isPressedKeyPageUp = true;
    5. }
    6. else if (isPressedKeyPageUp && keyStates == KeyStates.Toggled | keyStates == KeyStates.None)
    7. {
    8. isPressedKeyPageUp = false;
    9. }

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Takafusa“ ()

    @Takafusa Ich bin mir sicher diese Methode hatte ich auch bereits versucht. Jedenfalls klappt es nun wunderbar, vielen Dank. Ich verstehe auch warum ich es nicht geschafft habe: Ich ging davon aus, dass DOWN bedeutet, dass die Taste gerade gedrückt wird (was auch stimmt) und NONE einfach nur bedeutet, dass sie gerade nicht gedrückt wird.

    Vielen Dank.
    @CensoredAlpaca Such mal im Forum nach Tastatur Hook.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das Problem ist das hier Logische Operationen zu nutzen sind.

    Wenn KeyStates für PageUp == None ist, PageUp gedrückt wird ist KeyStates als Integer == 3;

    00000011 bin == 3 dez

    Current KeyStates & KeyStates down
    00000011 & 00000001 = 00000001

    Daher beim IF der test ob Current KeyStates & KeyStates down > 0 ist, so wissen wir ob das Bit für KeyDown gesetzt ist. Mann könnte auch testen ob das gleich 1 ist bzw. Keystates.Down, anstatt > 0.

    Somit konnte diese Bedingung Keyboard.GetKeyStates(Key.PageUp) == KeyStates.Down niemals wahr sein.

    Wenn die taste nicht gedrückt ist kann entweder eine (int)0 für None kommen oder aber (int)2 für toggled. Da du aber nur auf None getestet hast ging auch das in die Hose.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Takafusa“ ()