Code: Select all
KeyCode% = CVI(Inkey$ + Chr$(0) + Chr$(0))
For example, instead of
Code: Select all
k$ = Inkey$
If k$ = Chr$(0) + "M" Then
Print "Right Arrow Presed"
End If
Code: Select all
Const ESCAPE = 27
Const LEFTARROW = &H4B00
Const RIGHTARROW = &H4D00
Do
KeyCode% = CVI(Inkey$ + Chr$(0) + Chr$(0))
Select Case KeyCode%
Case ESCAPE
Exit Do
Case LEFTARROW
Print "Left Arrow Pressed"
Case RIGHTARROW
Print "Right Arrow Pressed"
Case 32 to 127
Print "'" + Chr$(KeyCode%) + "' Presed"
Case <> 0
Print "Other Key Pressed : "; Str$(KeyCode%)
End Select
Loop
End
Before we figure out why this won't work in FB, let's look at CHR$(0)
EDIT: The behaviour described here regarding Print and chr$(0) has been fixed in fbc 0.15b win32 and you can skip this section if you like.
OLD_STUFF
Even though the FB docs and many posts state that FB does not allow null terminators (CHR$(0)) in strings, this would seem only partially correct. If we try:
Code: Select all
a = "ABCD" + Chr$(0) + "EFGH"
Print a
Now if we actually look at what's in the string variable a, we will see *all* the bytes:
Code: Select all
For i = 1 to Len(a)
Print Asc(Mid$(a, i, 1))
Next i
END OLD_STUFF
So why doesn't our KeyCode% expression work in FB?
First thing is that Inkey$ returns a Chr$(255) for the extended character in FB instead of a Chr$(0) as in QB. We can fix this problem by changing our constants.
Code: Select all
Const ESCAPE = 27
Const LEFTARROW = &H4BFF
Const RIGHTARROW = &H4DFF
We can fix that problem in FB with:
Code: Select all
Dim KeyCode as Integer
KeyCode = CVI(Left$(Inkey$ + Chr$(0) + Chr$(0) + Chr$(0) + Chr$(0), 4)
Processor Compatibility
But wait, if we read the docs, we will see that CVI() should only be used with strings returned from MKI$(). CVI() and MKS$() will return different results depending on the endianness of our processor. The above code will work fine on little endian (intel type) processors but will not on big endian processors. (looking at the hCV() and fb_CVI() functions in libfb_str_cvmk.c of the run-time library confirm this behaviour)
Now, I could just quit here and say, well it works on my system, so to heck with anyone not using intel type processors. But that would not be a Good thing.
Actually, the fix is quite simple:
Code: Select all
Dim KeyCode as Integer, k as String
k = Inkey$
KeyCode = (ASC(k,2) shl 8) + ASC(k,1)
Code: Select all
Declare Function GetKeyCode () As Integer
Const ESCAPE = 27
Const LEFTARROW = &H4BFF
Const RIGHTARROW = &H4DFF
Dim KeyCode AS INTEGER
Do
KeyCode = GetKeyCode()
Select Case KeyCode
Case ESCAPE
EXIT DO
Case LEFTARROW
PRINT "Left Arrow Pressed"
Case RIGHTARROW
PRINT "Right Arrow Pressed"
Case 32 TO 127
PRINT "'" + CHR$(KeyCode) + "' Presed"
Case IS <> 0
Print "Other Key Pressed : "; STR$(KeyCode); " = &H"; Hex$(KeyCode)
End Select
Loop
End
Function GetKeyCode () As Integer
Dim k AS String
k = InKey$
GetKeyCode = (Asc(k, 2) Shl 8) + Asc(k, 1)
End Function
So if we used the CVI(Inkey$...) trick in our old QB code, we can fairly easily move the code to our new FB code. The only draw back is that our new function is not compatible with QB. Personally, I think this is reasonable considering that most likely there are lots of other things I am going to have in my FB code that won't run in QB.
FB/QB Compatibility
Now, if we really wanted to, we could write the GetKeyCode() function so that it is compatible in both FB and QB *and* still be processor indenpendant. But we have to sacrifice some performance. We will keep the new 'FB style' keycode constants and only change the function. The compatible but slower GetKeyCode function would be as follows:
Code: Select all
Function GetKeyCode%
Dim k AS String, n as Integer, ch as Integer
k = InKey$
n = len(k)
Select Case n
Case 1
GetKeyCode% = Asc(k)
Case 2
ch = Asc(Mid$(k, 2, 1))
If ch > 127 Then
GetKeyCode% = ((ch And &h7f) * 256) Or &H80FF
Else
GetKeyCode% = (ch * 256) Or &HFF
End If
Case Else
GetKeyCode% = 0
End Select
End Function
And finally ...
If you need to check key states there's MutliKey(). There are also other key getting routines in various libraries which may be suited to your purpose.
Like with most problems there are usually several solutions. I think the CVI(Inkey$...) method I used with QB is still a good method in FB even though a few changes are needed.
Jeff Marshall