# Tastenerkennung



## Fr3dd1 (14. Juni 2006)

Jeder kennt es:

Man stellt ein Programm/Spiel ein und kommt dahin das man die Funktionen mit Tasten belegen muss.
SOOOOOO das war der Vorspann / Vorspam
Wie mache ich es, wenn ich es so mache will das jemand eine Listbox auswählt eine Taste drückt und die darin erscheint oder das man auf die maus klickt etc.

thx Freddy


----------



## Fr3dd1 (17. Juni 2006)

weiss keiner wie das geht?


----------



## Shakie (17. Juni 2006)

Kannst du das bitte nochmal auf Deutsch schreiben? Ich versteh kein Wort.


----------



## Blatt (17. Juni 2006)

Ich denk ma freddi will sowas, wie z.b. aus spielen [counter strike -> optionen -> Steuerung, Du klickst auf das Feld, Drückst eine Taste und diese erscheint dann im Feld und Wird in eine Variable gesetzt], machen.


----------



## Shakie (17. Juni 2006)

Und wo ist das Problem dabei?


----------



## Fr3dd1 (18. Juni 2006)

Das dass auch bei Maustatsten und Tasten wie Tab,Shift, Leertaste usw funktioniert


----------



## Shakie (18. Juni 2006)

Maustasten und Tastaturtasten musst du getrennt abfragen. Die Tastaturtasten kannst du über das KeyDown und KeyUp-Ereignis abfangen. (siehe z.B. hier)


----------



## Fr3dd1 (18. Juni 2006)

und wie geht das bei maustatsen bzw geht das was du mir gepostet hast auch bei leertatse usw?


----------



## Shakie (18. Juni 2006)

Das KeyDown-Ereignis wird immer dann ausgelöst, wenn *irgend eine* Taste gedrückt wird. Das KeyUp-Ereignis tritt ein, wenn ein Taste losgelassen worden ist.
Für die Maus gibt es auch MouseDown und MouseUp-Ereignisse.


----------



## Fr3dd1 (18. Juni 2006)

ich hab nun zwie ereignisse verschachtelt:


Private Sub List1_Click()
Private Sub List1_KeyPress(KeyAscii As Integer)
If KeyCode = KeyCodeConstants.vbKeyW Then
List1.List = "W"
End Sub
End Sub

So nun zeigt der mir immer an (wenn ich die listbox füllen will):
Argument nor Optional

was hab ich falsch gemacht?


----------



## Shakie (18. Juni 2006)

Dein Code ergibt keinen Sinn. Was verstehst du unter "zwei ereignisse verschachteln"?
Des weiteren kann man keine Sub in einer anderen Sub erstellen.

Kann es sein, dass du einfach nur herausfinden willst, welche Taste gedrückt worden ist?
Dann kannst du das so machen:

```
Private Sub Form_KeyPress(KeyAscii As Integer)
    List1.AddItem VBA.Chr(KeyAscii)
End Sub
```

Ich denke, du solltest auch mal ein paar VB-Tutorials durchmachen um das Programmier-Prinzip zu verstehen.


----------



## Fr3dd1 (19. Juni 2006)

ja ich will das man ERST die listbox anklickt und man DANACH eine Taste drückt und diese gespeichert wird.


----------



## Shakie (19. Juni 2006)

Dann nimm halt statt dem KeyPress-Ereignis der Form wie in meinem Beispiel das KeyPress-Ereignis der Listbox. Das KeyPress-Ereignis eines Controls kann erst ausgelöst werden, wenn das Control den Fokus hat. Dies geschieht entweder durch Anklicken oder auch durch die Tabulatortaste. Insofern ist es nicht nötig, Ereignisse zu "verschachteln", was übrigens auch gar nicht geht.


----------



## Fr3dd1 (19. Juni 2006)

aso ja danke wusste das mit dem Fokus net thx


----------



## Fr3dd1 (19. Juni 2006)

So noch en Frage, ich hab das soweit schon alles fertig aber fehlen mir noch die "Spezial" Tasten wie Leertaste etc. Ich wolte die nun mit einer If abfrage abfragen Code:

Private Sub List1_KeyPress(KeyAscii As Integer)
 List1.Clear
 List1.AddItem VBA.Chr(KeyAscii)
 If KeyCode = KeyCodeConstants.vbKeySpace Then
 List1 = "Leer"
End If
End Sub

Es wird auch kein Fehler angezeigt sondern, das "Leer" wird nicht in die Box geschrieben wie muss ich das machen?


----------



## Shakie (19. Juni 2006)

Du hast das AddItem vergessen. Normalerweise sollte an der stelle List1="Leer" von der Entwicklungsumgebung ein Fehler ausgegeben werden.
Überprüfe mal, ob bei dir in den Code-Fenstern ganz oben an aller erster Stelle folgendes steht:
	
	
	



```
Option Explicit
```
 Sollte das nicht der Fall sein, so solltest du es auf alle Fälle hinschreiben. Fehlt "Option Explicit", dann erstellt VB automatisch Variablen vom Typ Variant, falls du diese nicht irgendwo mit Dim... definiert hast. Das hat zur Folge, dass man durch den Code nicht mehr durchblickt. Außerdem braucht man nicht allzu häufig Variant-Variablen.
