KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q65925: Using OS/2 API Calls for Keyboard Input from BASIC PDS

Article: Q65925
Product(s): See article
Version(s): 7.00 7.10
Operating System(s): OS/2
Keyword(s): ENDUSER | SR# S900831-121 | mspl13_basic
Last Modified: 19-OCT-1990

This article contains a sample BASIC module, which calls the OS/2 API
functions to perform a simple keyboard input routine in protected
mode.

This information applies to Microsoft BASIC compiler versions 6.00 and
6.00b for MS OS/2 (for protected mode only) and Microsoft BASIC
Professional Development System (PDS) versions 7.00 and 7.10 for MS
OS/2 (for protected mode only).

For more information on the OS/2 keyboard input functions, please
refer to the "Microsoft OS/2 Programmer's Reference" Volume 3, Pages
164-180, published by Microsoft Press (1989).

OS/2 protected mode allows for multiple logical keyboard buffers to be
set up and used by a process. When a logical keyboard buffer is
opened, it does not receive any characters until that buffer is given
the focus by the KbdGetFocus function. When a keyboard buffer has the
focus, it receives all characters that are typed in through the
keyboard.

The largest string that can be typed in is determined by the buffer
that the program sets up; in this example, the buffer is set to 40.
Any extra characters are ignored until the BACKSPACE, DEL, or arrow
keys are pressed.

This sample program uses the KbdOpen and KbdGetFocus function to open
a logical keyboard. It then uses the KbdGetStatus and KbdSetStatus
functions to preserve the status of the keyboard and then to modify
the status, forcing the CAPSLOCK key on. It also uses the
VioSetCurType function to set the display of the cursor (by default
there is no cursor).

To run the program in OS/2 protected mode, the program should be
compiled and linked as follows:

     BC /Lp OS2KEY;
     LINK OS2KEY,,,BRT71ENP.LIB+OS2.LIB;

OS2KEY.BAS
----------

'This sample program OS2KEY.BAS uses OS/2 keyboard input routines.
'Wait flags for keyboard input and status check:
CONST IOWAIT     = 0
CONST IONOWAIT   = 1
'Constant declarations for KdbInfo.fsMask:
CONST KEYBOARDECHOON            = &H0001
CONST KEYBOARDECHOOFF           = &H0002
CONST KEYBOARDBINARYMODE        = &H0004
CONST KEYBOARDASCIIMODE         = &H0008
CONST KEYBOARDMODIFYSTATE       = &H0010
CONST KEYBOARDMODIFYINTERIM     = &H0020
CONST KEYBOARDMODIFYTURNAROUND  = &H0040
CONST KEYBOARD2BTURNAROUND      = &H0080
CONST KEYBOARDSHIFTREPORT       = &H0100
'Constant declarations for Keyboard flags:
CONST RIGHTSHIFT    = &H0001
CONST LEFTSHIFT     = &H0002
CONST CONTROL       = &H0004
CONST ALT           = &H0008
CONST SCROLLLOCKON  = &H0010
CONST NUMLOCKON     = &H0020
CONST CAPSLOCKON    = &H0040
CONST INSERTON      = &H0080
CONST LEFTCONTROL   = &H0100
CONST LEFTALT       = &H0200
CONST RIGHTCONTROL  = &H0400
CONST RIGHTALT      = &H0800
CONST SCROLLLOCK    = &H1000
CONST NUMLOCK       = &H2000
CONST CAPSLOCK      = &H4000
CONST SYSREQ        = &H8000
TYPE KbdInfoType    'KbdInfo structure
    cb           AS INTEGER
    fsMask       AS INTEGER
    chTurnAround AS INTEGER
    fsInterim    AS INTEGER
    fsState      AS INTEGER
END TYPE
TYPE StringInBufType    'StringInBuf structure
    cb    AS INTEGER
    cchIn AS INTEGER
END TYPE
TYPE StringBufType    'Fixed length string to receive input characters
    Chars AS STRING * 40   'BASIC doesn't allow passing fixed length
END TYPE                   'strings, so use a user-defined type of
                           'a fixed length string.
TYPE VioCursorInfoType   'Type that holds the cursor attributes
    yStart AS INTEGER
    cEnd   AS INTEGER
    cx     AS INTEGER
    attr   AS INTEGER
END TYPE
'The fundamental OS/2 Keyboard functions
DECLARE FUNCTION KbdOpen% (SEG hkbd%)
DECLARE FUNCTION KbdClose% (BYVAL hkbd%)
DECLARE FUNCTION KbdGetStatus% (SEG KbdInfo AS KbdInfoType, BYVAL hkbd%)
DECLARE FUNCTION KbdSetStatus% (SEG KbdInfo AS KbdInfoType, BYVAL hkbd%)
DECLARE FUNCTION KbdGetFocus% (BYVAL fWait%, BYVAL hkbd%)
DECLARE FUNCTION KbdFreeFocus% (BYVAL hkbd%)
DECLARE FUNCTION KbdStringIn% (SEG chBuffer AS StringBufType, _
        SEG StringInBuf AS StringInBufType, BYVAL fWait%, BYVAL hkbd%)
