Solved

How to know which key has been pressed in the keyboard

Posted on 1998-10-29
11
801 Views
Last Modified: 2008-02-20
I would like to know how to know which key is pressed on
the keyboard.be it a single stroke or a combination.i am
writing a text editior and would like the usage of ctrl and
alt keys.The problem i face is i am unable to know when a numlock or a caps is pressed(as i am displaying it on the screen).i tried to get the value from port 0x60 but i find it difficult to apply it when the key remains depressed.
i am doing it in borland C++.

please help me out
0
Comment
Question by:girishr
  • 4
  • 2
  • 2
  • +3
11 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1176444
What OS?  DOS?  windows?  (if windows a true windows APP or a win32 console app?)
0
 

Expert Comment

by:Mithander
ID: 1176445
I agree with nietod, the best way we can help is if you provide more information.  If you want to try to read it from port 60h. then you probably want to write a interupt handler instead of just looking at the port.  then inside the handler, you could have some flags for alt, ctrl, shift (If you write a handler you need to handle capitol letters) etc.  I can't come up with the code off the top of my head, but if you would like I can post some code I have already written.  I would have to dig it up though, so let me know if you want it.
NOTE: This is not the easiest way to do it.  If you are writing it in dos, then you might want to do it this way.  But if you are doing it in windows, there are lots of easier ways to do this.  For example in VC++, you can request the state of a key. (Up or Down) then use that to see if the ctrl key is down when they press another key.  Let us know what operating system you are writting for, and what compiler you are using.
0
 

Author Comment

by:girishr
ID: 1176446
Edited text of question
0
 

Author Comment

by:girishr
ID: 1176447
Edited text of question
0
 

Expert Comment

by:LucJanssens
ID: 1176448
Hallo,

pressing a key is followed by a windows message like WM_KEYDOWN, WM_KEYUP.   For special keys the following windows messages are generated: WM_SYSTEMKEYDOWN, WM_SYSTEMKEYUP.  

You are able to write message response functions. Look in the help for ev_wm_keydown, ev_wm_systemkeydown.   Make a message response table. (DECLARE ...).

If you dedect by this way when a key is pressed, you can check the state of the keyboard in the following way:  (you can also look inside the received message)



void GetKeyboardState(lpbKeyState)

BYTE FAR* lpbKeyState;      /* address of array to receive virtual-key codes      */


The GetKeyboardState function copies the status of the 256 virtual-keyboard keys to the specified buffer.

Parameter      Description

lpbKeyState      Points to the 256-byte buffer that will receive the virtual-key codes.

Returns

This function does not return a value.

Comments

An application calls the GetKeyboardState function in response to a keyboard-input message. This function retrieves the state of the keyboard at the time the input message was generated.

If the high-order bit is 1, the key is down; otherwise, it is up. If the low-order bit is 1, the key is toggled. A toggle key, such as the CAPSLOCK key, is toggled if it has been pressed an odd number of times since the system was started. The key is untoggled if the low-order bit is 0.
Example

The following example simulates a pressed CTRL key:

BYTE pbKeyState[256];

GetKeyboardState((LPBYTE) &pbKeyState);
pbKeyState[VK_CONTROL] |= 0x80;
SetKeyboardState((LPBYTE) &pbKeyState);

See Also

GetKeyState, SetKeyboardState


Good Luck

