1.11M Members

Reading Scan Codes from the Keyboard

 
2
 

Introduction

Hello everyone. This little code snippet shows you how to read in scan codes from the keyboard. It is slightly different than reading in a regular character. When you use the getch() function, it is normally returning an ASCII value. Some keyboards have extra keys though. These include the F1 - F12 function keys and the directional arrows to start. These keys do not have an ASCII code. A char data type is a one byte item. When you press a key that doesn't have an ASCII code, it returns two bytes. If the first byte is 0, then the next byte contains the scan code. In the following code, I include the scan code for many typical keys and how to read them.

Notes:

  • Even though there are two calls to getch() , it does not require two keystrokes.
  • Not all of these scan codes may be 100% accurate for all computers. It may, of course, need some modifications.
/* This program shows how to pick up the scan codes from a keyboard */

/* These define the scan codes(IBM) for the keys. All numbers are in decimal.*/
#define PAGE_UP     73
#define HOME        71
#define END         79
#define PAGE_DOWN   81
#define UP_ARROW    72
#define LEFT_ARROW  75
#define DOWN_ARROW  80
#define RIGHT_ARROW 77
#define F1          59
#define F2          60
#define F3          61
#define F4          62
#define F5          63
#define F6          64
#define F7          65
#define F8          66
#define F9          67
#define F10         68
#include <iostream>
#include <conio.h>

using namespace std;

void main()
{
	char KeyStroke;

	cout << "Press Escape to quit." << endl;
	
	do
	{
		KeyStroke =	getch();

		if (KeyStroke == 0)
		{
			KeyStroke = getch(); // Even though there are 2 getch() it reads one keystroke
			switch (KeyStroke)
			{
			case PAGE_UP:
				cout << "PAGE UP" << endl;
				break;
			case PAGE_DOWN:
				cout << "PAGE DOWN" << endl;
				break;
			case HOME:
				cout << "HOME" << endl;
				break;
			case END:
				cout << "END" << endl;
				break;
			case UP_ARROW:
				cout << "UP ARROW" << endl;
				break;
			case DOWN_ARROW:
				cout << "DOWN ARROW" << endl;
				break;
			case LEFT_ARROW:
				cout << "LEFT_ARROW" << endl;
				break;
			case RIGHT_ARROW:
				cout << "RIGHT_ARROW" << endl;
				break;
			case F1:
				cout << "F1" << endl;
				break;
			case F2:
				cout << "F2" << endl;
				break;
			case F3:
				cout << "F3" << endl;
				break;
			case F4:
				cout << "F4" << endl;
				break;
			case F5:
				cout << "F5" << endl;
				break;
			case F6:
				cout << "F6" << endl;
				break;
			case F7:
				cout << "F7" << endl;
				break;
			case F8:
				cout << "F8" << endl;
				break;
			case F9:
				cout << "F9" << endl;
				break;
			case F10:
				cout << "F10" << endl;
				break;
			default:
				cout << "Some other key." << endl;
			}
		}
		else
			cout << KeyStroke << endl;
	} 
	while (KeyStroke != 27); // 27 = Escape key
}
A simple program that shows you how to read the keyboard scan code for keys that don't have a normal ASCII code. It includes typical scan codes for the function keys and and the arrow keys.
 
1
 

One modification for those under vista/visual 2008:

KeyStroke =getch();
if (KeyStroke == -32)  //weird, i know.... but it works
{
	KeyStroke = getch();
...}

thk you for the ideea. :hat off:

 
0
 

thanks a lot..

if (KeyStroke == -32)

works on DevC++ Windows XP.

 
-1
 

This "code" has no sense at all (case, case, case... horrible !!!!)
It's done in 1 line of code with Win32 api (VK)

 
0
 

@macro93 can u please explain how it can be done using Win32 api?

 
1
 

win32 api doesn't work on non-Windows platforms, but this code snippet will work with some possible mods to the defines at the top.

 
0
 

I tried this and the left,right,up,down keys are returning aH aP and so on. F1-F9 work fine. So, If I wanted to control a stepper motor, I would need to learn how to use scan keys. Problem is, I need to figure why the scancodes for the arrow keys are not outputting correctly.

Can any of you try this? I am running xp pro.

 
0
 

