Getting Started With Windows Programming In C/C++: Key Events

First create the Win32 project in Visual Studio and create the window.

See following articles to create window & to draw shapes in Win32.

As you all know key events are input type events.

You could have used key events in Object Oriented programming languages like Key Down,Key Up & Key Press events.

Win32 supports these all events also.

Key Down

When you press a key, Windows places either a WM_KEYDOWN or WM_SYSKEYDOWN message in the message queue of the window with the input focus.

  • WM_KEYDOWN: These types of events are generated by the user.
  • WM_SYSKEYDOWN: These are system keys down events and refers to keystrokes that are more important to Windows than to Windows applications.

Key Up

When you released a key, Windows places either a WM_KEYUP or WM_SYSKEYUP message in the message queue of the window with the input focus.

  • WM_KEYUP: Same as above.
  • WM_SYSKEYUP: Same as above.

Virtual Key Codes

The virtual key code is stored in the wParam parameter of the WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, and WM_SYSKEYUP messages. This code identifies the key being pressed or released.

This is same as used in Java programming languages.

Not surprise because JVM is written in Win32.

Virtual key codes starts with prefix VK_ defined in the WINUSER.H header file.

e.g :

  • VK_BACK
  • VK_LEFT
  • VK_RIGHT
  • VK_UP
  • VK_RIGHT
  • VK_CONTROL
  • VK_SHIFT etc.

When you process a keystroke message, you may need to know whether any of the shift keys (Shift,Ctrl, and Alt) or toggle keys (Caps Lock, Num Lock, and Scroll Lock) are pressed.

You can obtain this information by calling the GetKeyState() function.

  1. iState = GetKeyState (VK_SHIFT) ;  
Using Code

To use Key down & key up events in the program, declare WM_KEYDOWN or WM_KEYUP statement in the switch statement in WndProc() function.

The generated key event is provided by wparam parameter.

You have to compare that parameter value with the virtual key codes and perform actions that you want.

Example:
  1. case WM_KEYDOWN:  
  2.     switch (wparam)  
  3.     {  
  4.         case VK_CONTROL:  
  5.             //your code here    
  6.             break;  
  7.             //another switch statements        
  8.     }  
  9. case WM_KEYUP:  
  10.     switch (wparam)  
  11.     {  
  12.         case VK_CONTROL:  
  13.             //your code here    
  14.             break;  
  15.             //another switch statements        
  16.     }  
Key Characters

As you know there are two types of keys,one is defined above for down/up and another is the typed characters keys.

As you know,Object Oriented languages provide this function in KeyPress() or KeyTyped() events,but in Win32 this can be done using WM_CHAR message type.

There are four character messages:
  • WM_CHAR
  • WM_DEADCHAR
  • WM_SYSCHAR
  • WM_SYSDEADCHAR

Pressed characters are also provided by wparam parameter.

How to use this ?

Example:

  1. case WM_CHAR :    
  2.     switch(wparam)    
  3.     {    
  4.       case 'a' :    
  5.           //your code here    
  6.           break;    
  7.               
  8.       case '\t' :    
  9.           //your code here    
  10.           break;     
  11.               
  12.       case '\n' :    
  13.           //your code here    
  14.           break;     
  15.               
  16.        //another switch statements        
  17.     }   
Let's see the program for better understanding.

