Wednesday, September 26, 2012

[ MFC ] - Check Shift, ctrl, alt and Toggle keystate in onkeydown (WM_KEYDOWN Message Handler)


1. Introduction


We know that keyboard and mouse are very basic hardware interface supported by almost all the computer operating system. When the user presses the Keyboard key the device driver for the keyboard processes that input by making use of the interrupts. Windows OS knows about these kinds of hardware actions in the form of a message structure. The hardware fills this structure with the information it has processed and places that in the Operating system message queue.

The operating system message queue then places the message in the corresponding application and from the application queue; the message is delivered to the target window for responding back.

In this article, we will see how can we check various keyboard events with a simple example.



2. Create an SDI Application


The sample is a simple SDI Application.  To create the application on your own,
1. Create a new project and chose MFC Application under the Visual C++ category. Then provide the project name as shown in Fig.1
Fig.1


2. Then click ok to the above dialog. This will open a wizard now. Accept the default for the pages except the one shown in Fig.2 below:

Fig.2


The SDI Application is ready to check the different kinds of keyboard input.



3. Before we code


When a key is pressed by the user, the target window will receive the below-specified windows messages. The messages and its details are shown in Fig.3:

Fig.3


From the above table, we can conclude that KeyDown and KeyUp will be fired for any type of keyboard keys. Therefore, this event is the combination of System key as well as the character keystrokes. Let us say that you typed the alphabet letter ‘K’ in a notepad. The hardware interprets that as a two events. One is KeyDown and the other one is KeyUp. So we get three messages WM_KEYDOWN, WM_KEYUP and WM_CHAR as the typed keystroke is not a  system key.

There some special keys that we should be aware. These are categorized as Shift Keys as well as Toggle keys. Examples for shift keys are ctrl, shift and Alt. Similarly, Toggle key changes it’s key state in between on & off. One best example for toggle key is Caps Lock.

We will use the sample created in section 2 to demonstrate the WM_KEYDOWN event. You can handle other events similar to this.



4. Implement the WM_KEYDOWN event


First, we need to provide the handler for the WM_KEYDOWN message. The steps are shown in Fig.4. Go to class view and select properties for the class CKeyBoardInputView. We are going to handle our keyboard events in the view class. Next, provide the handler function for WM_KEYDOWN windows message. To do this click on the message icon, then double click on the grid column for the WM_KEYDOWN.

Fig.4


The signature of the empty handler is shown below:
void CKeyBoardInputView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
}

In this article, we are going to deal with the first parameter only. The first parameter represents the key code that you can compare with the keyboard constants to decide the keystroke.



5. Looking for Alphanumeric Key


The alphanumeric keystroke can be compared directly with character constants. In the below code we are looking for the English letter M or the numeric digit 3.

//01. Numbers and Charactors
if (nChar == 'M')
        AfxMessageBox(_T("M Pressed"));
if (nChar == '3')
        AfxMessageBox(_T("Three Pressed"));



6. Looking for the System Key


System keys should be compared with the pre-defined constant values defined in the WinUser.h header file.  The below code shows how we ensure that the typed keystroke is either an F5 key or an End key. These two keys are system keys and do not fall in the alphabets or numeric keys.

//02. Process System Keys
if (nChar == VK_F5)
        AfxMessageBox(_T("F5 Function Key Pressed"));
if (nChar == VK_END)
        AfxMessageBox(_T("END Key Pressed"));



7. Looking for the Shift key combination


Sometimes we will end up in a situation where we need to check the alphanumeric keystroke in combination with the shift keys like ctrl, shift etc. The below example will check for the ctrl+A and the Shift+S combination of the keys. When converting the 8000 from hexadecimal to binary we get 16 digits with the high bit set to one. The GetKeyState returns a negative number when the shift key is kept down. So you can either check the return value is negative or check the high order bit with the Bitwise AND operator ‘&’. The code listed uses the bit-wise operator to make the comparison:

//03. Numbers and Char keys with Shift key combination
if (nChar == 'A')
{
        if (GetKeyState(VK_CONTROL ) & 0x8000  )
               AfxMessageBox(_T("Ctrl+A is pressed"));
}

if (nChar == 'S')
{
        //Shift Keys [Alt, Shift, Ctrl]
        if (GetKeyState(VK_SHIFT) & 0x8000  )
               AfxMessageBox(_T("Shift+S is pressed"));
}



8. Looking for the Toggle key state




The toggle key like Insert and CapsLock will change their state between ON and OFF. When the toggle key is pressed it current state is inverted. In the previous section, we saw the importance of the High order bit of the nChar (First parameter of the event handler) to decide the state (Hold down) of the shift key. The low order bit is used to check the toggle key status. When the low order bit is set, the toggle key is turned on. The below code informs you whenever the CAPSLOCK key is turned-ON. Similarly, the code below will also show a message box when the NumLock is turned-Off.

//04. Checking toggle keys
if (nChar == VK_CAPITAL)
{
        if (GetKeyState(VK_CAPITAL) & 0x01 )
               AfxMessageBox(_T("Caps Key On"));
}

if (nChar == VK_NUMLOCK)
{
        if (!(GetKeyState(VK_NUMLOCK) & 0x01) )
               AfxMessageBox(_T("Num Key Off"));     
}


Source Code: Download

No comments:

Post a Comment

Leave your comment(s) here.

Like this site? Tell it to your Firend :)