Page 1 of 2
2 key presses
Posted: Thu Mar 03, 2005 6:55 am
by NewMan
is there a way i can detect if two keys are currently pressed, i mean both the key should be down. i tried this
Code: Select all
If GetAsyncKeyState_(#VK_Control) & GetAsyncKeyState_(#VK_X)
but if u press n release control and then press x it generates an even.t i want to check if the keys are down at the same time, i want to do it in such a way that it will detect all keys pressed, i mean not just the keys pressed while pb window is active but even in other programs.
Posted: Thu Mar 03, 2005 9:54 am
by einander
Hi NewMan:
Hope this helps:
Code: Select all
Procedure Callback(Win, Msg, wParam, lParam)
RESULT = #PB_ProcessPureBasicEvents
Select Msg
Case #PB_EventCloseWindow : End
Case #WM_KEYDOWN
Debug "Pressed"+Str(wParam)
Case #WM_KEYUP
Debug "Released"+Str(wParam)
EndSelect
ProcedureReturn RESULT
EndProcedure
OpenWindow(0,0,0,0,0, #WS_OVERLAPPEDWINDOW | #WS_MAXIMIZE, "")
SetWindowCallback(@Callback())
Repeat : WaitWindowEvent() :ForEver
Posted: Thu Mar 03, 2005 10:22 am
by NewMan
ty, but it isnt what i am looking for. i dont want the callback edited and i want to check if two keys are pressed at the same time at once.
Posted: Thu Mar 03, 2005 11:14 am
by Mischa
Example:
Code: Select all
Repeat
If keystate
If GetAsyncKeyState_(keystate)=0
keystate=0
Debug "(released)"
EndIf
ElseIf altpressed
If GetAsyncKeyState_(#VK_MENU)
If GetAsyncKeyState_(#VK_RETURN)
keystate=#VK_RETURN
Debug "Alt + Return"
ElseIf GetAsyncKeyState_(#VK_F4)
keystate=#VK_F4
Debug "Alt + F4"
EndIf
Else
altpressed=0
EndIf
Else
;clear buffer
GetAsyncKeyState_(#VK_MENU)
GetAsyncKeyState_(#VK_ESCAPE)
GetAsyncKeyState_(#VK_RETURN)
GetAsyncKeyState_(#VK_F4)
If GetAsyncKeyState_(#VK_RETURN)=0 And GetAsyncKeyState_(#VK_F4)=0 And GetAsyncKeyState_(#VK_MENU)
altpressed=1
ElseIf GetAsyncKeyState_(#VK_ESCAPE)
End
EndIf
EndIf
ForEver
If you would modify einander's example it will work also, but for GetAsyncKeyState_() you don't need focus or a window.
Regards,
Mischa
Re: 2 key presses
Posted: Thu Mar 03, 2005 12:19 pm
by PB
> If GetAsyncKeyState_(#VK_Control) & GetAsyncKeyState_(#VK_X)
You almost had it.

The above should be:
Code: Select all
If GetAsyncKeyState_(#VK_Control)<>0 And GetAsyncKeyState_(#VK_X)<>0
; Do whatever.
EndIf
By the way, you DON'T use "&" for comparisons... use "And" for that.
Posted: Fri Mar 04, 2005 6:35 am
by NewMan
thanks for the reply. PB thanks but it wasnt the way i wanted. though i found out the answer. in ur code (to PB) if you press ctrl and release it and then press x and release it or not, it will return yes. but i wanted something that checks if both the keys r down simultaniously. so this code worked for me
Code: Select all
While GetAsyncKeyState_(#VK_Shift)=-32767
If GetAsyncKeyState_(#VK_LButton)=-32767
;Do Whatever
EndIf
Wend
Posted: Fri Mar 04, 2005 7:02 am
by PB
Hi NewMan,
I see what you mean now... normally I just flush all the key buffers first like so:
Code: Select all
Repeat
For k=0 To 255 : GetAsyncKeyState_(k) : Next
If GetAsyncKeyState_(#VK_Control)<>0 And GetAsyncKeyState_(#VK_X)<>0
Debug "Both!"
EndIf
ForEver
Posted: Tue Sep 25, 2007 7:49 pm
by Ollivier
@PB
Refreshing all the 256 keys with the loop For... Next. It's a really good idea!
Thanks!
Posted: Tue Sep 25, 2007 9:10 pm
by Kaeru Gaman
I only see GetAsyncKeyState_ in all examples.... each call makes a new State...
think about GetKeyboardState_(), to get all 256 keys at once.
Posted: Tue Sep 25, 2007 9:30 pm
by Ollivier
@kaeru
this code below contains this line
Code: Select all
For k=0 To 255 : GetAsyncKeyState_(k) : Next
Without it, you can't get simultaneously really 2 key states. Try to execute PB's code (indeed the last code) without this line. After many manipulations, it doesn't right.
I changed this with key 'B' and key 'X' to check it.
PB wrote:Hi NewMan,
I see what you mean now... normally I just flush all the key buffers first like so:
Code: Select all
Repeat
For k=0 To 255 : GetAsyncKeyState_(k) : Next
If GetAsyncKeyState_(#VK_B)<>0 And GetAsyncKeyState_(#VK_X)<>0
Debug "Both!"
EndIf
ForEver
Posted: Tue Sep 25, 2007 10:07 pm
by Kaeru Gaman
the point is, with that loop it does 256(!) calls of the keycheck,
and definitely, it can have a different status on Func_(0) than on Func_(255),
because the key-func is called 256 times and recieves an actual state every call.
better use GetKeyboardState_() once, and recieve a 256-byte table to express the state of each and every key at this very moment.
not only that it's faster (one call to 256 calls), it's barn more precise!
Posted: Tue Sep 25, 2007 10:19 pm
by PB
> better use GetKeyboardState_() once, and recieve a 256-byte table to
> express the state of each and every key at this very moment
Can you give an example of how to do this? Like, to check if both Control
and A are pressed at the same time. Thanks.
Posted: Tue Sep 25, 2007 10:28 pm
by Ollivier
@kaeru
GetKeyboardState_() is intersting. Good idea!
But I try to display the 256 key states but there is an error. Could you check it?
Posted: Tue Sep 25, 2007 10:30 pm
by Ollivier
I think I might to set each key before using GetKeyboardState(). Isn't it?
(But I ignore how to do it)
Posted: Tue Sep 25, 2007 10:59 pm
by Kaeru Gaman
Code: Select all
EnableExplicit
Structure FFmap
key.b[256]
EndStructure
Define Keys.FFmap
Define.l EvID
OpenWindow(0,#PB_Ignore,#PB_Ignore,200,100,"keytest")
CreateGadgetList(WindowID(0))
TextGadget(0,10,10,180,30,"go")
Repeat
EvID = WaitWindowEvent(100)
GetKeyboardState_(@Keys)
If Keys\key[#VK_A] And Keys\key[#VK_CONTROL]
SetGadgetText(0, "you hit ctrl-a")
EndIf
Until EvID = #PB_Event_CloseWindow
I'm setting off a 256byte-array in a struct, and hand it to the API-func to fill it with the actual KeyboardState.
after that, I just look into the Array, what Keys have been pressed or not.
[edit]
@Ollivier
pardon, looking at your code, I'm bashed by a dozen Menus....
I think that's not necessary... remember the KISS-principle!