Ctrl-(Shift-)Tab

General FreeBASIC programming questions.
Jawade
Posts: 173
Joined: Apr 25, 2008 19:13

Ctrl-(Shift-)Tab

Postby Jawade » Aug 28, 2017 19:19

I found a way to use the key-combi Ctrl-(Shift-)Tab. It has not a repeatfunction. My question is: Is there a better way to use Ctrl-(Shift-)Tab?

Code: Select all

#include "windows.bi"
Dim a As Integer
Dim i As Integer
Dim aa As String
Dim t(7) As String


Main:
  ScreenRes 640, 480, 32: Width 80, 30
  Color 0, -1: Cls
  t(0) = " File    "
  t(1) = " Edit    "
  t(2) = " Memory  "
  t(3) = " Backup  "
  t(4) = " Vieuws  "
  t(5) = "Settings "
  t(6) = " About   "
  t(7) = " Help    "
  Line (0, 0) - (639, 0), 0
  For a = 80 To 639 Step 80
    Line (a, 0) - (a, 32), 0
  Next
  Do
    Color &hBABABA, -1
    For a = 0 To 7
      Locate 2, 2 + 10 * a: Print t(a)
    Next
    Color 0, -1
    Line (0, 32) - (639, 32), 0
    Locate 2, 2 + 10 * i: Print t(i):
    Locate 3, 1 + 10 * i: Print "          "
    Do: Sleep 3: Loop Until (GetKeyState(VK_TAB) And 128) = 0
    Do: aa = InKey$: Sleep 3: Loop Until _
        (GetKeyState(VK_TAB) And 128) Or aa <> ""
    If (GetKeyState(VK_CONTROL) And 128) Then
      If (GetKeyState(VK_TAB) And 128) Then
        If (GetKeyState(VK_SHIFT) And 128) = 0 Then
          i = i + 1: If i = 8 Then i = 0
        End If
      End If
    End If
    If (GetKeyState(VK_CONTROL) And 128) Then
      If (GetKeyState(VK_TAB) And 128) Then
        If (GetKeyState(VK_SHIFT) And 128) Then
          i = i - 1: If i < 0 Then i = 7
        End If
      End If
    End If
  Loop Until aa = Chr$(27)
System
xlucas
Posts: 227
Joined: May 09, 2014 21:19
Location: Argentina

Re: Ctrl-(Shift-)Tab

Postby xlucas » Sep 01, 2017 0:33

There sure is a better way. Your code is Windows-specific. You can make it multi-platform by using MultiKey instead of GetKeyState. I can also show you how to detect repetition like you would with other keys.

First, what you must do is check what InKey will give you when you use this combination. I think for Windows, it will give you Chr(255, 15), which is the same as for Shift+Tab (without the Ctrl key). You will probably get the same result for DOS, although for GNU/Linux, I guess you'd be getting Chr(9) (same as for Tab alone).

With this in mind, what we'll do is first detect these combinations with InKey, like you would normally do, and then use MultiKey to make sure it's the full combination, like this:

Code: Select all

'This included file will give you access to scan-code constants to use with MultiKey
#include "fbgfx.bi"
#if __FB_LANG__ = "fb"
Using FB  'Scan code constants are stored in the FB namespace in lang FB
#endif

'Our key string variable
Dim mykey As String

'Set resolution, same you used for your program. Notice that MultiKey won't work in console mode
'You HAVE to set up a graphics mode.
ScreenRes 640, 480, 32
Width 80, 30

'Our loop with key checking
Do
    mykey = InKey
    Select Case mykey
        Case Chr(27)    'ESC - Exit
            Exit Do
        Case Chr(9), Chr(255, 15)   'Detect both Tab and Shift+Tab and their combinations with Ctrl
            If MultiKey(SC_CONTROL) And (MultiKey(SC_LSHIFT) Or MultiKey(SC_RSHIFT)) Then
                'Do here whatever Ctrl+Shift+Tab is supposed to do
            ElseIf MultiKey(SC_CONTROL) Then
                'This is for Ctrl+Tab
            ElseIf MultiKey(SC_LSHIFT) Or MultiKey(SC_RSHIFT) Then
                'This is for Shift+Tab
            Else
                'This is for Tab
            End If
    End Select
Loop


Hope you find it useful... and that I haven't made any mistake. Even if I did, it should illustrate the idea! :)
Jawade
Posts: 173
Joined: Apr 25, 2008 19:13

Re: Ctrl-(Shift-)Tab

Postby Jawade » Sep 01, 2017 16:38

Thanks, but the trl-(Shift-)Tab don't work. Tab works, and Shift-Tab works double.
I work with FreeBASIC-1.05.0-win32 and Windows10. I have tried some things, but
it won't do the right things.
xlucas
Posts: 227
Joined: May 09, 2014 21:19
Location: Argentina

Re: Ctrl-(Shift-)Tab

Postby xlucas » Sep 01, 2017 22:46

Uhm... I've tested it and I see what's happening. Ctrl does not change the value in InKey, so it works, but the Shift+Tab combination (which traditionally in QB returned Chr$(0) + Chr(15) and in FB should return Chr(255, 15)) is not returning anything with InKey.

This is an error in InKey, which already has many errors (many combinations do return the correct values in DOS and Windows, but not in Linux). I can think of two ways around it. One would be to also use MultiKey to detect the Tab key itself, which is easier and akin to what you did in your program, but, just like what you did, will not allow you to detect repetition or keyboard latency. The other possibility is to use Windows' system-specific keyboard buffering system (which I don't know how to use; I am a Linux user and in Linux, this can be done with XLib. I'm sure there's something of the kind in Windows).

To do it with MultiKey (and no InKey), you'll do the following:

Code: Select all

Do
    mykey = InKey
    Select Case mykey
        Case Chr(27) : Exit Do
        Case Chr(9)
            If MultiKey(SC_CONTROL) Then
                'Ctrl+Tab was pressed, repetition and latency considered
            Else
                'Tab was pressed, repetition and latency considered
            End If
        Case ""
                If MultiKey(SC_TAB) Then
                    If MultiKey(SC_LSHIFT) Or MultiKey(SC_RSHIFT) Then
                        If MultiKey(SC_CONTROL) Then
                            'Ctrl+Shift+Tab is being pressed
                        Else
                            'Shift+Tab is being pressed
                        End If
                    Else
                        'These are already detected with InKey
                    End If
                End If
    End Select
Loop
Jawade
Posts: 173
Joined: Apr 25, 2008 19:13

Re: Ctrl-(Shift-)Tab

Postby Jawade » Sep 02, 2017 20:16

Thanks, but no, it won't work. Some gives a fast repeat, others don't do work.
I think, we are looking to the wrong way. I've made the autorepeat by my shelf,
and it works fine:

Code: Select all

Dim a As Integer
Dim aa As String


Main:
  ScreenRes 640, 480, 32: Width 80, 30
  Do
    aa = InKey$
    If MultiKey(15) = 0 Then a = 0
    If MultiKey(15) And MultiKey(29) And MultiKey(42) = 0 Then
      Print "Ctrl Tab"
      If a = 400 Then a = 30
      If a = 0 Then a = 400
      Sleep a
    End If
    If MultiKey(15) And MultiKey(29) And MultiKey(42) Then
      Print "Ctrl Shift Tab"
      If a = 400 Then a = 30
      If a = 0 Then a = 400
      Sleep a
    End If
  Loop Until aa = Chr$(27) Or MultiKey(1)
End

Return to “General”

Who is online

Users browsing this forum: No registered users and 2 guests