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?

Code: Select all

(EDIT : The right code is below)

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!