BCX Documentation Version 8.1.0, June 30, 2024

Started by Robert, June 30, 2024, 10:02:56 PM

Previous topic - Next topic

Robert

BCX Documentation Version 8.1.0, June 30, 2024

Ad Rienks
... added to the KEYPRESS function Return Value: section a list of typical values for Function Key presses.

... added to the INKEY function Return Value: section a list of typical values for Function Key presses.

Robert Wishlaw
... replaced instances of the obsolete BCX keyword "BCX_TmpStr" with its replacement "BCX_TempStr".

... added MACRO and CONST to the list prohibiting encasement by control flow conditional directives.

Ad_Rienks

Hi Robert,

Thank you for the addition to the INKEY and KEYPRESS documentation, but, unfortunately, there are more `Special Keys` that give negative values.
If I use Kevins example app, these are my results:

HOME   : -71
END     : -79
PgUp    : -73
PgDn    : -81
Insert   : -82
Delete  : -83
NumLk : -69
Pause   : -69
ScrlLoc : -70
cursor keys:
Up  : -72
Dn  : -80
Lft  : -75
Rgt : -77

Of course, it might be dependent on the signals that the keyboard emits, but I do not have another make of keyboard to test!

MrBcx

#2
Quote from: Ad_Rienks on July 01, 2024, 06:04:33 AM
Hi Robert,

Thank you for the addition to the INKEY and KEYPRESS documentation, but, unfortunately,
there are more `Special Keys` that give negative values.   

Hello Ad, et al

I understand you to mean it's unfortunate that Robert has not included all the negative values in
the Help file, and not that there is anything inherently unfortunate about the values being negative. 
In fact, they are negative for a reason.  That the values might differ on some keyboards would certainly be
an annoyance but I've not personally experienced that with any keyboard I've ever used, wired or wireless.

Back in my MS-DOS days, I did a lot of programming using TurboBasic and PowerBasic. 

The PowerBasic INKEY$ implementation was explained in its Help files thusly:

INKEY$ function                                                           
  ───────────────                                                           
  Purpose:  Reads a character from the keyboard without echoing the         
            character to the screen.                                       
                                                                           
  Syntax:   s$ = INKEY$                                                     
                                                                           
  INKEY$ does not wait for a key to be pressed; it reads the keyboard       
  buffer immediately. INKEY$ returns a string of zero, one, or two         
  characters. A string of length zero means the buffer was empty. A         
  string of length one means that an ASCII key was pressed and the string   
  contains the ASCII character. A string of length two means a non-ASCII   
  key was pressed (such as a function key). In this case, the first         
  character in the string has a value of zero, and the second is an         
  extended keyboard code that represents one of the keyboard's
  non-ASCII keys.   
                                           

ChatGPT gives a nice explanation why some keys are negative when using BCX:

The negative values you are seeing are due to how certain keys are represented in
the keyboard input system, particularly in the context of the BCX BASIC INKEY function.

In many systems, extended keys (such as function keys, cursor keys, and other special keys)
are often represented using two-byte codes. The first byte is typically zero (indicating an extended key),
and the second byte represents the actual key code. When these codes are read and interpreted as signed
integers, the result can be negative values.

Here's a more detailed breakdown:

    Extended Keys:
    Keys like Home, End, Page Up, Page Down, Insert, Delete, Num Lock, Pause, Scroll Lock, and cursor keys
    are considered extended keys.

    Two-byte Representation:

    These keys generate a sequence where the first byte is zero (0x00) and the second byte is the actual scan
    code. When combined into a single value and interpreted as a signed integer, this can result in a negative value.


For example, let's consider the cursor keys:

    Up: 0x00 0x48 -> -72
    Down: 0x00 0x50 -> -80
    Left: 0x00 0x4B -> -75
    Right: 0x00 0x4D -> -77


The negative values come from interpreting the second byte in the context of signed integers.

If you want to handle these keys differently, you can use the absolute value of the key codes
or simply recognize the negative values in your code.

Here's an example of how you might handle these keys in a loop:

DIM ky AS INTEGER
DO
    ky = INKEY
    IF ky THEN
        IF ky < 0 THEN
            PRINT "Extended key: "; ky
        ELSE
            PRINT "Regular key: "; ky
        END IF
    END IF
LOOP UNTIL
ky = 27  ' ESC KEY


Alternatively, one can DIM ky AS UINT64, if one doesn't like negative numbers

DIM ky AS UINT64
DO
    ky = INKEY
    IF ky THEN
        IF ky < 0 THEN
            PRINT "Extended key: "; ky
        ELSE
            PRINT "Regular key: "; ky
        END IF
    END IF
LOOP UNTIL ky = 27  ' ESC KEY


Ad_Rienks

Hi Kevin, Robert, et al

I shouldn't have used the word unfortunately. My aim was that, to notify in the help of INKEY and KEYPRESS, users are warned that the extended keys behave differently.

You know https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
The Virtual-Key Codes mentioned there, the Extended Keys, Function Keys, cursor keys, et al could not be used.
Like Kevin writes, recognize these negative values in your code! using MACRO.

MrBcx

Here is a helpful way to use the various VK_ keys with INKEY / KEYPRESS:



DIM ky AS INTEGER

