reliable way to detect key state?
reliable way to detect key state?
I need to find out if keys are pressed (alt,ctrl, shift) (individually or combinations...)
I tried to use GetKeyState_(); but this seem to record a value and hold it, not always releasing it back to 0 when the key is released.
I tried a keyboard hook, but that seemed to screw up if keys are pressed/released quickly (ie: record a 'down' but not the 'up') There's got to be a good way to do this, is there?
I tried to use GetKeyState_(); but this seem to record a value and hold it, not always releasing it back to 0 when the key is released.
I tried a keyboard hook, but that seemed to screw up if keys are pressed/released quickly (ie: record a 'down' but not the 'up') There's got to be a good way to do this, is there?
Re: reliable way to detect key state?
For Windows only, you can do this:
Code: Select all
Macro KeyIsDown(key)
GetAsyncKeyState_(key) & $8000
EndMacro
Macro KeyIsUp(key)
GetAsyncKeyState_(key)=0
EndMacro
If KeyIsDown(#VK_CONTROL)
; ....do whatever.
EndIf
Re: reliable way to detect key state?
Dude beat me to it.
Bool-ified:
Bool-ified:
Code: Select all
Macro KeyIsDown(key)
Bool(GetAsyncKeyState_(key) & $8000)
EndMacro
Macro KeyIsUp(key)
Bool(Not (GetAsyncKeyState_(key) & $8000))
EndMacro
Re: reliable way to detect key state?
Thanks; I'll try that!
Re: reliable way to detect key state?
It doesn't seem to work inside of a keyboard hook procedure/callback. ;(
despite having 'ctrl' or 'alt' pressed while hitting 'esc'; it only 'sees' the esc key, using getasynckeystate_()&$8000 always says ctrl and alt are not pressed...
I'll try to distill it down to bare essence later and post code to replicate.
despite having 'ctrl' or 'alt' pressed while hitting 'esc'; it only 'sees' the esc key, using getasynckeystate_()&$8000 always says ctrl and alt are not pressed...
I'll try to distill it down to bare essence later and post code to replicate.
- netmaestro
- PureBasic Bullfrog
- Posts: 8433
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: reliable way to detect key state?
Just a bit of tooling around. Code is added to prevent the window minimizing on alt-esc. Should show all combinations of keys currently up/down using the three keys CTRL, ALT, and ESC. You may not need a hook, depending on your goals.
Code: Select all
Enumeration images
#down
#up
EndEnumeration
Enumeration gadgets
#ctrl
#alt
#escape
EndEnumeration
Enumeration message #PB_Event_FirstCustomValue
#buttonevent
EndEnumeration
Enumeration eventtype
#buttondown
#buttonup
EndEnumeration
CreateImage(#down, 64, 32, 24, #Red)
CreateImage(#up, 64, 32, 24, #Green)
Procedure thread(void)
Repeat
If GetAsyncKeyState_(#VK_CONTROL) & 32768
PostEvent(#buttonevent, 0, #ctrl, #buttondown )
Else
PostEvent(#buttonevent, 0, #ctrl, #buttonup )
EndIf
If GetAsyncKeyState_(#VK_MENU) & 32768
PostEvent(#buttonevent, 0, #alt, #buttondown )
Else
PostEvent(#buttonevent, 0, #alt, #buttonup )
EndIf
If GetAsyncKeyState_(#VK_ESCAPE) & 32768
PostEvent(#buttonevent, 0, #escape, #buttondown )
Else
PostEvent(#buttonevent, 0, #escape, #buttonup )
EndIf
Delay(50)
ForEver
EndProcedure
Procedure WinProc(hwnd, msg, wparam, lparam)
result = #PB_ProcessPureBasicEvents
Select msg
Case #WM_ACTIVATEAPP
If wparam = 0
SetForegroundWindow_(hwnd)
ProcedureReturn 0
EndIf
EndSelect
ProcedureReturn result
EndProcedure
Procedure ButtonProc()
If EventType() = #buttondown
SetGadgetState(EventGadget(), ImageID(#down))
Else
SetGadgetState(EventGadget(), ImageID(#up))
EndIf
EndProcedure
OpenWindow(0,0,0,320,240,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
StickyWindow(0, 1)
SetWindowCallback(@WinProc())
ImageGadget(#ctrl, 20, 40, 0, 0, ImageID(#up))
ImageGadget(#alt, 90, 40, 0, 0, ImageID(#up))
ImageGadget(#escape, 160, 40, 0, 0, ImageID(#up))
tid = CreateThread(@thread(), 0)
BindEvent(#buttonevent, @buttonproc())
Repeat
EventID = WaitWindowEvent()
Until EventID = #PB_Event_CloseWindow
KillThread(tid)
WaitThread(tid)
End
BERESHEIT
Re: reliable way to detect key state?
hmm. Your code is showing me (or I'm finally seeing) that it is not a global hook. getasynckeystate() only seems to work if your application has focus. So what I may be seeing is that something else is getting focus & locking out what I'm reading.
An easy demo is to press alt-esc a few times (leave alt pressed, and just press esc a few times) -- the 1st two are what you expect, teh 3rd leaves all three boxes green..
Definately gives me something to focus on to rule out causes...
thank you.
An easy demo is to press alt-esc a few times (leave alt pressed, and just press esc a few times) -- the 1st two are what you expect, teh 3rd leaves all three boxes green..
Definately gives me something to focus on to rule out causes...
thank you.
Re: reliable way to detect key state?
How about this? Test it with the W key on your keyboard.
Code: Select all
Repeat
Delay(1)
KeyStateDown=#False
If GetKeyState_(#VK_W)&$80
KeyStateDown=#True
EndIf
If KeyStateDown And Not KeyStateWasNotDown
KeyStateWasNotDown=#True
Debug "Key down!"
Else
If Not KeyStateDown And KeyStateWasNotDown
KeyStateWasNotDown=#False
Debug "Key up!"
EndIf
EndIf
ForEver
Re: reliable way to detect key state?
Thank you! That seems to work globally! Sorry for the late reply -- had a wicked thesis due.
That'll get me going! Works awesome.
That'll get me going! Works awesome.
Re: reliable way to detect key state?
No, GetAsyncKeyState_() works globally, no matter what has the focus. I've been using my macros forever that way.Damion12 wrote:getasynckeystate() only seems to work if your application has focus
Re: reliable way to detect key state?
weird -- because it stops working using the demo above and repeatedly pressing ctrl-esc.Dude wrote:No, GetAsyncKeyState_() works globally, no matter what has the focus. I've been using my macros forever that way.Damion12 wrote:getasynckeystate() only seems to work if your application has focus
Re: reliable way to detect key state?
Can't duplicate the problem here. Each key state works totally as expected, even when the window doesn't have the focus. That is, each key shows as green when released, and red while pressed. Is that not the case for you?Damion12 wrote:An easy demo is to press alt-esc a few times (leave alt pressed, and just press esc a few times) -- the 1st two are what you expect, teh 3rd leaves all three boxes green.
Re: reliable way to detect key state?
No, did I not say that already? sorry. No when I do it; it seems to 'not see' the keypress after a few presses. This mirrors what I was originally seeing with other methods....Dude wrote:Can't duplicate the problem here. Each key state works totally as expected, even when the window doesn't have the focus. That is, each key shows as green when released, and red while pressed. Is that not the case for you?Damion12 wrote:An easy demo is to press alt-esc a few times (leave alt pressed, and just press esc a few times) -- the 1st two are what you expect, teh 3rd leaves all three boxes green.