DECLARE FUNCTION VioSetCurType% (SEG VioCursorInfo AS _
                                 VioCursorInfoType, BYVAL hvio%)
'Dimension the structured variables
DIM KbdInfo AS KbdInfoType
DIM PrevkbdInfo AS KbdInfoType
DIM StringInBuf AS StringInBufType
DIM chBuffer AS StringBufType
DIM VioCursorInfo AS VioCursorInfoType
CLS
ReturnVal% = KbdOpen%(hkbd%)             'Open a logical Keyboard
IF ReturnVal% = 0 THEN
 PRINT "Opened logical keyboard"
 PRINT "Getting the focus: ";
 ReturnVal% = KbdGetFocus%(IONOWAIT, hkbd%)   'Make it the one to
                                              'receive keyboard
 IF ReturnVal% = 0 THEN                       'input
    PRINT "we have the focus"
    'Save the previous state of the keyboard, so it can be reset:
    PRINT "Saving the previous state of the input mode"
    PRINT "Getting the status and checking for echo mode, input mode"
    PrevkbdInfo.cb = LEN(KbdInfo)
    ReturnVal% = KbdGetStatus%(PrevkbdInfo, hkbd%)
    IF RetrunVal% = 0 THEN
      'Check echo mode:
      IF (PrevkbdInfo.fsMask AND KEYBOARDECHOON) THEN
       PRINT "Echo on, ";
      ELSE
       PRINT "Echo off, ";
      END IF
      'Check input mode:
      IF (PrevkbdInfo.fsMask AND KEYBOARDASCIIMODE) THEN  '
       PRINT "Ascii mode"
      ELSE
       PRINT "Binary Mode"
      END IF
      'Set the cursor type: size, and attribute:
      VioCursorInfo.yStart = 12    'beginning scan line for cursor
                                   'starting from top position
      VioCursorInfo.cEnd = 13      'ending scan line, zero-based
      VioCursorInfo.cx = 0         'default width, one character
      VioCursorInfo.attr = 0       'normal attribute, &hffff is hidden
      hvio% = 0                    'video handle
      ReturnVal% = VioSetCurType%(VioCursorInfo, hvio%)
      IF ReturnVal% = 0 THEN
       PRINT "Cursor is the normal TWO scan lines tall"
      END IF

      'Initialize KbdInfo to the new status:
      PRINT "Setting the CAPSLOCK on"
      KbdInfo.cb = LEN(KbdInfo)
      KbdInfo.chTurnAround = PrevkbdInfo.chTurnAround
      KbdInfo.fsInterim = PrevkbdInfo.fsInterim
      KbdInfo.fsMask = (PrevkbdInfo.fsMask OR _    'Turn on the modify
                        KEYBOARDMODIFYSTATE)       'state
      KbdInfo.fsState = (PrevkbdInfo.fsState OR _  'force caps lock on
                         CAPSLOCKON)
      ReturnVal% = KbdSetStatus%(KbdInfo, hkbd%)   'Set the status
      IF ReturnVal% = 0 THEN
       PRINT "Caps lock should be on"
       PRINT "Input some characters: ";
       StringInBuf.cb = LEN(chBuffer)
       'Input the string:
       RetrunVal% = KbdStringIn%(chBuffer, StringInBuf, IOWAIT, hkbd%)

     'During input, OS/2 does not advance the cursor, to prevent
     'writing over what was typed, use a LOCATE statement, or a double
     'PRINT to advance the cursor position
       PRINT : PRINT "This is what you typed: "; chBuffer.Chars
       SLEEP (3)                       'Sleep for three seconds
      ELSE
       PRINT "Caps on failed"
      END IF
      'Start cleaning up, restore the status, free focus, and close
      'keyboard:
      PRINT "Restoring the status"
      RetrunVal% = KbdSetStatus%(PrevKbdInfo, hkbd%)
      IF RetrunVal% = 0 THEN
       PRINT "Status Returned"
      ELSE
       PRINT "Status Could Not Be Restored
      END IF

      'Free the focus and close the logical keyboard
      PRINT "Freeing the focus and closing keyboard"
      ReturnVal% = KbdFreeFocus%(hkbd%)
      IF ReturnVal% = 0 THEN
       ReturnVal% = KbdClose%(hkbd%)
       IF ReturnVal% = 0 THEN
         PRINT "Keyboard closed"
       ELSE
         PRINT "Keyboard could not be closed, Error= "; ReturnVal%
       END IF
      ELSE
       PRINT "Focus could not be freed: "; ReturnVal%
      END IF
    ELSE
     PRINT "Get status failed: "; RetrunVal%
    END IF
 ELSE
    PRINT "ERROR on Focus, ReturnVal% = "; ReturnVal%
 END IF
ELSE
    PRINT "Logical keyboard could not be opened"
END IF
END

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.