Seite 1 von 3
getasynckeystate probleme/fragen
Verfasst: 20.06.2008 16:58
von orderinchaos
Hi !
Hab noch ein Problem das ich seit Stunden zu lösen versuche:
Wie kann ich mit getasynckeystate auslesen ob ein Buchstabe gross (A) oder klein (a) geschrieben wurde?
Ich habs so versucht:
Code: Alles auswählen
if getasynckeystate_(#VK_A) and getasynckeystate_(#VK_SHIFT)
Hat auch funktioniert, aber wirklich sicher und sauber ist diese Lösung bestimmt nicht.... vorallem wenn CAPSLOCK eingeschaltet ist, werden trotzdem alle keys in kleinbuchstaben ausgelesen....
Welche Möglichkeiten hab ich denn sonst noch? Wurde bis jetzt nirgends fündig.....
und nochmals ne kurze Frage:
mit
wird die IF-Schleife erst ausgeführt wenn die taste released wurde, richtig?
oder gibt's ne bessere alternative?
bin übrigens winapi beginner, also nehmt's mir nicht übel....
Vielen Dank schon mal!

Verfasst: 21.06.2008 19:26
von Kai
Zu 2. kann ich dir meine Methode vorschlagen, vieleicht hilft es ja.
Code: Alles auswählen
EnableExplicit
Structure _vkKeyReleased
vkKey.l
state.b
EndStructure
Global NewList vkKeyReleased._vkKeyReleased()
;AddChecked Keys
Define lNext.l
For lNext = 48 To 57 : AddElement(vkKeyReleased()): vkKeyReleased()\vkKey = lNext : Next ;0 - 9
For lNext = 65 To 90 : AddElement(vkKeyReleased()): vkKeyReleased()\vkKey = lNext : Next ;A - Z
For lNext = 112 To 135 : AddElement(vkKeyReleased()): vkKeyReleased()\vkKey = lNext : Next ;F1 - F24
AddElement(vkKeyReleased()): vkKeyReleased()\vkKey = #VK_SPACE ;Space
AddElement(vkKeyReleased()): vkKeyReleased()\vkKey = #VK_ESCAPE ;Escape
Procedure GetAsyncKeyStateReleased(vkKey)
Protected lNext.l, lIndex.l = -1
ForEach vkKeyReleased()
If vkKeyReleased()\vkKey = vkKey
lIndex = lNext: Break
EndIf
Next
If lIndex > -1
If GetAsyncKeyState_(vkKey) & $8000
If vkKeyReleased()\state = 0
vkKeyReleased()\state = 1
ProcedureReturn 0
EndIf
Else
If vkKeyReleased()\state = 1
vkKeyReleased()\state = 0
ProcedureReturn 1
EndIf
EndIf
EndIf
EndProcedure
;Example
Repeat
If GetAsyncKeyStateReleased(#VK_A)
Debug "A"
EndIf
If GetAsyncKeyStateReleased(#VK_B)
Debug "B"
EndIf
Delay(2)
Until GetAsyncKeyStateReleased(#VK_ESCAPE)
Verfasst: 22.06.2008 22:10
von orderinchaos
thx, das sieht ganz gut aus..!!
war mir echt ne hilfe!!
zum ersten punkt weiss niemand was?
Verfasst: 22.06.2008 22:20
von Kaeru Gaman
Get(Async)KeyState berichtet nunmal einen Tastaturstatus, keine Zeicheneingabe.
und eine Taste hat kein Groß/Klein Zustand.
CAPSLOCK musst du halt mitschreiben,
bzw. dafür gibts in der API bestimmt auch irgendwo ne Funktion wo du den Zustand erfragen kannst,
wie auch für die NUM-Taste.
wenn du Texteingaben haben willst, musst du halt ein paar Ebenen höher deine Informationen besorgen,
nicht ganz unten beim Hardwarehandling, was KeyStates nunmal sind.
Verfasst: 23.06.2008 01:41
von orderinchaos
okay, danke für deine hilfe
dann muss ich wohl oder übel alle tasten abfragen....
thx, nochmals
Verfasst: 23.06.2008 02:11
von Kaeru Gaman
schau dir mal GetKeyboardState_() an.
damit fragst du die komplette Tastatur in einem Aufruf ab.
der Status wird in einem 256byte-Array abgelegt.
du könntest also ein bytearray erzeugen
übergibst den pointer auf das array an GetKeyboardState,
und kannst danach bequem alle tasten mit Key(#Taste) abfragen.
der Vorteil:
es wird zu genau einem Zeitpunkt der Keyboardstatus ermittelt.
wenn du mehrere Aufrufe von Get(Async)Keystate benutzt,
wird jedesmal erneut der aktuelle Keystatus ermittelt.
Verfasst: 25.06.2008 18:59
von orderinchaos
das klingt nach genau dem was ich suche!! nur leider bin ich im moment ein wenig überfragt...
ich werd jedoch einen weiteren versuch mit deiner idee starten... vielleicht hast du noch ein codebeispiel für mich? wäre sehr hilfreich!!
vielen dank nochmals für all diese tipps!
Verfasst: 27.06.2008 11:11
von Andreas
Code: Alles auswählen
Macro GetBit(value,bit)
(value>>bit&1)
EndMacro
Dim States.b(255)
If OpenWindow(0, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
Repeat
EventID = WaitWindowEvent()
If EventID = #WM_KEYUP
If EventwParam() > 64 And EventwParam() < 91
GetKeyboardState_(@States(0))
Select GetBit(States(#VK_CAPITAL),0)
Case 0
Select GetBit(States(#VK_SHIFT),7)
Case 0
Debug LCase(Chr(EventwParam()))
Case 1
Debug UCase(Chr(EventwParam()))
EndSelect
Case 1
Select GetBit(States(#VK_SHIFT),7)
Case 0
Debug UCase(Chr(EventwParam()))
Case 1
Debug LCase(Chr(EventwParam()))
EndSelect
EndSelect
EndIf
EndIf
If EventID = #PB_Event_CloseWindow
Quit = 1
EndIf
Until Quit = 1
EndIf
End
Verfasst: 27.06.2008 13:20
von orderinchaos
das ist doch mal eine schöne arbeit
herzlichen dank, funktioniert bei mir richtig doll.....
aber genau verstehen was hier abgeht tu ich nicht. wie könnt ich jetzt zum beispiel noch alle zahlen (0-9) einbauen? da muss ich die EventwParam schleife einfach grösser machen, richtig?
oder muss ich da ne ganz neue schleife machen? genau so wie für die space taste und enter?
thx, auf jedenfall... hilft mir sehr weiter!!

Verfasst: 27.06.2008 13:48
von Kaeru Gaman
@Andreas: danke fürs Beispiel
@orderinchaos
er prüft hier den Capslock-Status, vergleicht das mit Shift-Status,
und gibt dementsprechend die aktuell gedrückte taste als groß oder klein aus.
mit dem ganzen reagiert er auf das loslassen einer taste,
If EventID = #WM_KEYUP steht als rahmenbedingung drumrum.
das ist für die Demo hier wichtig, aber je nachdem was du nachher machen willst, musst du das anders gliedern.
wenn du es fürs erste dabei belassen willst,
> wie könnt ich jetzt zum beispiel noch alle zahlen (0-9) einbauen?
> da muss ich die EventwParam schleife einfach grösser machen, richtig?
das ist keine schleife sondern eine bedingung (wichtig! die richtigen begriffe verwenden)
aber ja, die umfassen im moment nur die Buchstaben, für zahlen musst du deren codes noch hinzunehmen.