I compiled the code in Dev-C++ in Windows XP and the F1-F9 keys were working properly, however the arrow keys printed out αH, αP, etc...

When i changed the code to Keystroke == -32 the arrow keys worked correctly but the F1-F9 keys didn't work properly.

I solved the problem with the following code:

if (KeyStroke == 0 || -32)
 
0
 

You mean like this if (KeyStroke == 0 || KeyStroke == -32)

 
0
 

^oops, yeah that's what i meant.

Thanks.

 
-1
 

thanks a mile mate..!!

 
0
 

Hi, all!

I,ve made some changes in the program code and now everything works fine. Now you can read F11, F12, ARROW keys and the other keys as it must be.

/* This program shows how to pick up the scan codes from a keyboard */
	 
	/* These define the scan codes(IBM) for the keys. All numbers are in decimal.*/
	#define PAGE_UP     73
	#define HOME        71
	#define END         79
	#define PAGE_DOWN   81
	#define UP_ARROW    72
	#define LEFT_ARROW  75
	#define DOWN_ARROW  80
	#define RIGHT_ARROW 77
	#define F1          59
	#define F2          60
	#define F3          61
	#define F4          62
	#define F5          63
	#define F6          64
	#define F7          65
	#define F8          66
	#define F9          67
	#define F10         68
	#include <iostream>
	#include <conio.h>
	 
	using namespace std;
	 
	int main()
	{
		unsigned char KeyStroke,c; unsigned int KStroke;
	 
		cout << "Press Escape to quit." << endl << endl;
	 
		do
		{
		c = char(getch());	KeyStroke =	c;   KStroke = int(KeyStroke);  
            
            if (KStroke == 72){cout << "UP ARROW" << endl;} 
            if (KStroke == 80){cout << "DOWN ARROW" << endl;}
            if (KStroke == 75){cout << "LEFT ARROW" << endl;} 
            if (KStroke == 77){cout << "RIGHT ARROW" << endl;}
            if (KStroke == 83){cout << "Delete" << endl;} 
            if (KStroke == 73){cout << "PAGE UP" << endl;}
            if (KStroke == 81){cout << "PAGE DOWN" << endl;} 
            if (KStroke == 71){cout << "HOME" << endl;} 
            if (KStroke == 79){cout << "END" << endl;}
            if (KStroke == 133){cout << "F11" << endl;} 
            if (KStroke == 134){cout << "F12" << endl;} 
            if (KStroke == 82){cout << "Insert" << endl;} 
            if (KStroke == 9){cout << "Tab" << endl;}
	        	        
			if (KeyStroke == 0)
			{
				KeyStroke = getch(); // Even though there are 2 getch() it reads one keystroke
				switch (KeyStroke)
				{
				case F1:
					cout << "F1" << endl;
					break;
				case F2:
					cout << "F2" << endl;
					break;
				case F3:
					cout << "F3" << endl;
					break;
				case F4:
					cout << "F4" << endl;
					break;
				case F5:
					cout << "F5" << endl;
					break;
				case F6:
					cout << "F6" << endl;
					break;
				case F7:
					cout << "F7" << endl;
					break;
				case F8:
					cout << "F8" << endl;
					break;
				case F9:
					cout << "F9" << endl;
					break;
				case F10:
					cout << "F10" << endl;
					break;
				default:
					cout << "Some other key." << endl;
				}
			}
			if((KeyStroke!=0)&&(KeyStroke!=72)&&(KeyStroke!=80)&&(KeyStroke!=75)&&(KeyStroke!=77)&&(KeyStroke!=83)&&(KeyStroke!=73)&&(KeyStroke!=81)&&(KeyStroke!=71)&&(KeyStroke!=79)&&(KeyStroke!=133)&&(KeyStroke!=134)&&(KeyStroke!=89)&&(KeyStroke!=9)){cout<<c<<endl;}
            
		} 
		while (KeyStroke != 27); // 27 = Escape key
	}
 
0
 

The only problem with these changes and the code at all, as you can see, is the conflic with conio.h library and getch(). And thats why when you press arrow keys or F11, F12 appear a letter (p) before it. I still can't resolve this but hope I'll find other solution.

 
1
 

