2 key presses

Just starting out? Need help? Post your questions and find answers here.
NewMan
User
User
Posts: 11
Joined: Sun Jul 25, 2004 9:54 am

2 key presses

Post 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.
User avatar
einander
Enthusiast
Enthusiast
Posts: 744
Joined: Thu Jun 26, 2003 2:09 am
Location: Spain (Galicia)

Post 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
NewMan
User
User
Posts: 11
Joined: Sun Jul 25, 2004 9:54 am

Post 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.
User avatar
Mischa
Enthusiast
Enthusiast
Posts: 115
Joined: Fri Aug 15, 2003 7:43 pm

Post 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
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: 2 key presses

Post 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.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
NewMan
User
User
Posts: 11
Joined: Sun Jul 25, 2004 9:54 am

Post 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 
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post 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
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post by Ollivier »

@PB

Refreshing all the 256 keys with the loop For... Next. It's a really good idea!

Thanks!
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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.
oh... and have a nice day.
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post 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
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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!
oh... and have a nice day.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post 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.
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post 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)
Last edited by Ollivier on Tue Sep 25, 2007 11:50 pm, edited 1 time in total.
Ollivier
Enthusiast
Enthusiast
Posts: 281
Joined: Mon Jul 23, 2007 8:30 pm
Location: FR

Post by Ollivier »

I think I might to set each key before using GetKeyboardState(). Isn't it?
(But I ignore how to do it)
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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!
oh... and have a nice day.
Post Reply