Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Detecting the shift state of keys in realtime
Message
From
07/02/2019 09:20:35
 
 
To
07/02/2019 08:50:31
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Environment versions
Visual FoxPro:
VFP 9 SP2
OS:
Windows 10
Miscellaneous
Thread ID:
01665968
Message ID:
01666021
Views:
37
>>>>Me again,
>>>>
>>>>I have been playing around with the WinApi's getKeyState and GetKeyboardState function to determine when the Shift, Ctrl, or Alt key are pressed when a routine occurs. But the results tend to be random. Does anyone have a solution that returns the state of these keys? FYI. the routine is occurring in a TImer. I am attempt to implement a more dynamic tooltip that would display the content based on the state of the shift state and the content the mouse happens to be over at the time.
>>>>
>>>>Any suggestion are welcome.
>>>
>>>Use GetAsyncKeyState(). It returns a 32-bit value that can have the lower 16-bits parsed using BITAND(lnResult, 0x8000) to determine if the key is down or up (non-zero = down, zero = up).
>>>
>>>You can see all of the virtual keys to test, including VK_SHIFT, VK_CONTROL, VK_MENU (alt), as well as VK_RSHIFT, VK_LSHIFT, etc.
>>>
>>>
#define key_lshift 0xa0
>>>#define key_rshift 0xa1
>>>#define key_lctrl 0xa2
>>>#define key_rctrl 0xa3
>>>#define key_lalt 0xa4
>>>#define key_ralt 0xa5
>>>
>>>DECLARE INTEGER GetAsyncKeyState IN WIN32API INTEGER nVKey
>>>
>>>LOCAL llLShiftDown, llRShiftDown, llLCtrlDown, llRCtrlDown, llLAltDown, llRAltDown
>>>llLShiftDown = isKeyDown(key_lshift)
>>>llRShiftDown = isKeyDown(key_rshift)
>>>llLCtrlDown  = isKeyDown(key_lctrl)
>>>llRCtrlDown  = isKeyDown(key_rctrl)
>>>llLAltDown   = isKeyDown(key_lalt)
>>>llRAltDown   = isKeyDown(key_ralt)
>>>
>>>* The same works for reading mouse buttons
>>>#define left_button 0x1
>>>#define right_button 0x2
>>>#define middle_button 0x4
>>>llLeftButtonDown   = isKeyDown(left_button)
>>>llRightButtonDown  = isKeyDown(right_button)
>>>llMiddleButtonDown = isKeyDown(middle_button)
>>>
>>>
>>>FUNCTION isKeyDown
>>>LPARAMETERS tnVKey
>>>    RETURN (BITAND(GetAsyncKeyState(tnVKey), 0x8000) != 0)
>>>
>>>You can also BINDEVENTS(thisForm.HWnd, WM_KEYDOWN, "thisForm", "my_method") and intercept keystrokes which are made as they are made. This will be for any keystroke directed to that window. See WM_KEYDOWN for the bits to examine there to retrieve the vKey and live state as it changes.
>>
>>I cannot make this work by only Pressing the left shift key, it only triggers if I press Ctrl+shift.
>>
>>Ctrl alone does work, so it seems GetAsyncKeyState does not trigger with only shift key pressed?
>
>I created this program to test it. It works here. Maybe I posted something incorrectly in the code above?
>
>
#define key_lshift 0xa0
>#define key_rshift 0xa1
>#define key_lctrl 0xa2
>#define key_rctrl 0xa3
>#define key_lalt 0xa4
>#define key_ralt 0xa5
>#define left_button 0x1
>#define right_button 0x2
>#define middle_button 0x4
>
>LOCAL llLShiftDown, llRShiftDown, llLCtrlDown, llRCtrlDown, llLAltDown, llRAltDown
>LOCAL llLeftButtonDown, llRightButtonDown, llMiddleButtonDown
>
>DECLARE INTEGER GetAsyncKeyState IN WIN32API INTEGER nVKey
>DO WHILE INKEY() != 27
>    llLShiftDown = (BITAND(GetAsyncKeyState(key_lshift), 0x8000) != 0)
>    llRShiftDown = (BITAND(GetAsyncKeyState(key_rshift), 0x8000) != 0)
>    llLCtrlDown  = (BITAND(GetAsyncKeyState(key_lctrl), 0x8000) != 0)
>    llRCtrlDown  = (BITAND(GetAsyncKeyState(key_rctrl), 0x8000) != 0)
>    llLAltDown   = (BITAND(GetAsyncKeyState(key_lalt), 0x8000) != 0)
>    llRAltDown   = (BITAND(GetAsyncKeyState(key_ralt), 0x8000) != 0)
>    IF llLShiftDown
>        CLEAR
>        ? "Left shift"
>    ENDIF
>    IF llRShiftDown
>        CLEAR
>        ? "Right shift"
>    ENDIF
>    IF llLCtrlDown
>        CLEAR
>        ? "Left control"
>    ENDIF
>    IF llRCtrlDown
>        CLEAR
>        ? "Right control"
>    ENDIF
>    IF llLAltDown
>        CLEAR
>        ? "Left alt"
>    ENDIF
>    IF llRAltDown
>        CLEAR
>        ? "Right alt"
>    ENDIF
>
>    * The same works for reading mouse buttons
>    llLeftButtonDown   = (BITAND(GetAsyncKeyState(left_button), 0x8000) != 0)
>    llRightButtonDown  = (BITAND(GetAsyncKeyState(right_button), 0x8000) != 0)
>    llMiddleButtonDown = (BITAND(GetAsyncKeyState(middle_button), 0x8000) != 0)
>    IF llLeftButtonDown
>        CLEAR
>        ? "Left mouse button"
>    ENDIF
>    IF llRightButtonDown
>        CLEAR
>        ? "Right mouse button"
>    ENDIF
>    IF llMiddleButtonDown
>        CLEAR
>        ? "Middle mouse button"
>    ENDIF
>ENDDO
Thanks, I will check why it did not work previously, but this does work.
Christian Isberner
Software Consultant
Previous
Reply
Map
View

Click here to load this message in the networking platform