Seite 1 von 2
GetAsyncKeyState_() zu langsam?
Verfasst: 28.07.2010 15:40
von Tombi
Liebe Community,
habe bisher eine nervige Erfahrung gemacht und bisher keine Lösung gefunden.
Code:
Code: Alles auswählen
Global hWindow,hook
Global Dim Array.b(256)
Structure KBDLLHOOKSTRUCT
vkCode.l
scanCode.l
flags.l
time.l
dwExtraInfo.l
EndStructure
Global HWND = 0
Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
Char.s = Space(1)
If nCode = #HC_ACTION
If wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP Or wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN
If GetAsyncKeyState_(#VK_ESCAPE) ;Escape pressed
UnhookWindowsHookEx_(hook)
End
EndIf
GetKeyboardState_(@Array())
If GetAsyncKeyState_(#VK_SHIFT) Or GetKeyState_($14) > 0
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@dummy, @Char.s,0,GetKeyboardLayout_(0));
Else
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@array(), @Char.s,0,GetKeyboardLayout_(0));
EndIf
If Check.i And wParam = #WM_KEYUP
Debug Char.s
EndIf
EndIf
EndIf
ProcedureReturn CallNextHookEx_(hook, nCode, wParam, *p)
EndProcedure
#WH_KEYBOARD_LL = 13
hook = SetWindowsHookEx_(#WH_KEYBOARD_LL,@myKeyboardHook(),GetModuleHandle_(0),0)
If hook = 0: End: EndIf
hWindow = OpenWindow(1,0,0,0,0,"k8D h00K",#PB_Window_Invisible)
Repeat
WaitWindowEvent()
ForEver
Probiert es selber aus..
Bei der schnellen(!) Eingabe von "Test" erfolgt des öfteren der Text "test" statt "Test".
Ist ja noch in Ordnung. Nur bei Zeichen wie "ß" statt "?" ist es einfach nervig.
Bei langsamer Eingabe bzw längerem drücken der SHIFT-Taste passiert das nicht,
dann funktioniert immer alles. Aber ich bin einer der schnelleren Sorte
Jemand ne Idee, das besser zu lösen?
Code stammt hier aus dem Forum, um es eben mal zu zeigen, was ich meine
MFG,
Tombi
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 28.07.2010 16:18
von alter Mann
probier mal das hier
Code: Alles auswählen
Global hWindow,hook
Global Dim bArray.b(256)
Structure KBDLLHOOKSTRUCT
vkCode.l
scanCode.l
flags.l
time.l
dwExtraInfo.l
EndStructure
Global HWND = 0
Global Layout.i
Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
Char.s = Space(1)
If nCode = #HC_ACTION
If wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP Or wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN
GetKeyboardState_(@bArray())
If *p\vkCode = #VK_ESCAPE ;Escape pressed
UnhookWindowsHookEx_(hook)
End
EndIf
If bArray(#VK_SHIFT)
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@dummy, @Char.s,0,Layout);
Else
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@bArray(), @Char.s,0,Layout);
EndIf
If Check.i And wParam = #WM_KEYUP
Debug Char.s
Debug *p\scanCode
EndIf
EndIf
EndIf
ProcedureReturn CallNextHookEx_(hook, nCode, wParam, *p)
EndProcedure
Layout = GetKeyboardLayout_(0)
#WH_KEYBOARD_LL = 13
hook = SetWindowsHookEx_(#WH_KEYBOARD_LL,@myKeyboardHook(),GetModuleHandle_(0),0)
If hook = 0: End: EndIf
hWindow = OpenWindow(1,0,0,0,0,"k8D h00K",#PB_Window_Invisible)
Repeat
WaitWindowEvent()
ForEver
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 28.07.2010 16:21
von Tombi
Alles Großbuchstaben.
Wenn ich diese Zeile entferne aus deinem Code:
Alles Kleinbuchstaben
MFG,
Tombi
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 28.07.2010 20:42
von alter Mann
ich habe noch mal ein bisschen rumexperimentiert und bin jetzt etwas verwirrt
Code: Alles auswählen
Global hWindow,hook
Global Dim bArray.b(255)
Structure KBDLLHOOKSTRUCT
vkCode.l
scanCode.l
flags.l
time.l
dwExtraInfo.l
EndStructure
Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
Char.s = Space(1)
If nCode = #HC_ACTION
If wParam = #WM_KEYUP ;Or wParam = #WM_SYSKEYUP Or wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN
If GetAsyncKeyState_(#VK_ESCAPE) ;Escape pressed
UnhookWindowsHookEx_(hook)
End
EndIf
If GetAsyncKeyState_(#VK_SHIFT)
Check = ToAscii_(*p\vkCode,*p\scanCode.l,@dummy, @Char.s,0)
Else
Check.i=ToAscii_(*p\vkCode,*p\scanCode.l,@bArray(), @Char.s,0);
EndIf
If Check.i
SetGadgetText(1, "Buchstabe : "+Char.s)
Debug Char
EndIf
EndIf
EndIf
ProcedureReturn CallNextHookEx_(hook, nCode, wParam, *p)
EndProcedure
#WH_KEYBOARD_LL = 13
hook = SetWindowsHookEx_(#WH_KEYBOARD_LL,@myKeyboardHook(),GetModuleHandle_(0),0)
If hook = 0: End: EndIf
hWindow = OpenWindow(1,0,0,200,50,"k8D h00K",#PB_Window_BorderLess|#PB_Window_ScreenCentered)
TextGadget(1,5,5,150,30,"Buchstabe : ")
Repeat
WaitWindowEvent()
ForEver
Hiermit geht es bei mir erstmal. Allerdings gibt es ein paar Merkwürdigkeiten:
- wenn man dummy mit einem Wert belegt kommen nur Kleinbuchstaben
- bArray() muss nicht vorbelegt werden (GetKeyboardState_ brauch nicht aufgerufen werden)
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 28.07.2010 22:00
von Tombi
Keine Änderung:
Bei schnellen Eingaben werden großgeschriebene Zeichen (genutzte SHIFT-Taste) automatisch klein.
Der Befehl zu langsam? Wo ist das Problem?
Getestet auf WinXP Pro SP3 mit PB 4.40 x86
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 28.07.2010 22:55
von alter Mann
kann ich nicht bestätigen (vielleich bin ich auch zu langsam

), mach mal 'ne exe draus, vielleicht ist der Debugger schuld
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 29.07.2010 00:23
von freak
Das Mischen von GetAsyncKeyState_() und GetKeyState_() ist der Fehler. Der erste Befehl gibt den aktuellen Zustand der Hardware wieder und der zweite gibt den aktuellen Zustand in der Input-Queue des Prozesses wieder. Die Queue ist dem tatsächlichen Zustand hinterher wenn das Programm viel zu tun hat. In diesem Fall (mit hook) macht die asynchrone Version überhaupt keinen Sinn. Also nur GetKeyState_() verwenden und es sollte gehen.
Auserdem sind die Aufrufe falsch:
Das ist falsch. Es muss heißen:
Code: Alles auswählen
If GetAsyncKeyState_(#VK_ESCAPE) & $8000 ; Escape pressed
Die Funktion gibt eine (16bit) Bitmaske zurück bei der nur das höchste bit bedeutet "die Taste ist gedrückt". Das niedrigste bit bedeutet "Taste gedrückt seit letztem Aufruf", auf was man sich aber nicht verlassen kann (siehe:
http://msdn.microsoft.com/en-us/library/ms646293.aspx)
Das gleiche gilt für GetKeyState_().
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 29.07.2010 12:33
von Tombi
Naja... hab ich was vergessen was du meinst?
Weiterhin habe ich das Problem:
Wenn ich schnell tippe (naja, meine 600 Anschläge pro Minute sind eben doch zu schnell

),
wird die SHIFT-Taste nicht registriert und dadurch der Text klein statt groß erfasst...
Aus "Ich teste diese Programm!" wird bei schnellem tippen eben dann schnell mal "Ich teste dieses programm1".
Wenn ich langsamer tippe, wird es richtig erfasst.
Wo liegt das Problem?

Wir brauchen Speed ... keine Drogen
MFG,
Tombi
Edit: Ups, Code vergessen. Hier:
Code: Alles auswählen
;- PureBasic 4.50 (x86)
;
Global hWindow,hook
Global Dim Array.b(256)
Structure KBDLLHOOKSTRUCT
vkCode.l
scanCode.l
flags.l
time.l
dwExtraInfo.l
EndStructure
Global HWND = 0
Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
Char.s = Space(1)
If nCode = #HC_ACTION
If wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP Or wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN
If GetAsyncKeyState_(#VK_ESCAPE) & $8000 ;Escape pressed
UnhookWindowsHookEx_(hook)
End
EndIf
GetKeyboardState_(@Array())
If GetKeyState_($14) > 0
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@dummy, @Char.s,0,GetKeyboardLayout_(0));
Else
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@array(), @Char.s,0,GetKeyboardLayout_(0));
EndIf
If Check.i And wParam = #WM_KEYUP
Debug Char.s
EndIf
EndIf
EndIf
ProcedureReturn CallNextHookEx_(hook, nCode, wParam, *p)
EndProcedure
#WH_KEYBOARD_LL = 13
hook = SetWindowsHookEx_(#WH_KEYBOARD_LL,@myKeyboardHook(),GetModuleHandle_(0),0)
If hook = 0: End: EndIf
hWindow = OpenWindow(1,0,0,0,0,"k8D h00K",#PB_Window_Invisible)
Repeat
WaitWindowEvent()
ForEver
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 29.07.2010 12:45
von Tombi
Sorry wegen Doppelpost, möchte aber nicht den vorherigen Beitrag so lang ziehen...
Hoffe das geht in Ordnung
Habe hier mal ein kleines Fenster gebastelt. Bitte mal selber austesten.
Bei schnellen Eingaben wird der Großbuchstabe schnell mal zum Kleinbuchstaben...
Code: Alles auswählen
; PureBasic 4.50 x86
;- Window Constants
;
Enumeration
#Window_0
EndEnumeration
;- Gadget Constants
;
Enumeration
#text
EndEnumeration
Global hWindow,hook
Global Dim Array.b(256)
Structure KBDLLHOOKSTRUCT
vkCode.l
scanCode.l
flags.l
time.l
dwExtraInfo.l
EndStructure
If OpenWindow(#Window_0, 255, 175, 600, 300, "Test", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
TextGadget(#text, 50, 30, 490, 220, "")
EndIf
Procedure.l myKeyboardHook(nCode, wParam, *p.KBDLLHOOKSTRUCT)
Char.s = Space(1)
If nCode = #HC_ACTION
If wParam = #WM_KEYUP Or wParam = #WM_SYSKEYUP Or wParam = #WM_KEYDOWN Or wParam = #WM_SYSKEYDOWN
GetKeyboardState_(@Array())
If GetKeyState_($14) > 0
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@dummy, @Char.s,0,GetKeyboardLayout_(0));
Else
Check.i=ToAsciiEx_(*p\vkCode,*p\scanCode.l,@array(), @Char.s,0,GetKeyboardLayout_(0));
EndIf
If Check.i And wParam = #WM_KEYUP
SetGadgetText(#text, GetGadgetText(#text)+char.s)
EndIf
EndIf
EndIf
ProcedureReturn CallNextHookEx_(hook, nCode, wParam, *p)
EndProcedure
#WH_KEYBOARD_LL = 13
hook = SetWindowsHookEx_(#WH_KEYBOARD_LL,@myKeyboardHook(),GetModuleHandle_(0),0)
If hook = 0: End: EndIf
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_CloseWindow
Quit = 1
EndIf
Until Quit = 1
(Sry, war nur schnell zusammengeflickt. Kein besonderst schöner Code

)
Re: GetAsyncKeyState_() zu langsam?
Verfasst: 29.07.2010 15:40
von alter Mann
Wahrscheinlich nur ein Verständnisproblem. Du reagierst auf KEY_UP, die meisten Editoren aber auf KEY_DOWN.