From: Shane.Greyvenstein@f61.n7101.z5.fidonet.org (Shane Greyvenstein)
Newsgroups: comp.lang.pascal
Subject: inputting non-character keys
Date: Sun, 08 Nov 92 12:01:05 GMT
Organization: FidoNet node 5:7101/61 - Pyramid, Pretoria

Hello Jack!

In a msg of <06 Nov 92>, Jack Hammond writes to All:

 -> How does Turbo Pascal (I have 5.0) read such non-character keys
 -> as the function keys, insert, home, pgup etc., and alt-keys?

Ok.  Well in posing this question, you're actually asking for two different parts of code.  The ALT/CTRL/LSHIFT/RSHIFT keys, etc. all generate SCAN codes and cannot be read via the ch:=readkey, etc. commands.  To find the scan code of a key, the following code can be used:


uses CRT,DOS;



var oldvec                 : pointer; { save old int 9 vec here }
    scode                  : byte;





procedure INT9HANDLER;  interrupt;

begin
  scode:=port[$60];                    { get the scan code }

  if scode<>0 then
  writeln(scode);                      { if not 0 then print }

  port[$20]:=$20;                      { tell PIC were done }
end;





begin
  writeln('Press ESC to quit ...');
  getintvec($09,oldvec);                   { hook in }
  setintvec($09,@int9handler);

  scode:=0;

  repeat                                { go until esc pressed }
  until scode=1;

  setintvec($09,oldvec);                { uninstall }
end.



As you can see, it's easily modifyable to process the keys.  Just change the interrupt handler to check for a certain scan code . and process it accordingly.  There is a FASTER method to do this too, without the use of interrupts.  All ALT/CTRL/SHIFT/etc. have their status bitmapped at adress $0000:$0417.  By declaring a byte absolute to this position, you can check the status of the keys using simple AND/OR routines.  The bitmap is as follows:

      bits           meaning
7 6 5 4 3 2 1 0
---------------------------------------
. . . . . . . 1     Right Shift
. . . . . . 1 .     Left Shift
. . . . . 1 . .     Ctrl
. . . . 1 . . .     Alt
. . . 1 . . . .     Scroll Lock
. . 1 . . . . .     Num Lock
. 1 . . . . . .     Caps Lock
1 . . . . . . .     Insert Lock
---------------------------------------

As for standard keys like F1, ENTER, etc, use the following:

uses CRT;





procedure PRINT_KEY;


var ch : char;


begin
  ch:=readkey;

  if ch=#0 then      { Key is extended.  (Function keys, INS, etc)
  begin
    write('Extended + #');
    ch:=readkey;     { Read second key in extended sequence }

    writeln(ord(ch));
  end

  else

  writeln(ord(ch);
end;



The above will print out the character codes for the keys desired. To process them, a simple case statement as follows is all that is needed:



begin
  ch:=readkey;

  case ch of

  #0  : begin
          ch:=readkey;

          case ch of
          #80 : writeln('UpArrow');
          end;
        end;

  #27 : writeln('ESC');
  end;
end;



Well, I hope that this answers all your questions.  It may be a bit unclear, but if so, don't hesitate to holler.

Kindest regards,
Shane

--  
INTERNET: Shane.Greyvenstein@f61.n7101.z5.fidonet.org
via:  THE CATALYST BBS in Port Elizabeth, South Africa.
       (catpe.alt.za)   +27-41-34-1122 HST or +27-41-34-2859, V32bis & HST.