Page 1 of 1

GetAsyncKeyState and x64 compiler

Posted: Wed Jul 08, 2015 8:58 pm
by Samuel
EDIT:
Solved, I was originally using Integers when I should have been using Words.


[Original Post]

I have a procedure for collecting key strokes which seems to work correctly on the 5.3(x86) compiler.
Sadly, on the 64 compiler it won't return any key releases.

I have very little knowledge when it comes to windows api.
So, I'm hoping someone can enlighten me on the proper way of collecting keystrokes using GetAsyncKeyState on the 86 and 64 compilers.

Any help is very much appreciated.

Code: Select all

Structure KeyData
  OldKey.w
  NewKey.w
EndStructure
Global.KeyData KEY_KeyA

#KEY_KeyA_UP   = 1
#KEY_KeyA_DOWN = 2

Declare KEY_KeyboardButton(WindowHandle.i, Type.i)

If OpenWindow(0, 0, 0, 400, 300, "A Key Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

  Repeat
    
    Event = WaitWindowEvent()
    
    If KEY_KeyboardButton(0, #KEY_KeyA_DOWN) = #True
      Debug "Down"
    EndIf
    
    If KEY_KeyboardButton(0, #KEY_KeyA_UP) = #True
      Debug "Up"
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf
End

Procedure KEY_KeyboardButton(WindowHandle.i, Type.i)
  
  If WindowHandle >= 0
    If GetActiveWindow() <> WindowHandle
      ProcedureReturn #False
    EndIf
  EndIf

  Select Type

    Case #KEY_KeyA_DOWN
      KEY_KeyA\NewKey = GetAsyncKeyState_(#VK_A) & 32768
      If KEY_KeyA\NewKey <> 0
        KEY_KeyA\OldKey = KEY_KeyA\NewKey
        ProcedureReturn #True
      EndIf
    Case #KEY_KeyA_UP
      KEY_KeyA\NewKey = GetAsyncKeyState_(#VK_A)
      If KEY_KeyA\OldKey <> 0 And KEY_KeyA\NewKey = 0
        KEY_KeyA\OldKey = 0
        ProcedureReturn #True
      EndIf
      
  EndSelect
      
  ProcedureReturn #False

EndProcedure

Re: GetAsyncKeyState and x64 compiler

Posted: Wed Jul 08, 2015 10:18 pm
by Thunder93
Change the structure types from .I to .w

Re: GetAsyncKeyState and x64 compiler

Posted: Wed Jul 08, 2015 10:50 pm
by RASHAD
Hi
It looks OK to me with x86 or x64
Which version of PB you are using ?

Code: Select all

Global KEY_KeyA.KeyData

Re: GetAsyncKeyState and x64 compiler

Posted: Wed Jul 08, 2015 10:55 pm
by Thunder93
Using PureBasic 5.31 and like the OP, the x64 Compile didn't function the same way. Because the data saved and the data being compared to wouldn't match, the structure types needed to be modified.

Re: GetAsyncKeyState and x64 compiler

Posted: Wed Jul 08, 2015 11:04 pm
by Samuel
Thank you very much, Thunder93. :D
I didn't even consider that I could be using the wrong variable type.

I'll edit my original example for others.

Re: GetAsyncKeyState and x64 compiler

Posted: Wed Jul 08, 2015 11:10 pm
by Thunder93
No prob Samuel. :D

Re: GetAsyncKeyState and x64 compiler

Posted: Thu Jul 09, 2015 2:53 am
by RASHAD
Hi
The compare is false because of the type of the structure elements (No this is not true)
Your are messing with GetAsyncKeyState_()

Try the next tested with PB x64 Win 7,8.1,10 b10162 insider x64

Code: Select all

Structure KeyData
  OldKey.i
  NewKey.i
EndStructure
Global KEY_KeyA.KeyData

#KEY_KeyA_UP   = 1
#KEY_KeyA_DOWN = 2

Declare KEY_KeyboardButton(WindowHandle.i, Type.i)

If OpenWindow(0, 0, 0, 400, 300, "A Key Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

  Repeat
    
    Event = WaitWindowEvent()
    
    If KEY_KeyboardButton(0, #KEY_KeyA_DOWN) = #True
      Debug "Down"
    EndIf
    
    If KEY_KeyboardButton(0, #KEY_KeyA_UP) = #True
      Debug "Up"
    EndIf
    
  Until Event = #PB_Event_CloseWindow
EndIf
End

Procedure KEY_KeyboardButton(WindowHandle.i, Type.i)
  
  If WindowHandle >= 0
    If GetActiveWindow() <> WindowHandle
      ProcedureReturn #False
    EndIf
  EndIf

  Select Type

    Case #KEY_KeyA_DOWN
      KEY_KeyA\NewKey = GetAsyncKeyState_(#VK_A) & 32768
      If KEY_KeyA\NewKey <> 0
        KEY_KeyA\OldKey = KEY_KeyA\NewKey
        ProcedureReturn #True
      EndIf
    Case #KEY_KeyA_UP
      KEY_KeyA\NewKey = GetAsyncKeyState_(#VK_A) & 32768
      If KEY_KeyA\OldKey <> 0 And KEY_KeyA\NewKey = 0
        KEY_KeyA\OldKey = 0
        ProcedureReturn #True
      EndIf
      
  EndSelect
      
  ProcedureReturn #False

EndProcedure

Re: GetAsyncKeyState and x64 compiler

Posted: Thu Jul 09, 2015 3:56 pm
by Thunder93
Hi.

Of course you could use Integer in the structure for this. Ensure that also GetAsyncKeyState() in the ' A ' button release procedure is saving also with.. & 32768

However I don't see the point in using Integers or types using more memory than required. I would personally drop this ' & 32768 ' addition on GetAsyncKeyState() and change the structure field types to .u