Here’s another neat little MapBasic function I’ve been using recently. I needed a way of detecting whether a key on the keyboard was currently pressed or not. My intention was to show a hidden debugging dialog if a user shift-clicked on a specific button control, but there’s no in-built functions in MapBasic for detecting key states. Fortunately it’s possible to hook into the Windows User32.dll to use the GetAsyncKeyState call. Here’s how this all works in MapBasic…
First, we’ve got to define the GetASyncKeyState call and a bunch of related constants which map keys to a numeric value. Copy and paste the contents below to a .def file (or download a pre-made version later in this post).
asynckeys.def:
Declare Function GetAsyncKeyState Lib "User32.dll" Alias "GetAsyncKeyState" (ByVal vKey As Integer) As Integer DEFINE vbKeyShift 16 DEFINE vbKey1 49 DEFINE vbKey2 50 DEFINE vbKey3 51 DEFINE vbKey4 52 DEFINE vbKey5 53 DEFINE vbKey6 54 DEFINE vbKey7 55 DEFINE vbKey8 56 DEFINE vbKey9 57 DEFINE vbKey0 48 DEFINE vbKeyBack 8 DEFINE vbKeyTab 9 DEFINE vbKeyReturn 13 DEFINE vbKeyControl 17 DEFINE vbKeyMenu 18 DEFINE vbKeyPause 19 DEFINE vbKeyEscape 27 DEFINE vbKeySpace 32 DEFINE vbKeyEnd 35 DEFINE vbKeyHome 36 DEFINE vbKeyLeft 37 DEFINE vbKeyRight 39 DEFINE vbKeyUp 38 DEFINE vbKeyDown 40 DEFINE vbKeyInsert 45 DEFINE vbKeyDelete 46 DEFINE vbKeyMultiply 106 DEFINE vbKeyDivide 111 DEFINE vbKeyAdd 107 DEFINE vbKeySubtract 109 DEFINE vbKeyDecimal 110 DEFINE vbKeyF1 112 DEFINE vbKeyF2 113 DEFINE vbKeyF3 114 DEFINE vbKeyF4 115 DEFINE vbKeyF5 116 DEFINE vbKeyF6 117 DEFINE vbKeyF7 118 DEFINE vbKeyF8 119 DEFINE vbKeyF9 120 DEFINE vbKeyF10 121 DEFINE vbKeyF11 122 DEFINE vbKeyF12 123 DEFINE vbKeyNumlock 144 DEFINE vbKeyScrollLock 145 DEFINE vbKeySnapshot 44 DEFINE vbKeyPageUp 33 DEFINE vbKeyPageDown 34 DEFINE vbKeyNumpad1 97 DEFINE vbKeyNumpad2 98 DEFINE vbKeyNumpad3 99 DEFINE vbKeyNumpad4 100 DEFINE vbKeyNumpad5 101 DEFINE vbKeyNumpad6 102 DEFINE vbKeyNumpad7 103 DEFINE vbKeyNumpad8 104 DEFINE vbKeyNumpad9 105 DEFINE vbKeyNumpad0 96 DEFINE vbKeyPressed -32767 DEFINE vbKeyWasPressed 1
Now, you can test for the state of any key by calling getASyncKeyState( vKey ), where vKey is an integer value corresponding to the key you want to test. So getASyncKeyState( vbKeyControl ) will test the state of the control key. The value returned will reflect whether the key is currently pressed (vbKeyPressed), or has been pressed since the last call to the function (vbKeyWasPressed). Easy! Here’s a little sample program to demonstrate how this all works:
Include "asynckeys.def" Declare Sub Main Declare Sub KeyCheck Sub KeyCheck ' Store the pressed state of the SHIFT key Dim iState As Integer iState = getASyncKeyState( vbKeyShift ) ' Check what the state was Do Case iState Case vbKeyPressed Print "SHIFT is being pressed!" Case vbKeyWasPressed Print "SHIFT has been pressed since last check" Case Else Print "Nothing to report..." End Case ' Keep the dialog around Dialog Preserve End Sub Sub Main Dialog Title "ASync Key State" Control OKButton Title "Check" Calling KeyCheck Control CancelButton Title "Quit" End Sub
Both the asynckeys.def definition file and the sample program are contained in this archive.