I didn't add comments, but I think it's pretty self explanatory.
<snippet>
&GLOBAL VK_CAPITAL 20
&GLOBAL VK_INSERT 45
&GLOBAL VK_NUMLOCK 144
&GLOBAL VK_SCROLL 145
&GLOBAL VK_SHIFT 16
&GLOBAL VK_CONTROL 17
/* NT/2000/XP only */
&GLOBAL VK_LSHIFT 160
&GLOBAL VK_RSHIFT 161
&GLOBAL VK_LCONTROL 162
&GLOBAL VK_RCONTROL 163
PROCEDURE GetKeyState EXTERNAL "user32.dll":
DEFINE INPUT PARAM nVirtKey AS LONG.
DEFINE RETURN PARAM RetVal AS SHORT.
END PROCEDURE. /* GetKeyState */
FUNCTION VirtKeyDown RETURNS LOGICAL ( nVirtKey AS INTEGER ):
DEFINE VAR RetVal AS INT NO-UNDO.
RUN GetKeyState( nVirtKey, OUTPUT RetVal ).
RETURN ( GET-BITS( RetVal, 8, 1 ) = 1 ).
END FUNCTION. /* VirtKeyDown */
ON "MOUSE-SELECT-DOWN" ANYWHERE DO:
MESSAGE
"Shift Down: " VirtKeyDown( {&VK_SHIFT} )
VIEW-AS ALERT-BOX.
END. /* mouse-select-down */
VIEW CURRENT-WINDOW.
WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW.
</snippet>
You can find a thorough explanation on the GetKeyState function @msdn.com
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/getkeystate.asp
There's also a similar sample using the GetKeyboardState function @Jurjen Dijkstra - global-shared.com
http://global-shared.com/win32/keyboard/getkeyboardstate?s=getkeyboardstate
I'd recommend not using ANYWHERE and building a Windows API procedure library ( persistent or super procedure ). HTH