Verständnisfragen zu Tastatur-Ereignissen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Verständnisfragen zu Tastatur-Ereignissen

    Hallo,

    ich verstehe nicht, wie die Tastatureingabe auf einer Userform funktioniert und habe hierzu einige Fragen:

    A.: Für Tastatureingaben werden Ereignisse und Ereignishandler benötigt?
    B.: Ein Ereignis ist etwas was passieren kann, wie z.B. ein _Click-Ereignis Wie z.B. cmdButtonEins.PerformClick(). Also definiere ich nur die Aktion, die ausgeführt werden soll?
    C.: Ein Ereignishandler ist die Reaktion auf ein Ereignis, welches ausgeführt werden soll?
    D.: Ein Handle ist eine vom Prozessor festgelegte interne Speicheradresse?

    E.: Tastaturbezogene Ereignisse sind KeyDown wenn die Taste gedrückt wird), KeyUp(wenn die Taste loggelassen wird) und KeyPress(ist die
    Umwandlung des ASCII-Codes in die Maschinensprache)?

    F.: Jede Taste einer Tastatur hat einen Tasturcode, der in den Enumation keys festgelegt ist?

    Dieser copy&pasted Code funktioniert für mich einwandfrei, jedoch verstehe ich es nicht und möchte gerne wissen, was da passiert:

    VB.NET-Quellcode

    1. Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, _
    2. ByVal keyData As System.Windows.Forms.Keys) As Boolean
    3. Select Case msg.WParam.ToInt32
    4. Case CInt(Keys.D1), CInt(Keys.NumPad1)
    5. cmdButtonEins.PerformClick()
    6. Return True
    7. Case CInt(Keys.D2), CInt(Keys.NumPad2)
    8. cmdButtonZwei.PerformClick()
    9. Return True
    10. Case Else Return MyBase.ProcessCmdKey(msg, keyData)
    11. End Select
    12. Return False
    13. End Function

    A: Zumindest bei der auswertung der Eingaben, wenn man die Events des Controls/ der Form nutzt. Geht aber auch ohne wenn man die API benutzt, wie auch wenn du die wie in deinem Code die ProcessCmdKey Funktion überschreibst.

    B, C: msdn.microsoft.com/de-de/library/edzehd2t(v=vs.110).aspx

    D: Du verwechselst das wohl mit einem Pointer. Dieser zeigt auf eine Speicheradresse. Obwohl ich nicht mal weiss ob das die CPU oder das OS zuweisst.

    E: Ja, ausser das mit dem Machsinencode.
    msdn.microsoft.com/de-de/libra…l.keypress(v=vs.110).aspx

    F: Ja.

    Dein Code überschreibt die Funktion ProcessCmdKey, welche die Daten der Tastatureingaben verarbeitet:
    msdn.microsoft.com/de-de/libra…cesscmdkey(v=vs.110).aspx
    Zu Ereignissen gugge auch Alles über Events - da werden (neben viel mehr) auch die Begriffe sorgsam erklärt (weil kommt man schon leicht durcheinander)
    Eine Handle ist was ganz anderes und hat mit Events nichts zu tun (Verwechslung, weils ja EventHandler gibt, aber das ist was ganz anneres).

    Dein Code ist eine Überschreibung, ein Override.
    Overrides sind eine besondere Technik, mit der man sich in den internen Prozess der Ereignis-Generierung einklinkt. Ist in gewisser Weise also auch Ereignis-Behandlung, aber nicht durch einen Empfänger, sondern wie gesagt durch ein sich dazwischen-schieben beim Sender.

    Lass am besten die Finger davon, solange du der Zusammenhänge noch nicht sicher bist - das ist bisserl advanced und erfordert richtiges Verständnis der Vererbungs-Lehre. Und ist um Tastendrücke zu verarbeiten garnet nötig.
    Und der WndProc-Override ist der advanceste von allen, da gehts garnet mehr um Framework-Events, sondern um Betriebssystem-Resourcen (etwa die Window-Handles etc.).
    Danke euch beiden!
    An dieser Stellen bin ich an meine Grenzen gestoßen und muss mich erst einlesen.

    ErfinderDesRades schrieb:

    Lass am besten die Finger davon, solange du der Zusammenhänge noch nicht sicher bist - das ist bisserl advanced und erfordert richtiges Verständnis der Vererbungs-Lehre. Und ist um Tastendrücke zu verarbeiten garnet nötig.

    Ich muss erst einmal nach einer Lösung ohne dem advanced Zeug suchen und dann mich in das advanced Zeug einarbeiten.

    Bruno schrieb:

    Ich muss erst einmal nach einer Lösung ohne dem advanced Zeug suchen
    meine Rede :thumbsup:
    Deshalb lösche diese Methode da, und mach eine normale Tastatur-Ereignisbehandlung, und versuch die zu verstehen. Obige Methode ist in gewisser Weise garnet zu verstehen, denn niemand, der auch nur bischen was davon versteht, würde sowas hinhauen.

    und dann mich in das advanced Zeug einarbeiten.
    jo - und wie gesagt: der WndProc-Override ist dermassen advanced - damit kommst du u.U. auch in Jahren noch nicht in Berührung.
    WndProc-Overrides sind im Grunde Hacks, alsoCodier-Techniken, die zumindest teilweise ausserhalb dessen stehen, was in VB.Net und im Framework dokumentiert ist.
    Ich habe nun eine einfache Übung zur Tastatur-Ereignissen erstellt.
    Hier kann ich sämtliche Tasteneinschläge mit dem KeyDown Ereignis abgreifen.
    Auf meiner Übungs-Userform habe ich KeyPreview auf True gesetzt und TabStop auf False.
    'Klicke ich auf einen Button, bekommt dieser den Focus.
    Wenn ich auf den Button cmdNull klicke und dann auf Enter drücke, wird die 0 auf der TextBox erneut angezeigt, da sie noch den Focus hat.
    Ich möchte nicht unter jedem Click-Ereignis den Focus auf cmdEnter setzen, da ich davon ausgehe, dass das keine schöne Lösung ist.
    Wenn ich auf Null geklickt habe und die Enter-Taste drücke, wird so lange die 0 in eingegeben, bis ich die Return-Taste loslasse. Erst danach wird mein KeyDown-Ereignis ausgeführt.

    Wo setze ich an? Was sollte ich tun, damit das Key Ereignis zuvor überprüft wird?


    VB.NET-Quellcode

    1. Private Sub frmMeineForm_KeyDown(ByVal sender As Object, _
    2. ByVal e As System.Windows.Forms.KeyEventArgs) _
    3. Handles Me.KeyDown
    4. Select Case e.KeyCode
    5. Case Keys.D0, Keys.NumPad0
    6. cmdNull.PerformClick()
    7. Case Keys.D1, Keys.NumPad1
    8. cmdEins.PerformClick()
    9. Case Keys.Enter
    10. cmdEnter.PerformClick()
    11. End Select
    12. End Sub
    prima!
    die Tastatur-Events behandelst du nun wies halt vorgesehen ist.
    Zu allem weitern kann man nix sagen - man sieht ja nur, dass bei verschiedenen TastenDrücken von verschiedenen Buttons die Klickse ausgeführt werden.
    Was in diesen Klicksen passiert und was passieren soll, teilst du ja nicht mit, oder wenn doch, so mir vollkommen unverständlich.
    Ich habe leider kein bestimmtes Projekt, das ich angehe, aber wohl oder übel werde demnächst ich einen Taschenrechner programmieren, wie es mir scheint. Folgender Programmablauf ergibt keinen Sinn, aber es geht mir nur um die Übung Tastatur-Ereignisse.

    Das KeyDown-Ereignis wird erst ausgelöst, nachdem ich die Enter-Taste losgelassen habe.
    Wenn der Fokus gerade auf cmdEins ist, wird dieser solange in die TextBox geschrieben, bis ich die Enter-Taste loslasse.

    VB.NET-Quellcode

    1. Public Class frmMeineForm
    2. Private Sub cmdNull_Click(sender As Object, e As EventArgs) Handles cmdNull.Click
    3. Dim cmdNull As Button = TryCast(sender, Button)
    4. txtTextBox.Text += cmdNull.Text
    5. End Sub
    6. Private Sub cmdEins_Click(sender As Object, e As EventArgs) Handles cmdEins.Click
    7. Dim cmdEins As Button = TryCast(sender, Button)
    8. txtTextBox.Text += cmdEins.Text
    9. End Sub
    10. Private Sub cmdEnter_Click(sender As Object, e As EventArgs) Handles cmdEnter.Click
    11. Dim cmdEnter As Button = TryCast(sender, Button)
    12. Dim dErsteZahl As Double
    13. dErsteZahl = CDbl(txtTextBox.Text)
    14. dErsteZahl += dErsteZahl
    15. txtTextBox.Text = dErsteZahl.ToString
    16. End Sub
    17. Private Sub frmMeineForm_KeyDown(ByVal sender As Object, _
    18. ByVal e As System.Windows.Forms.KeyEventArgs) _
    19. Handles Me.KeyDown
    20. Select Case e.KeyCode
    21. Case Keys.D0, Keys.NumPad0
    22. cmdNull.PerformClick()
    23. Case Keys.D1, Keys.NumPad1
    24. cmdEins.PerformClick()
    25. Case Keys.Enter
    26. cmdEnter.PerformClick()
    27. End Select
    28. End Sub
    29. End Class
    Nun ja, wenn ich mir den Windows 7 Rechner anschaue:
    Drücke ich dort auf eine Zahl klicke und dann auf die Enter-Taste, wird wie in meinem Übungscode cmdEnter.PerformClick() ausgeführt.
    Wenn ich aber in meinem Übungsprojekt eine Zahl eingebe und dann auf Enter drücke, wird die Zahl weiterhin zum TextBox hinzugefügt, ohne cmdEnter.PerformClick() auszuführen.
    Richtig, genau das meinte ich. Der Haltepunkt wird mit der Enter-Taste nicht erreicht. :)
    Mit den Tasten 0 und 1 aber schon.
    Egal ob KeyDown, KeyUp oder KeyPress-Ereignis.
    UPDATE: Wenn ich in die TextBox reinklicke und dann Enter drücke, läuft der Code zum Haltepunkt rein. Da ich die TextBox.Enabled auf False gesetzt habe, kann ich natürlich nicht reinklicken.
    Wenn ich dann cmdEnter.Focus() in die Click-Ereignisse einfüge, setze ich den Focus immer auf cmdEnter. Dann klappt es, aber das scheint keine gute Lösung zu sein.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Public Class frmMeineForm
    4. Private Sub cmdNull_Click(sender As Object, e As EventArgs) Handles cmdNull.Click
    5. txtTextBox.Text += cmdNull.Text
    6. cmdEnter.Focus()
    7. End Sub
    8. Private Sub cmdEins_Click(sender As Object, e As EventArgs) Handles cmdEins.Click
    9. txtTextBox.Text += cmdEins.Text
    10. cmdEnter.Focus()
    11. End Sub
    12. Private Sub cmdEnter_Click(sender As Object, e As EventArgs) Handles cmdEnter.Click
    13. Dim dErsteZahl As Double
    14. dErsteZahl = CDbl(txtTextBox.Text)
    15. dErsteZahl += dErsteZahl
    16. txtTextBox.Text = dErsteZahl.ToString
    17. End Sub
    18. Private Sub frmMeineForm_KeyDown(ByVal sender As Object, _
    19. ByVal e As System.Windows.Forms.KeyEventArgs) _
    20. Handles Me.KeyDown
    21. Select Case e.KeyCode
    22. Case Keys.D0, Keys.NumPad0
    23. cmdNull.PerformClick()
    24. Case Keys.D1, Keys.NumPad1
    25. cmdEins.PerformClick()
    26. Case Keys.Enter
    27. cmdEnter.PerformClick()
    28. End Select
    29. End Sub
    30. End Class

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

    In das PreviewKeyDown-Ereignis kommt der Debugger nicht rein. Mache ich etwas falsch?

    'An diesen Haltepunkt kommt der Debugger gar nicht erst hin

    VB.NET-Quellcode

    1. Private Sub frmMeineForm_PreviewKeyDown(ByVal sender As Object, ByVal e As PreviewKeyDownEventArgs)
    2. Select Case (e.KeyCode)
    3. Case Keys.Enter
    4. e.IsInputKey = True
    5. End Select
    6. End Sub


    Hier auch nicht

    VB.NET-Quellcode

    1. Private Sub cmdEnter_PreviewKeyDown(ByVal sender As Object, ByVal e As PreviewKeyDownEventArgs)
    2. Select Case (e.KeyCode)
    3. Case Keys.Enter
    4. e.IsInputKey = True
    5. End Select
    6. End Sub


    So auch nicht:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Imports System
    4. Imports System.Windows
    5. Imports System.Windows.Input
    6. Public Class frmMeineForm
    7. Private Sub cmdNull_Click(sender As Object, e As EventArgs) Handles cmdNull.Click
    8. txtTextBox.Text += cmdNull.Text
    9. cmdEnter.Focus()
    10. End Sub
    11. Private Sub cmdEins_Click(sender As Object, e As EventArgs) Handles cmdEins.Click
    12. txtTextBox.Text += cmdEins.Text
    13. cmdEnter.Focus()
    14. End Sub
    15. Private Sub cmdEnter_Click(sender As Object, e As EventArgs) Handles cmdEnter.Click
    16. Dim dErsteZahl As Double
    17. dErsteZahl = CDbl(txtTextBox.Text)
    18. dErsteZahl += dErsteZahl
    19. txtTextBox.Text = dErsteZahl.ToString
    20. End Sub
    21. Private Sub frmMeineForm_KeyDown(ByVal sender As Object, _
    22. ByVal e As System.Windows.Forms.KeyEventArgs) _
    23. Handles Me.KeyDown
    24. Select Case e.KeyCode
    25. Case Keys.D0, Keys.NumPad0
    26. cmdNull.PerformClick()
    27. Case Keys.D1, Keys.NumPad1
    28. cmdEins.PerformClick()
    29. Case Keys.Enter
    30. cmdEnter.PerformClick()
    31. End Select
    32. End Sub
    33. Private Sub frmMeineForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    34. AddHandler txtTextBox.PreviewKeyDown, AddressOf MTXTP
    35. End Sub
    36. Private Sub MTXTP(ByVal sender As Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles txtTextBox.PreviewKeyDown
    37. MsgBox("OK")
    38. End Sub
    39. End Class



    ohne Handles-Klausel wird das nix.
    Wie konnte das passieren, dass du die vergessen hast? Hast du das Video auf Alles über Events mal angeguckt?
    Wenn man standard-mäßig Events behandelt, kriegt man die Handles-Klausel doch generiert.

    Ups - jetzt in den Spoiler geguckt - da ist ja Handles Klausel bzw. AddHandler.

    kannst du das Projekt mal zippen und anhängen? Imo müsste das funzen.
    Meinst du, dass dieser Code erreicht wird? Das ist seltsam, denn bei mir wird das KeyDown-Ereignis mit der Enter-Taste nicht erreicht.

    VB.NET-Quellcode

    1. Case Keys.Enter
    2. cmdEnter.PerformClick()


    Dass cmdEnter.Click-Ereignis ausgeführt wird, liegt daran, dass innerhalb der beiden anderen Buttons der Fokus auf diesen cmdEnter-Button gelegt wird. Nachdem du die 1 angeklickt hast. hat cmdenter den Fokus.

    VB.NET-Quellcode

    1. Private Sub cmdEins_Click(sender As Object, e As EventArgs) Handles cmdEins.Click
    2. txtTextBox.Text += cmdEins.Text
    3. cmdEnter.Focus()
    4. End Sub

    Ich glaube aber nicht, dass das eine saubere Lösung ist, da ich die Enter-Taste dadurch nicht wirklich abgreife.