Keyboard handling of held keys

Blitz3D Forums/Blitz3D Programming/Keyboard handling of held keys

_33(Posted 2007) [#1]
OK this will require a little reflection. I've been working on my terminal emulation for quite some time and am getting in the polishing phase. I've prepared code for handling key repeating if a key is held. But, here's the issue:

I get my keys from GetKey(). This works really well for 99.9% of my needs. But, as soon as I wanted to figure out if a key is held down, from the GetKey() back to a KeyDown(), I stumbled upon a big issue.

GetKey() returns ascii values and in that regards, it doesn't have any idea where the key is placed on the keyboard. On the other hand, KeyDown() is exactly the location of the key on the keyboard. As we all know, keyboards come in all shapes and form, from various countries around the world. A Russian, french, English, north american, etc. keyboard is all unique to each other, which GetKey() doesn't care about. Yet, when you want to code something about key auto repeat, you can't place the ascii code to the key instantly, as scancodes vary from each keyboard layout.

If anyone has answers as to how I could read the auto repeat from the keyboard controller, or if I could get that from a win api, that would be of great help!

Cheers.


jfk EO-11110(Posted 2007) [#2]
We recently discussed this here, try to seek "key repeat". I am using a key repeat emulation, based on millisecs, getkey and keydown, this works nicely. Haven't got the source on this machine, sorry.

Simplify the implemetation by wrapping the whole thing in a function like "myGetKey()" that will return ANY key, including keyrepeat, backspace, del etc. with their ascii values.


_33(Posted 2007) [#3]
We recently discussed this here


I doubt!

Is your suggestion good only for north american type keyboards, or is it also international? Are you sure you understand the issue I stated?

Z on QWERTY, QWERTZ and AZERTY are all different scancodes in a KeyDown(), for example.

http://www.microsoft.com/globaldev/reference/keyboards.mspx

I'll look into User32... Some people have found keyboard handling stuff in there.


Mr.Waterlily(Posted 2007) [#4]
The discussion we had about this is located here:

http://www.blitzbasic.com/Community/posts.php?topic=68624

There´s some code there I made with the tips I got from jfk EO-11110 for you to try out.


_33(Posted 2007) [#5]
Thanks! I haven't found that one from my search. I guess, I could support SOME keys at least.

Cheers.


SLotman(Posted 2007) [#6]
You would be better off using the getasynckeystate from windows api if you plan to use diferent keyboard layouts.

Just use the API call and the VK_ codes and it should work everywhere.


_33(Posted 2007) [#7]
\o/
Thanks!


_33(Posted 2007) [#8]
OK, got this sample code, should work on all keyboards around, some keys won't repeat, but they are not really useful to repeat.

Dim scancodes(256)
For i = 0 To 255
   scancodes(i) = api_OemKeyScan(i) And $ff
Next
repeat_delay = 500
repeat_rate = 100
Print "TYPE HERE:"
While Not KeyDown(1)
   timer = MilliSecs()
   ascii% = GetKey()
   If ascii > 0 Then
      ascii_repeat = ascii
      scancode% = scancodes(ascii)
      repeat_timer = timer + repeat_delay
      Write Chr$(ascii)
   EndIf
   If KeyDown(scancode) = True Then
      If timer >= repeat_timer Then
         Write Chr$(ascii_repeat)
         repeat_timer = timer + repeat_rate
      EndIf
   Else
      scancode = 0
   EndIf
Wend


Just make sure you have api_OemKeyScan in your DECLS (user32.DLL)


jfk EO-11110(Posted 2007) [#9]
Hey _33, thanks for that. Can you give me the decls line too (parameters etc.)?
How doesn it work, will this return any keyhits, or only the keyhits when your blitz app has focus?

The solution I suggested and Mr.Waterlily worked out is of course only a hack to make something useful out of the really limited GetKey and Keydown (although it supports country keys!), but at least this works with older versions of Blitz3D too.


_33(Posted 2007) [#10]
Make sure this is in user32.DECLS :
api_OemKeyScan% (wOemChar%) : "OemKeyScan" 


It returns the scancode from an ascii code corresponding to the application that is running, and it is based on the windows system that determined the keyboard layout in the first place, and it is specially for the applic ation running (from my understanding of the MSDN info). So it is as reliable as windows, in a way. LOL!

But this code should work on all Blitz3D versions, and OemKeyScan should be in all versions of windows from Win95 and up (I hope). I'm taking a slight chance thoe, but I have a good feeling on this.

The worst that could happen IMHO is that the key won't repeat. What I noticed, is that most keys that won't repeat are keys that are of character code greater than 127, such as éèä£ù³ÌýÃæ×® ... I don't think I can do anything about that, and I don't think it really is a big issue.