Here's the Win32 program that show messagebox when Control key is down,Shift key is up & alphabet is pressed.
  1. #include "stdafx.h"  
  2. #include < Windows.h >  
  3. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  4. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)  
  5. {  
  6.     TCHAR appname[] = TEXT("Key Events");  
  7.     MSG msg;  
  8.     HWND hwnd;  
  9.     WNDCLASS wndclass;  
  10.     wndclass.cbClsExtra = 0;  
  11.     wndclass.cbWndExtra = 0;  
  12.     wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);  
  13.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);  
  14.     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);  
  15.     wndclass.hInstance = hInstance;  
  16.     wndclass.lpfnWndProc = WndProc;  
  17.     wndclass.lpszClassName = appname;  
  18.     wndclass.lpszMenuName = NULL;  
  19.     wndclass.style = CS_HREDRAW | CS_VREDRAW;  
  20.     if (!RegisterClass( & wndclass))  
  21.     {  
  22.         MessageBox(NULL, TEXT("Class not registered"), TEXT("Error...."), MB_OK);  
  23.     }  
  24.     hwnd = CreateWindow(appname,  
  25.         appname,  
  26.         WS_OVERLAPPEDWINDOW,  
  27.         100,  
  28.         100,  
  29.         CW_USEDEFAULT,  
  30.         CW_USEDEFAULT,  
  31.         NULL,  
  32.         NULL,  
  33.         hInstance,  
  34.         NULL);  
  35.     ShowWindow(hwnd, iCmdShow);  
  36.     UpdateWindow(hwnd);  
  37.     while (GetMessage( & msg, NULL, 0, 0))  
  38.     {  
  39.         TranslateMessage( & msg);  
  40.         DispatchMessage( & msg);  
  41.     }  
  42.     return msg.wParam;  
  43. }  
  44. CHAR getChar(WPARAM wparam)  
  45. {  
  46.     CHAR a = NULL;  
  47.     for (char ch = 'a'; ch <= 'z'; ch++)  
  48.     {  
  49.         if (wparam == ch)  
  50.         {  
  51.             a = ch;  
  52.         }  
  53.     }  
  54.     for (char ch = 'A'; ch <= 'Z'; ch++)  
  55.     {  
  56.         if (wparam == ch)  
  57.         {  
  58.             a = ch;  
  59.         }  
  60.     }  
  61.     return a;  
  62. }  
  63. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  64. {  
  65.     HDC hdc;  
  66.     switch (message)  
  67.     {  
  68.         case WM_CREATE:  
  69.             return 0;  
  70.             break;  
  71.             // key down    
  72.         case WM_KEYDOWN:  
  73.             switch (wParam)  
  74.             {  
  75.                 case VK_CONTROL:  
  76.                     MessageBox(NULL, TEXT("Control Key Down"), TEXT("Key Down"), MB_OK);  
  77.                     break;  
  78.             }  
  79.             return 0;  
  80.             break;  
  81.             // key down    
  82.         case WM_KEYUP:  
  83.             switch (wParam)  
  84.             {  
  85.                 case VK_SHIFT:  
  86.                     MessageBox(NULL, TEXT("Shift Key Up"), TEXT("Key Up"), MB_OK);  
  87.                     break;  
  88.             }  
  89.             return 0;  
  90.             break;  
  91.             // key down    
  92.         case WM_CHAR:  
  93.             if (getChar(wParam))  
  94.             {  
  95.                 MessageBox(NULL, TEXT("Character Pressed"), TEXT("char"), MB_OK);  
  96.             }  
  97.             return 0;  
  98.             break;  
  99.         case WM_DESTROY:  
  100.             PostQuitMessage(EXIT_SUCCESS);  
  101.             return 0;  
  102.     }  
  103.     return DefWindowProc(hwnd, message, wParam, lParam);  
  104. }  
Here's the another Win32 program that demonstrate KeyDown,Char events.