DO
    ky = INKEY
    IF ky<0 THEN
        SELECT CASE Convert_To_VK (ky)
        CASE VK_F1 : PRINT "You pressed the VK_F1"          ' WINAPI defines VK_F1 = 112
        CASE VK_F2 : PRINT "You pressed the VK_F2"          ' WINAPI defines VK_F2 = 113
        CASE VK_F3 : PRINT "You pressed the VK_F3"          ' WINAPI defines VK_F3 = 114
        CASE VK_F4 : PRINT "You pressed the VK_F4"          ' WINAPI defines VK_F4 = 115
        CASE VK_F5 : PRINT "You pressed the VK_F5"          ' WINAPI defines VK_F5 = 116
        CASE ELSE  : PRINT "You pressed extended key ", ky
        END SELECT
    ELSE
        IF ky > 0 THEN PRINT "You pressed the ", CHR$(ky), " key"
    END IF
LOOP UNTIL ky = 27  ' ESC KEY


FUNCTION Convert_To_VK (Inkey_Value AS INTEGER) AS INTEGER
    FUNCTION = ABS(Inkey_Value) + 53
END FUNCTION




Robert

Quote from: Ad_Rienks on July 01, 2024, 06:04:33 AM
Hi Robert,

Thank you for the addition to the INKEY and KEYPRESS documentation, but, unfortunately, there are more `Special Keys` that give negative values.
If I use Kevins example app, these are my results:

HOME   : -71
END     : -79
PgUp    : -73
PgDn    : -81
Insert   : -82
Delete  : -83
NumLk : -69
Pause   : -69
ScrlLoc : -70
cursor keys:
Up  : -72
Dn  : -80
Lft  : -75
Rgt : -77

Of course, it might be dependent on the signals that the keyboard emits, but I do not have another make of keyboard to test!

Thanks Ad.
Now I see what is missing. I will revise the Function key comments added in the last version of the help file to information on extended keys in general.

Ad_Rienks

Quote from: MrBcx on July 01, 2024, 11:23:58 AM
Here is a helpful way to use the various VK_ keys with INKEY / KEYPRESS:



DIM ky AS INTEGER

DO
    ky = INKEY
    IF ky<0 THEN
        SELECT CASE Convert_To_VK (ky)
        CASE VK_F1 : PRINT "You pressed the VK_F1"          ' WINAPI defines VK_F1 = 112
        CASE VK_F2 : PRINT "You pressed the VK_F2"          ' WINAPI defines VK_F2 = 113
        CASE VK_F3 : PRINT "You pressed the VK_F3"          ' WINAPI defines VK_F3 = 114
        CASE VK_F4 : PRINT "You pressed the VK_F4"          ' WINAPI defines VK_F4 = 115
        CASE VK_F5 : PRINT "You pressed the VK_F5"          ' WINAPI defines VK_F5 = 116
        CASE ELSE  : PRINT "You pressed extended key ", ky
        END SELECT
    ELSE
        IF ky > 0 THEN PRINT "You pressed the ", CHR$(ky), " key"
    END IF
LOOP UNTIL ky = 27  ' ESC KEY


FUNCTION Convert_To_VK (Inkey_Value AS INTEGER) AS INTEGER
    FUNCTION = ABS(Inkey_Value) + 53
END FUNCTION





If I add this CASE: CASE VK_HOME : PRINT "You pressed the VK_HOME" You pressed extended key -71 is printed!

Robert

Attached is a photo of a portion of the keyboard from the last Hewlett Packard system that I bought several years ago. It supports both ANSI and ISO keyboard standards  as well as Canadian English and French keyboard layouts.

I dug it out of storage to see what is what with the codes.

For those interested, have a look at the Win32 API function MapVirtualKey at

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapvirtualkeya

MrBcx

Quote from: Ad_Rienks on July 01, 2024, 01:27:52 PM

If I add this CASE: CASE VK_HOME : PRINT "You pressed the VK_HOME" You pressed extended key -71 is printed!

Ad,

FUNCTION Convert_To_VK (Inkey_Value AS INTEGER) AS INTEGER
    FUNCTION = ABS(Inkey_Value) + 53
END FUNCTION

will need to be expanded, as the "+ 53" only works for a range of keys.  I suspect
there may be a dozen or more offsets needed to cover the entire range of extended keys,
along with their Ctrl, Alt, and Shift variations. 
  I'll leave those exercises for others.  I showed how it could be done.

MrBcx

Quote from: Robert on July 01, 2024, 01:51:21 PM
Attached is a photo of a portion of the keyboard from the last Hewlett Packard system that I bought several years ago. It supports both ANSI and ISO keyboard standards  as well as Canadian English and French keyboard layouts.

I dug it out of storage to see what is what with the codes.

For those interested, have a look at the Win32 API function MapVirtualKey at

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapvirtualkeya

Robert - I've never seen a keyboard like that before.  It's pretty interesting.

The trip down the Microsoft keyboard API rabbit hole is becoming tedious and boring; time for me to focus on something else.


Quin

Quote from: MrBcx on July 01, 2024, 02:18:24 PM
Quote from: Robert on July 01, 2024, 01:51:21 PM
Attached is a photo of a portion of the keyboard from the last Hewlett Packard system that I bought several years ago. It supports both ANSI and ISO keyboard standards  as well as Canadian English and French keyboard layouts.

I dug it out of storage to see what is what with the codes.

For those interested, have a look at the Win32 API function MapVirtualKey at

https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-mapvirtualkeya

Robert - I've never seen a keyboard like that before.  It's pretty interesting.

The trip down the Microsoft keyboard API rabbit hole is becoming tedious and boring; time for me to focus on something else.

Oh man this is interesting. A current project of mine is working with low-level keyboard APIs for a C++ game engine (nvgt.gg), and I was looking at this function just a couple hours ago.
-Quin.
GitHub