Das heißt, VB wird bei dir eine Variable namens "List1" erstellt haben und diese Variable mit dem Text "Leer" gefüllt haben.
Schau dir das hier mal an.


----------



## Blatt (19. Juni 2006)

```
Private Sub List1_KeyPress(KeyAscii As Integer)
List1.Clear
List1.AddItem Chr(KeyAscii)
If KeyAscii = vbKeySpace Then
List1.AddItem "Leer"
End If
End Sub
```

oder


```
Private Sub List1_KeyDown(KeyCode As Integer, Shift As Integer)
List1.Clear
List1.AddItem Chr(KeyCode)
If KeyCode = vbKeySpace Then
List1.AddItem "Leer"
End If
End Sub
```


----------



## Shakie (20. Juni 2006)

Beide Varianten funktionieren. KeyPress wird nur bei Buchstaben- und Zahlentasten (praktisch alle Tasten die man zum schreiben eines Textes braucht) ausgelöst, während KeyDown bei wirklich allen Tasten ausgelöst wird (also auch bei Pfeiltasten, Enter, Escape, usw.)


----------



## Fr3dd1 (21. Juni 2006)

soweit funtzt das nun aber ich bekomme space net hin da kommt immer son " | ".
Ach udn wisst ihr zufällig wo ich die namen der Tasten herbekome sonst google ich.
THX
Freddy


----------



## Shakie (21. Juni 2006)

Es gibt eine API-Funktion, die heißt "GetKeyNameText". Diese liefert dir den Namen einer Taste.
Kleines Beispiel:

```
Option Explicit

Private Declare Function GetKeyNameText Lib "user32" Alias "GetKeyNameTextA" (ByVal lParam As Long, ByVal lpBuffer As String, ByVal nSize As Long) As Long
Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim ScanCodeLng As Long
    Dim ScanCodeByte(3) As Byte
    Dim lParamLng As Long
    Dim lParamByte(3) As Byte
    Dim TmpBuffer As String * 256
    
    'Scancode ermitteln (tastaturspezifische Tasten-ID)
    ScanCodeLng = MapVirtualKey(KeyCode, 0)
    CopyMemory ScanCodeByte(0), ScanCodeLng, 4

    'lParam zusammenbauen
    lParamByte(0) = 1
    lParamByte(2) = ScanCodeByte(0)
    CopyMemory lParamLng, lParamByte(0), 4

    'Text der Taste ermitteln
    GetKeyNameText lParamLng, TmpBuffer, Len(TmpBuffer)

    Me.Caption = TmpBuffer
End Sub
```
Allerdings sind die Tastennamen nicht besonders hübsch...und manche Tasten haben den gleichen Namen (z.B die Ende-Taste auf dem Num-Block und die "andere" Ende-Taste haben den gleichen Namen. Probier es einfach aus.


			
				Fr3dd1 hat gesagt.:
			
		

> Ach udn wisst ihr zufällig wo ich die namen der Tasten herbekome sonst google ich.


 Normalerweise solltest du *erst* googlen und *dann* hier nachfragen.


----------



## Fr3dd1 (22. Juni 2006)

gut man kann es als faul verstehen ansichtssache aber warum soll man suchen wenn man einfach fragen kann ob wer was weiss (warum soll ich meinen Schlüßel suchen wenn meine freundin weiss wo er si dummes bsb aber egal^^)

mfg Freddy

EDIT:
wird der Name der Taste in der TmpBuffer variable gespeicher tich verstehe den code net so ganz


----------



## Shakie (23. Juni 2006)

Ehrlich gesagt, ich hab den Code auch nur aus dem Internet.
Aber er funktioniert ungefähr so:
Die API "MapVirtualKey" erstellt eine tastaturspezifische Tasten-ID (keine Ahnung was das ist ^^)
Mit "CopyMemory" wird das Ergebnis von "MapVirtualKey" in das Array "ScanCodeByte" kopiert und später etwas verändert in die Long-Variable "lParamLng".
Nun steht in "lParamLng" eine Zahl, die die Taste identifiziert und mit der die API "GetKeyNameText" etwas anfangen kann. Diese schreibt dann den Namen der Taste in die Variable "TmpBuffer".


----------



## Fr3dd1 (23. Juni 2006)

so bei der Leertaste funktioniert das ja auch aber bei der Enter-, tab-, shift- Taste und dieversen anderen eben nicht kann da keiner weiterhelfen?


----------



## Shakie (26. Juni 2006)

Verwendest du das KeyDown- oder KeyPress-Ereignis?
Verwendest du das Ereignis der Form oder eines Steuerelements auf der Form? Wenn du das Ereignis der Form verwendest, dann stelle die "KeyPreview"-Eigenschaft der Form auf "TRUE". Dies bewirkt, dass alle Tastenanschläge zuerst an die Key-Ereignisse der Form gesendet werden, auch wenn ein Steuerelement gerade den Fokus besitzt.


----------

