Read NUMLOCK / CAPSLOCK from keyboard controller

Blitz3D Forums/Blitz3D Programming/Read NUMLOCK / CAPSLOCK from keyboard controller

_33(Posted 2007) [#1]
I have yet to find that out. Any hint on this greatly appreciated. If I do find it, I'll post it here. I'm here talking about the state of the CAPSLOCK and the state of the NUMLOCK, where the light is either on or off.

Maybe the two are not associated. Then I would need to program the lights :P

Cheers.


b32(Posted 2007) [#2]
You mean, checking their status ? The GetKeyState() function in user32.dll should be able to do that:

For changing them, I thing you could try using the Keybd_Event command.


_33(Posted 2007) [#3]
:o

Thanks a lot! I'll check it out right away! I was searching the code archive and whatnot, couldn't find anything on this.

I probably could of looked little more. This vaguely seems familiar.

Cheers.


b32(Posted 2007) [#4]
Well, I found the command by typing something like "capslock status api" in Google. Usually, I look for some VB code, because it is not too difficult to translate it.


_33(Posted 2007) [#5]
What's incredibly annoying thoe about keyboard management, is that, you encounter some problems like half managed schemes like for example, in Blitz3D, SHIFT is programmed in the GetKey(), but it doesn't consider CAPSLOCK. So, I have to worry if SHIFT is also active while CAPSLOCK is on. And usually, when you release SHIFT, CAPSLOCK turns off ;) . So, I'll have to find a way to set the status of CAPSLOCK. or I could simulate SHIFTED characters when the CAPSLOCK is on.....

See how painful?


b32(Posted 2007) [#6]
Hmm .. that does seem complicated. Here is an example of toggling the caps etc.:



_33(Posted 2007) [#7]
Even thoe the status of the shift or capslock is changed, doesn't mean that my input is shifted:
I'm trying to figure out something here, if this is because Blitz is handling the shift? This is too much, I'll have to rest... LOL!


b32(Posted 2007) [#8]
Actually, I don't know exactly why. However, you could use Upper$ and Lower$ to change the cast of the characters:



_33(Posted 2007) [#9]
Well, for now, this is how I shift keys when capslock is used:
      If term\key_typed > 0 Then
         If (api_GetKeyState(VK_CAPITAL) And $FFFF) = 1 Then
            If (KeyDown(KEY_LEFT_SHIFT) Or KeyDown(KEY_RIGHT_SHIFT)) = False Then
               If term\key_typed > 96 And term\key_typed < 123 Then
                  term\key_typed = term\key_typed - 32 ; switch to uppercase
               EndIf
            Else
               If term\key_typed > 64 And term\key_typed < 91 Then
                  term\key_typed = term\key_typed + 32 ; switch to lowercase
               EndIf
            EndIf
         EndIf
      EndIf
It only shifts letters, either upper to lower, or lower to upper, depending if shift is pressed or capslock is on. It works fine, but only for characters. Normally, you'd expect this to also work (capslock) on the symbols over the numbers, but this technique doesn't. I would need to figure out what those codes should be, or work with a translation table of some kind, user32 (from MSDN documentation I suppose).

It's really weird that the numeric keypad doesn't work also. The - + * / stuff works, but the numbers won't, wether numlock is on or off, it just doesn't care in GetKey().

I'll use these for my numeric keypad needs:
Const VK_NUMPAD0 = $60
Const VK_NUMPAD1 = $61
Const VK_NUMPAD2 = $62
Const VK_NUMPAD3 = $63
Const VK_NUMPAD4 = $64
Const VK_NUMPAD5 = $65
Const VK_NUMPAD6 = $66
Const VK_NUMPAD7 = $67
Const VK_NUMPAD8 = $68
Const VK_NUMPAD9 = $69



b32(Posted 2007) [#10]
Maybe you can look up the uppercase/lowercase stuff in strings ?
A bit like this:
lowercase$ = "0123456789"
uppercase$ = "!'#$%^&*()"

i = instr(lowercase$, chr$(key))
if caps_is_on then 
    write mid$(uppercase$, i, 1)
else 
    write mid$(lowercase$, i, 1)
end if



_33(Posted 2007) [#11]
I don't use strings b32. Using a fixed table of characters is pointless as my system works for all keyboards, not just north americans. And Strings will just slow down my terminal to a crawl. I'm currently happy to state that the core of my terminal has absolutely no usage of $/string/char/asc/mid/left/right/str/instr/uppercase/lowercase .... which are all CPU hungry compared to simple data movements. Currently my terminal emulator works on all keyboards, and I want to keep it that way. And I want to keep the data shuffling as fast as possible. I have other things to worry about that takes a lot of CPU, so basically I'm saving for later.


_33(Posted 2007) [#12]
OK so here's how I handle both the capslock and the numlock feature. Here's from the type declaration:
   Field key_typed%
   Field key_numpad_code[10]
   Field key_numpad_down[10]
From my keyboard init routine, here's the portion that concerns the numeric keypad:
   term\key_numpad_code[0]       = KEY_NUMPAD0 ; 82
   term\key_numpad_code[1]       = KEY_NUMPAD1 ; 79
   term\key_numpad_code[2]       = KEY_NUMPAD2 ; 80
   term\key_numpad_code[3]       = KEY_NUMPAD3 ; 81 
   term\key_numpad_code[4]       = KEY_NUMPAD4 ; 75
   term\key_numpad_code[5]       = KEY_NUMPAD5 ; 76
   term\key_numpad_code[6]       = KEY_NUMPAD6 ; 77
   term\key_numpad_code[7]       = KEY_NUMPAD7 ; 71
   term\key_numpad_code[8]       = KEY_NUMPAD8 ; 72
   term\key_numpad_code[9]       = KEY_NUMPAD9 ; 73

   For numpad_id% = 0 To 9
      term\key_numpad_down[numpad_id] = False
   Next
And here's how I handle the thing:
      term\key_typed = GetKey()
      If term\key_typed > 0 Then
         If (api_GetKeyState(VK_CAPITAL) And $FFFF) = 1 Then
            If (KeyDown(KEY_LEFT_SHIFT) Or KeyDown(KEY_RIGHT_SHIFT)) = False Then
               If term\key_typed > 96 And term\key_typed < 123 Then
                  term\key_typed = term\key_typed - 32 ; switch to uppercase
               EndIf
            Else
               If term\key_typed > 64 And term\key_typed < 91 Then
                  term\key_typed = term\key_typed + 32 ; switch to lowercase
               EndIf
            EndIf
         EndIf
      Else
         If (api_GetKeyState(VK_NUMLOCK) And $ffff) = 1 Then
            For numpad_id% = 0 To 9
               If KeyDown(term\key_numpad_code[numpad_id]) Then
                  If term\key_numpad_down[numpad_id] = False Then 
                     term\key_numpad_down[numpad_id] = True
                     term\key_typed = numpad_id + 48
                  EndIf
               Else
                  term\key_numpad_down[numpad_id] = False
               EndIf
            Next
         EndIf
      EndIf
This is patchwork of course.