This program moves the window to Left,Right,Up or Down direction when those keys are down.
  1. #include "stdafx.h"  
  2. #include < Windows.h >  
  3. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  
  4. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)  
  5. {  
  6.     TCHAR appname[] = TEXT("Move Window");  
  7.     MSG msg;  
  8.     HWND hwnd;  
  9.     WNDCLASS wndclass;  
  10.     wndclass.cbClsExtra = 0;  
  11.     wndclass.cbWndExtra = 0;  
  12.     wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);  
  13.     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);  
  14.     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);  
  15.     wndclass.hInstance = hInstance;  
  16.     wndclass.lpfnWndProc = WndProc;  
  17.     wndclass.lpszClassName = appname;  
  18.     wndclass.lpszMenuName = NULL;  
  19.     wndclass.style = CS_HREDRAW | CS_VREDRAW;  
  20.     if (!RegisterClass( & wndclass))  
  21.     {  
  22.         MessageBox(NULL, TEXT("Class not registered"), TEXT("Error...."), MB_OK);  
  23.     }  
  24.     hwnd = CreateWindow(appname,  
  25.         appname,  
  26.         WS_OVERLAPPEDWINDOW,  
  27.         300,  
  28.         200,  
  29.         400,  
  30.         300,  
  31.         NULL,  
  32.         NULL,  
  33.         hInstance,  
  34.         NULL);  
  35.     ShowWindow(hwnd, iCmdShow);  
  36.     UpdateWindow(hwnd);  
  37.     while (GetMessage( & msg, NULL, 0, 0))  
  38.     {  
  39.         TranslateMessage( & msg);  
  40.         DispatchMessage( & msg);  
  41.     }  
  42.     return msg.wParam;  
  43. }  
  44. TCHAR * getString(int type)  
  45. {  
  46.     TCHAR * str = L "";  
  47.     switch (type)  
  48.     {  
  49.         case 1:  
  50.             str = L "UP     :      Move Window Upward";  
  51.             break;  
  52.         case 2:  
  53.             str = L "Down     :      Move Window Downward";  
  54.             break;  
  55.         case 3:  
  56.             str = L "Left     :      Move Window to Left";  
  57.             break;  
  58.         case 4:  
  59.             str = L "Right     :      Move Window to Right";  
  60.             break;  
  61.         case 5:  
  62.             str = L " +     :      Increase Size of Window";  
  63.             break;  
  64.         case 6:  
  65.             str = L " -     :      Decrease Size of Window";  
  66.             break;  
  67.     }  
  68.     return str;  
  69. }  
  70. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  71. {  
  72.     HDC hdc;  
  73.     RECT rc;  
  74.     static int X, Y;  
  75.     PAINTSTRUCT ps;  
  76.     HWND hwndSmaller;  
  77.     switch (message)  
  78.     {  
  79.         case WM_CREATE:  
  80.             return 0;  
  81.             break;  
  82.         case WM_PAINT:  
  83.             hdc = BeginPaint(hwnd, & ps);  
  84.             SetTextColor(hdc, RGB(0, 0, 180));  
  85.             TextOut(hdc, 5, 5, getString(1), 32);  
  86.             TextOut(hdc, 5, 25, getString(2), 36);  
  87.             TextOut(hdc, 5, 45, getString(3), 35);  
  88.             TextOut(hdc, 5, 65, getString(4), 37);  
  89.             TextOut(hdc, 5, 85, getString(5), 37);  
  90.             TextOut(hdc, 5, 105, getString(6), 37);  
  91.             EndPaint(hwnd, & ps);  
  92.             return 0;  
  93.             break;  
  94.         case WM_SIZE:  
  95.             X = LOWORD(lParam);  
  96.             Y = HIWORD(lParam);  
  97.             return 0;  
  98.             break;  
  99.             // key down    
  100.         case WM_KEYDOWN:  
  101.             switch (wParam)  
  102.             {  
  103.                 case VK_LEFT:  
  104.                     GetWindowRect(hwnd, & rc);  
  105.                     rc.left -= X / 20;  
  106.                     rc.right -= X / 20;  
  107.                     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);  
  108.                     break;  
  109.                 case VK_RIGHT:  
  110.                     GetWindowRect(hwnd, & rc);  
  111.                     rc.left += X / 20;  
  112.                     rc.right += X / 20;  
  113.                     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);  
  114.                     break;  
  115.                 case VK_UP:  
  116.                     GetWindowRect(hwnd, & rc);  
  117.                     rc.bottom -= X / 20;  
  118.                     rc.top -= X / 20;  
  119.                     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);  
  120.                     break;  
  121.                 case VK_DOWN:  
  122.                     GetWindowRect(hwnd, & rc);  
  123.                     rc.bottom += X / 20;  
  124.                     rc.top += X / 20;  
  125.                     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);  
  126.                     break;  
  127.                 case VK_ESCAPE:  
  128.                     PostQuitMessage(EXIT_SUCCESS);  
  129.                     return 0;  
  130.             }  
  131.             return 0;  
  132.             break;  
  133.         case WM_CHAR:  
  134.             switch (wParam)  
  135.             {  
  136.                 //increase size of window    
  137.                 case '+':  
  138.                     GetWindowRect(hwnd, & rc);  
  139.                     rc.left -= X / 20;  
  140.                     rc.right += X / 20;  
  141.                     rc.top -= Y / 20;  
  142.                     rc.bottom += Y / 20;  
  143.                     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);  
  144.                     break;  
  145.                     // decrease size of window    
  146.                 case '-':  
  147.                     GetWindowRect(hwnd, & rc);  
  148.                     rc.left += X / 20;  
  149.                     rc.right -= X / 20;  
  150.                     rc.top += Y / 20;  
  151.                     rc.bottom -= Y / 20;  
  152.                     MoveWindow(hwnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);  
  153.                     break;  
  154.             }  
  155.             return 0;  
  156.             break;  
  157.         case WM_DESTROY:  
  158.             PostQuitMessage(EXIT_SUCCESS);  
  159.             return 0;  
  160.     }  
  161.     return DefWindowProc(hwnd, message, wParam, lParam);  
  162. }  
GetWindowRect() this function returns the rectangle parameters of the given window such as x,y,width,height.
 
Above program moves the window to left direction when Left key down,same as Right,Up,Down.
 
It increases the size of window when '+' character is pressed & decreases the size of window when '-' character is pressed.

MoveWindow() this function moves the window from one position to another position with its width & height.

It takes four parameters of HWND,x,y,width,height,BOOL.

Here's the output of above program.

 

X

Build smarter apps with Machine Learning, Bots, Cognitive Services - Start free.

Start Learning Now