getch() will return either 0 or 224 when you press special keys like F1-F10 and arrow keys. If it doesn't return one of those two values then you just pressed a normal key. After getting either 0 or 224 you have to call getch() again, then convert that value to something with will not duplicate normal keys. I've seen two different methods of conversion, either can be used as long as you use them consistently.

  1. make the keystroke value negative. Such as keystroke = -getch();
  2. Add 255 to the value such as keystroke = getch() + 255;

Run this little program and press several keys to find out how it works.

#include <stdio.h>
#include <conio.h>

int main()
{
    int keystroke;
    while(1)
    {
        keystroke = getch();
        printf("keystroks = %d\n", keystroke);
        if( keystroke == 0 || keystroke == 224)
             keystroke = getch() + 255;
        printf("keystroks = %d\n", keystroke);
    }
            
}
 
1
 

In the program you posted you will have to define all the special keys to have different values -- you can't use those values because they conflict with normal keys.

Then just delete lines 37-49 because they are all wrong. You won't get any of those values on the first call to getch().

The if statement on line 51 also needs to check for value of 224 because thats what is returned when an arrow key is pressed.

 
0
 

Ancient Dragon, Thanks for the answer!

In your post you said that "getch() will return either 0 or 224 when you press special keys like F1-F10 and arrow keys" and I agree with you.

But how we can see and from your program code for every key there are 2 equal values except for the special keys where the first value is always 224, but the second value is different and unique for every funct. key. For example F11 and F12 have next 2 values: 1st 224 and 2nd 133 for F11 & 224 and 134 for F12.

In my code I am using the second value for my goal in lines 37 - 49. I am sure this code is not correct and thats why I am searching for another solution.

 
0
 

As I said before, when a special key is pressed add the value 255 to the second call to getch() to make the key unique from all other keys on the keyboard. That way your program will always be able to distinguish F1 key from the semicolon, which also has key code of 59.

 
1
 

Here is what I mean. Note that variable KeyStroke must be int, not char because it will have a value > 255 for special keys.

#include <iostream>
	#include <conio.h>
/* This program shows how to pick up the scan codes from a keyboard */
	 
	/* These define the scan codes(IBM) for the keys. All numbers are in decimal.*/
	#define PAGE_UP     (73+255)
	#define HOME        (71+255)
	#define END         (79+255)
	#define PAGE_DOWN   (81+255)
	#define UP_ARROW    (72+255)
	#define LEFT_ARROW  (75+255)
	#define DOWN_ARROW  (80+255)
	#define RIGHT_ARROW (77+255)
	#define F1          (59+255)
	#define F2          (60+255)
	#define F3          (61+255)
	#define F4          (62+255)
	#define F5          (63+255)
	#define F6          (64+255)
	#define F7          (65+255)
	#define F8          (66+255)
	#define F9          (67+255)
	#define F10         (68+255)
	 
	using namespace std;
	 
	int main()
	{
		int KeyStroke;
	 
		cout << "Press Escape to quit." << endl << endl;
	 
		do
		{
		    KeyStroke = getch();
                    if( KeyStroke == 0 || KeyStroke == 224)
                        KeyStroke = getch()+255;
			switch (KeyStroke)
			{
				case F1:
					cout << "F1" << endl;
					break;
				case F2:
					cout << "F2" << endl;
					break;
				case F3:
					cout << "F3" << endl;
					break;
				case F4:
					cout << "F4" << endl;
					break;
				case F5:
					cout << "F5" << endl;
					break;
				case F6:
					cout << "F6" << endl;
					break;
				case F7:
					cout << "F7" << endl;
					break;
				case F8:
					cout << "F8" << endl;
					break;
				case F9:
					cout << "F9" << endl;
					break;
				case F10:
					cout << "F10" << endl;
					break;
				default:
					cout << "Some other key." << KeyStroke << '\n';
			}
            
		}while (KeyStroke != 27); // 27 = Escape key
	}
 
0
 

Ok, but how you will do it for F11, F12, ARROWS, HOME, END and the other funct. keys. This is the problem for me.

 
0
 

Sorry, my mistake. I read again your example and find what you wnat to say me :) Thank you very much Ancient Dragon for the advise.

You
Post:
Start New Discussion
Tags Related to this Article