Pearson Software Consulting Services
Testing The State Of The SHIFT, CTRL, And ALT Keys
You may wish to provide extended or alternative
functionality of a procedure depending on whether the user has pressed
SHIFT, CTRL, or ALT. For example, you might have a procedure that normally
processes one range, but you want the procedure to process all ranges if the
user presses the SHIFT key. As an existing example, you will get a slightly
modified Edit menu if you click the Edit menu with the SHIFT key down.
Similarly, range selection (selecting cells and ranges) behaves differently
depending on the state of the CTRL and SHIFT keys. You test the state (up or down) of a key using the GetKeyState Windows API function. The GetKeyState function is documented on-line at MSDN. The result of GetKeyState is evaluated with a bit-wise AND with the value KEY_MASK (hex &HFF80 decimal -128) to determine the state of the key. The following are the declarations for the 3 functions: Public Function IsShiftKeyDown( _ Optional LeftOrRightKey As Long = LeftKeyOrRightKey) Public Function IsControlKeyDown( _ Optional LeftOrRightKey As Long = LeftKeyOrRightKey) As Boolean Public Function IsAltKeyDown( _ Optional LeftOrRightKey As Long = LeftKeyOrRightKey) As Boolean The functions are nearly identical, differing only the the key code being tested. The code on this page, and in a downloadable bas module file, tests for the state of the SHIFT, CTRL, and ALT keys. You can specify whether to test only the Left key, only the Right key, either the Left OR Right keys, or BOTH the Left AND Right keys. Unless you specify otherwise, the procedures' default test is to check for either the Left or Right key, making no distinction between Left and Right. Which keys to test (Left, Right, Either, Both) is specified in the LeftKeyOrRightKey parameter to each key-test function. The values for this parameter are declared as Constants in the code module as follows: Public Const BothLeftAndRightKeys = 0 Public Const LeftKey = 1 Public Const RightKey = 2 Public Const LeftKeyOrRightKey = 3 You'll note that the value BothLeftAndRightKeys is the bit-wise AND of LeftKey and RightKey, and that the value LeftKeyOrRightKey is the bit-wise OR of LeftKey and RightKey. If the LeftKeyOrRightKey parameter is omitted, the test is for either the left or right key -- the code does not distinguish between the left or right key. The complete VBA code module is shown below. You may download the module file here. Option Explicit Option Compare Text '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' modKeyState ' By Chip Pearson, www.cpearson.com, chip@cpearson.com ' This module contains functions for testing the state of the SHIFT, ALT, and CTRL ' keys. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''' ' Declaration of GetKeyState API function. This ' tests the state of a specified key. '''''''''''''''''''''''''''''''''''''''''''''''''''' Private Declare Function GetKeyState Lib "user32" ( _ ByVal nVirtKey As Long) As Integer '''''''''''''''''''''''''''''''''''''''''' ' This constant is used in a bit-wise AND ' operation with the result of GetKeyState ' to determine if the specified key is ' down. '''''''''''''''''''''''''''''''''''''''''' Private Const KEY_MASK As Integer = &HFF80 ' decimal -128 ''''''''''''''''''''''''''''''''''''''''' ' KEY CONSTANTS. Values taken ' from VC++ 6.0 WinUser.h file. ''''''''''''''''''''''''''''''''''''''''' Private Const VK_LSHIFT = &HA0 Private Const VK_RSHIFT = &HA1 Private Const VK_LCONTROL = &HA2 Private Const VK_RCONTROL = &HA3 Private Const VK_LMENU = &HA4 Private Const VK_RMENU = &HA5 ''''''''''''''''''''''''''''''''''''''''' ' The following four constants simply ' provide other names, CTRL and ALT, ' for CONTROL and MENU. "CTRL" and ' "ALT" are more familiar than ' "CONTROL" and "MENU". These constants ' provide no additional functionality. ' They simply provide more familiar ' names. ''''''''''''''''''''''''''''''''''''''''' Private Const VK_LALT = VK_LMENU Private Const VK_RALT = VK_RMENU Private Const VK_LCTRL = VK_LCONTROL Private Const VK_RCTRL = VK_RCONTROL '''''''''''''''''''''''''''''''''''''''''''' ' The following constants are used to specify, ' when testing CTRL, ALT, or SHIFT, whether ' the Left key, the Right key, either the ' Left OR Right key, or BOTH the Left AND ' Right keys are down. ' ' By default, the key-test procedures make ' no distinction between the Left and Right ' keys and will return TRUE if either the ' Left or Right (or both) key is down. '''''''''''''''''''''''''''''''''''''''''''' Public Const BothLeftAndRightKeys = 0 ' Note: Bit-wise AND of LeftKey and RightKey Public Const LeftKey = 1 Public Const RightKey = 2 Public Const LeftKeyOrRightKey = 3 ' Note: Bit-wise OR of LeftKey and RightKey Public Function IsShiftKeyDown(Optional LeftOrRightKey As Long = LeftKeyOrRightKey) '''''''''''''''''''''''''''''''''''''''''''''''' ' IsShiftKeyDown ' Returns TRUE or FALSE indicating whether the ' SHIFT key is down. ' ' If LeftOrRightKey is omitted or LeftKeyOrRightKey, ' the function return TRUE if either the left or the ' right SHIFT key is down. If LeftKeyOrRightKey is ' LeftKey, then only the Left SHIFT key is tested. ' If LeftKeyOrRightKey is RightKey, only the Right ' SHIFT key is tested. If LeftOrRightKey is ' BothLeftAndRightKeys, the codes tests whether ' both the Left and Right keys are down. The default ' is to test for either Left or Right, making no ' distiction between Left and Right. '''''''''''''''''''''''''''''''''''''''''''''''' Dim Res As Long Select Case LeftOrRightKey Case LeftKey Res = GetKeyState(VK_LSHIFT) And KEY_MASK Case RightKey Res = GetKeyState(VK_RSHIFT) And KEY_MASK Case BothLeftAndRightKeys Res = (GetKeyState(VK_LSHIFT) And GetKeyState(VK_RSHIFT) And KEY_MASK) Case Else Res = GetKeyState(vbKeyShift) And KEY_MASK End Select IsShiftKeyDown = CBool(Res) End Function Public Function IsControlKeyDown(Optional LeftOrRightKey As Long = LeftKeyOrRightKey) As Boolean '''''''''''''''''''''''''''''''''''''''''''''''' ' IsControlKeyDown ' Returns TRUE or FALSE indicating whether the ' CTRL key is down. ' ' If LeftOrRightKey is omitted or LeftKeyOrRightKey, ' the function return TRUE if either the left or the ' right CTRL key is down. If LeftKeyOrRightKey is ' LeftKey, then only the Left CTRL key is tested. ' If LeftKeyOrRightKey is RightKey, only the Right ' CTRL key is tested. If LeftOrRightKey is ' BothLeftAndRightKeys, the codes tests whether ' both the Left and Right keys are down. The default ' is to test for either Left or Right, making no ' distiction between Left and Right. '''''''''''''''''''''''''''''''''''''''''''''''' Dim Res As Long Select Case LeftOrRightKey Case LeftKey Res = GetKeyState(VK_LCTRL) And KEY_MASK Case RightKey Res = GetKeyState(VK_RCTRL) And KEY_MASK Case BothLeftAndRightKeys Res = (GetKeyState(VK_LCTRL) And GetKeyState(VK_RCTRL) And KEY_MASK) Case Else Res = GetKeyState(vbKeyControl) And KEY_MASK End Select IsControlKeyDown = CBool(Res) End Function Public Function IsAltKeyDown(Optional LeftOrRightKey As Long = LeftKeyOrRightKey) As Boolean '''''''''''''''''''''''''''''''''''''''''''''''' ' IsAltKeyDown ' Returns TRUE or FALSE indicating whether the ' ALT key is down. ' ' If LeftOrRightKey is omitted or LeftKeyOrRightKey, ' the function return TRUE if either the left or the ' right ALT key is down. If LeftKeyOrRightKey is ' LeftKey, then only the Left ALT key is tested. ' If LeftKeyOrRightKey is RightKey, only the Right ' ALT key is tested. If LeftOrRightKey is ' BothLeftAndRightKeys, the codes tests whether ' both the Left and Right keys are down. The default ' is to test for either Left or Right, making no ' distiction between Left and Right. '''''''''''''''''''''''''''''''''''''''''''''''' Dim Res As Long Select Case LeftOrRightKey Case LeftKey Res = GetKeyState(VK_LALT) And KEY_MASK Case RightKey Res = GetKeyState(VK_RALT) And KEY_MASK Case BothLeftAndRightKeys Res = (GetKeyState(VK_LALT) And GetKeyState(VK_RALT) And KEY_MASK) Case Else Res = GetKeyState(vbKeyMenu) And KEY_MASK End Select IsAltKeyDown = CBool(Res) End Function Sub Test() ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Test ' This is a procedure to test and demonstrate the Key-State ' functions above. Since you can't run a macro in the VBA ' Editor if the SHIFT, ALT, or CTRL key is down, this procedure ' uses OnTime to execute the ProcTest test procedure. OnTime ' will call ProcTest two seconds after running this Test ' procedure. Immediately after executing Test, press the ' key(s) (Left/Right SHIFT, ALT, or CTRL) you want to test ' for. The procedure called by OnTime, ProcTest, displays the ' status of the Left/Right SHIFT, ALT, and CTRL keys. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Application.OnTime Now + TimeSerial(0, 0, 2), "ProcTest", , True End Sub Sub ProcTest() ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' ProcTest ' This procedure simply displays the status of the Left adn Right ' SHIFT, ALT, and CTRL keys. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Debug.Print "SHIFT KEY: ", "LEFT: " & CStr(IsShiftKeyDown(LeftKey)), _ "RIGHT: " & CStr(IsShiftKeyDown(RightKey)), _ "EITHER: " & CStr(IsShiftKeyDown(LeftKeyOrRightKey)), _ "BOTH: " & CStr(IsShiftKeyDown(BothLeftAndRightKeys)) Debug.Print "ALT KEY: ", "LEFT: " & CStr(IsAltKeyDown(LeftKey)), _ "RIGHT: " & CStr(IsAltKeyDown(RightKey)), _ "EITHER: " & CStr(IsAltKeyDown(LeftKeyOrRightKey)), _ "BOTH: " & CStr(IsAltKeyDown(BothLeftAndRightKeys)) Debug.Print "CTRL KEY: ", "LEFT: " & CStr(IsControlKeyDown(LeftKey)), _ "RIGHT: " & CStr(IsControlKeyDown(RightKey)), _ "EITHER: " & CStr(IsControlKeyDown(LeftKeyOrRightKey)), _ "BOTH: " & CStr(IsControlKeyDown(BothLeftAndRightKeys)) End Sub
|
|
|
Created By Chip Pearson and
Pearson Software Consulting, LLC
This Page:
Updated: November 06, 2013
MAIN PAGE
About This Site
Consulting
Downloads
Page Index
Search
Topic Index
What's New
Links
Legalese And Disclaimers
chip@cpearson.com
© Copyright 1997-2007 Charles H. Pearson