Luc Janssens
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:girishr
ID: 1176449
hi luc,
sorry for not accepting your answering.but  i am working in borland turbo c++ under DOS platform  and it does not does not support ur answer.Please explain a situation where i keep pressing a key (the key pressed has to be displaed and i suddenly press the numlock.i would like to display if the numlock is on or off on the screeen.

0
 
LVL 22

Expert Comment

by:nietod
ID: 1176450
Do you mean that  the first key (not numlock) would still be held down when the second key (numlock) is pressed?

If so, you cannot use DOS's keyboard handler (It doesn't support two keys beign down seperately, exxcept for the modifier keys (shift, control, alt).  Also it doesn not report the numlock and caps lock keys.  So it sounds like you will have to write your own driver.

That means hooking the keyboard interrupt each time a key is pressed or released  and then communicating with the keyboard to learn what was pressed/released.  You then have to "queue" this information so your application can get it later.  You can't supply it directly to your application because the interrupt will occur asynchronously.  that is going to be a lot of work and You are going to need at least some assembly language to do it.   (And each time you screw up as you debug, you will probably have to reboot your computer.  that makes it slow.)
0
 

Expert Comment

by:yuvalw
ID: 1176451
There's a function called "inportb"
It doesnt wait for a key to be pressed like getch,
it is giving you the Hex value of the key/keys that were pressed while it was launched.

you can run a test file to see which is the value for a certin key you would like to know on (just put it in a loop and print the answer)
and that's all.
0
 

Author Comment

by:girishr
ID: 1176452
thanks
but i knew about it already.i would like better ways ro access them..
0
 

Expert Comment

by:Mithander
ID: 1176453
nietod,  
    You can actually do it with no assembly language.  C++ makes it very easy to write your onw handlers.  But I agree, it is a lot of work, and you can end up rebooting many times before it works right.

girishr,
    I do have some code that you can use to help get you started.  I wrote it for a game, so it is not quite right.  It only looks to see if seven or eight keys are down, then sets flags.  But it shoudn't be to hard to set up a queue that you can read off of.

Mithander
0
 

Accepted Solution

by:
Noteran earned 10 total points
ID: 1176454
Here comes a file with needed info ( If you want I can send you some of my own code that handles the keyboard ( I'm a Borland Turbo C++ Programmer too !! (DOS real-mode ))

//BEGIN FILE

ÚÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ Overview ³
ÀÄÄÄÄÄÄÄÄÄÄÙ

The operation of the keyboard is really quite simple. Every time a key
is pressed or released an interrupt 9 is generated, and reading the value
from port 60h tells you what happened.

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ Decoding the Keyboard Byte ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

So let's say you've installed an interrupt handler to handle all keyboard
events and when an interrupt is generated your handler reads the byte from
port 60h. What now?

Well..each key on the keyboard has an associated scan code which is contained
in the lower 7 bits of the byte. The most significant bit (ie bit 7) tells
you what was actually done, 0 = key was just pressed, 1 = key was just
released. If someone had just pressed the ESC key for instance, the port will
show a value of 1 (1 is the ESC key's scan code). If they hold their finger
on the button the keyboard will keep generating interrupt 9's and each
time the port will still show a value of 1. When the person releases the key
a final interrupt will be generated and the port will return 129 (1 + 128,
since the high bit will be set indicating the person has released the key).

Well...it's almost this simple. Some keys are "extended" keys. When an
extended key is pressed an interrupt is generated and the keyboard port
will return a value of 224 (E0h). This means that an extended key was pressed
and it's *extended* scan code will be available during the *next* interrupt.
Note that the left control key has a scan code of 29, while the *right*
control key has an *extended* scan code of 29. The same applies to the alt
keys and the arrow keys (keypad arrows vs the other ones).

It would be nice if all keys were created equal and we could just throw away
the 224 extended bytes and handle all the other bytes normally. Unfortunately
there are two buttons which on my machine at least (and others I have tested)
do some really weird stuff:

PrtScn
ÄÄÄÄÄÄ
Pressing this button will send *2* extended characters to the handler, 42
and 55, so the actual byte sequence will be 224, 42, 224, 55. (Also note
that the left shift key has a regular scan code of 42, so there goes our
idea of just throwing 224's away). Only the extended 55's are sent during
auto-repeat. When the key is released, the two are sent again with the high
bits set (224, 170, 224, and 183). If any of the shift or control keys are
being held down when the PrtScn button is pressed then only the (224, 55) is
sent when the key is pressed and only the (224, 183) is sent when it's
released. If the alt key is being held down (System Request) then the key
behaves like an ordinary key with scan code 84. The practical upshot of all
this is that the handlers you write to handle normal keys and extended keys
will work fine with all the different PrtScn combinations (although a program
would have to check normal key 84 *AND* extended key 55 in order to determine
if the key is currently being pressed).

Pause/Break
ÄÄÄÄÄÄÄÄÄÄÄ
Welcome to hell. If you press this key while either of the the control keys
are being held down, it will behave like extended key 70, at all other times
it will send the following bytes: (225, 29, 69, 225, 157, 197). Holding the
key down does not result in autorepeat. Taking your finger off the key does
not send any extra bytes, they appear to be sent after the "key down" bytes
when you first press the key. Notice that 225 isn't 224, so our normal
extended character handler will not take care of this. My personal theory is
that while a scan code of 224 (E0h) means there is 1 more character
following, a scan code of 225 (E1h) means there are *2* more following. I've
seen a number of keyboard handler libraries and they all seem to overlook
this key. So why not be the first kid on your block to have a keyboard
handler which properly supports the Pause/Break key? CHECK IT OUT!!

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ Writing a Handler ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

Writing a keyboard handler is fairly straightforward. This section will
show how to do it in Pascal (you C and asm programmers would probably already
know this stuff anyway).

First we'll declare a few things we'll need:

const KEYBOARDINTR = 9;
      KEYBOARDPORT = $60;

var BIOSKeyboardHandler : procedure;
    CallBIOSHandler : boolean;

The CallBIOSHandler variable will be initialised by the calling program. If
we also want the BIOS handler to process all keystrokes then this variable
must be set to true.

Next we need to store the value of the current handler and set up own our
own one. We'll use a procedure called KeyboardHandler to handle the actual
interrupt.

CallBIOSHandler := false; { ...or set it to true if you want. }
GetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);
SetIntVec(KEYBOARDINTR, Addr(KeyboardHandler));

Ok, so everything is now set up and our handler will now be able to process
all keyboard events. The actual interrupt handler could look like this:

{$F+}
procedure KeyboardHandler(Flags, CS, IP, AX, BX, CX, DX,
                          SI, DI, DS, ES, BP: Word);
interrupt;
var key : byte;
begin

  key := Port[KEYBOARDPORT];

  { PROCESS THE KEYSTROKE HERE }

  if CallBIOSHandler then

  { Call the BIOS keyboard handler if the calling program wants us to }
    begin
      asm pushf end;
      BIOSKeyboardHandler;
    end

  { Otherwise just acknowledge the interrupt }
  else Port[$20] := $20;
end;
{$F-}


When the program is finished we can set the old keyboard handler again:

SetIntVec(KEYBOARDINTR, @BIOSKeyboardHandler);

ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ A Word of Warning ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ

When I was writing a simple handler to test the info in this file I did
something REALLY stoopid which I would like to share with the world. I
thought that my program was stuffing the keyboard up because when I exited
the program my editor (Borland Pascal 7.0) would act as though the control
button was being held down (I'm sure some of you have already started
laughing by now). I had to press it after each time I ran the program
just to sort it out. After spending a few hours looking all over the place
for info on what could possibly be wrong I realised what I was doing. I was
pressing CTRL-F9 to compile the program which would also immediately make it
run and I was releasing the control key when my program was running, ie the
regular BIOS handler was not getting the control key's "key up" command and
still thought it was being held down when my program returned control to
it. Moron.....

ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
³ Scan Codes ³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ

The following is a list of all the regular key scan codes in numerical
order:

Scan                                   Scan
Code Key                               Code Key
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ             ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
 1   ESC                               44   Z
 2   1                                 45   X
 3   2                                 46   C
 4   3                                 47   V
 5   4                                 48   B
 6   5                                 49   N
 7   6                                 50   M
 8   7                                 51   , <
 9   8                                 52   . >
10   9                                 53   / ?
11   0                                 54   RIGHT SHIFT
12   - _                               55   *            (KEYPAD)
13   = +                               56   LEFT ALT
14   BACKSPACE                         57   SPACEBAR
15   TAB                               58   CAPSLOCK
16   Q                                 59   F1
17   W                                 60   F2
18   E                                 61   F3
19   R                                 62   F4
20   T                                 63   F5
21   Y                                 64   F6
22   U                                 65   F7
23   I                                 66   F8
24   O                                 67   F9
25   P                                 68   F10
26   [ {                               69   NUMLOCK      (KEYPAD)
27   ] }                               70   SCROLL LOCK
28   ENTER (RETURN)                    71   7 HOME       (KEYPAD)
29   LEFT CONTROL                      72   8 UP         (KEYPAD)
30   A                                 73   9 PGUP       (KEYPAD)
31   S                                 74   -            (KEYPAD)
32   D                                 75   4 LEFT       (KEYPAD)
33   F                                 76   5            (KEYPAD)
34   G                                 77   6 RIGHT      (KEYPAD)
35   H                                 78   +            (KEYPAD)
36   J                                 79   1 END        (KEYPAD)
37   K                                 80   2 DOWN       (KEYPAD)
38   L                                 81   3 PGDN       (KEYPAD)
39   ; :                               82   0 INSERT     (KEYPAD)
40   ' "                               83   . DEL        (KEYPAD)
41   ` ~                               87   F11
42   LEFT SHIFT                        88   F12


The following is a list of all the extended key scan codes in numerical
order:

Scan                                   Scan
Code Key                               Code Key
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ        ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
28   ENTER        (KEYPAD)              75   LEFT         (NOT KEYPAD)
29   RIGHT CONTROL                      77   RIGHT        (NOT KEYPAD)
42   PRINT SCREEN (SEE TEXT)            79   END          (NOT KEYPAD)
53   /            (KEYPAD)              80   DOWN         (NOT KEYPAD)
55   PRINT SCREEN (SEE TEXT)            81   PAGE DOWN    (NOT KEYPAD)
56   RIGHT ALT                          82   INSERT       (NOT KEYPAD)
71   HOME         (NOT KEYPAD)          83   DELETE       (NOT KEYPAD)
72   UP           (NOT KEYPAD)         111   MACRO
73   PAGE UP      (NOT KEYPAD)

// END FILE

Hope this is enough - if not contact me at NOTERAN@FREEMAIL.NL
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now