Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Chr$(135) and _Keyhit
#1
Hey guys,

Working up a demo for @bplus while adding to my mouse/keyboard routine. I was also converting it from INKEY$ to _Keyhit when I noticed something I did not expect. When a key like Shift, Alt, or Ctrl is pressed the conversion to b$ becomes Chr$(0) + Chr$(135) in all cases. 

See the line that corrects this for my routine that simply catches it and makes b$ = "". Look for ' <----------------------------------

Code: (Select All)
ReDim Shared y_btl(2), y_bbr(2), x_btl(2), x_bbr(2), button$(2)
nob = 2
Color 15, 1
If mapping = 0 Then
    Locate 10, 50: y_btl(1) = CsrLin: x_btl(1) = Pos(0): Print Chr$(218) + String$(10, 196) + Chr$(191)
    Locate 11, 50: Print Chr$(179);: Locate , Pos(0) + 10: Print Chr$(179);
    Locate 12, 50: Print Chr$(192) + String$(10, 196) + Chr$(217);: y_bbr(1) = CsrLin: x_bbr(1) = Pos(0) - 1
    button$(1) = " Button 1 "
    Locate 11, 51: Print " Button 1 ";

    Locate 10, 65: y_btl(2) = CsrLin: x_btl(2) = Pos(0): Print Chr$(218) + String$(10, 196) + Chr$(191)
    Locate 11, 65: Print Chr$(179);: Locate , Pos(0) + 10: Print Chr$(179);
    Locate 12, 65: Print Chr$(192) + String$(10, 196) + Chr$(217);: y_bbr(2) = CsrLin: x_bbr(2) = Pos(0) - 1
    button$(2) = " Button 2 "
    Locate 11, 66: Print " Button 2 ";
Else
    Locate 10, 50: Print Chr$(218) + String$(10, 196) + Chr$(191)
    Locate 11, 50: Print Chr$(179);: Locate , Pos(0) + 10: Print Chr$(179);
    button$(1) = " Button 1 "
    Locate 12, 50: Print Chr$(192) + String$(10, 196) + Chr$(217)
    Locate 11, 51: Print " Button 1 ";

    Locate 10, 65: Print Chr$(218) + String$(10, 196) + Chr$(191)
    Locate 11, 65: Print Chr$(179);: Locate , Pos(0) + 10: Print Chr$(179);
    Locate 12, 65: Print Chr$(192) + String$(10, 196) + Chr$(217)
    button$(2) = " Button 2 "
    Locate 11, 66: Print " Button 2 ";
End If
PCopy 0, 1
Color 7, 0
Locate 1, 1
Do
    MyMouse_and_Keyboard lb, mb, rb, my, mx, mw, shift%, alt, AltToggle, alt%, ctrl%, clkcnt, drag, k&, b$, autokey$, nob, button$()

    If drag Then
        If olddrag <> drag Then
            If drag > 0 Then Print "Drag Right. Status ="; Else Print "Drag Left. Status = ";
            Print drag
            olddrag = drag
        End If
    Else
        olddrag = 0
    End If
    If oldlb <> lb Then
        Select Case lb
            Case 0: Print "Left Button Up - Button Status ="; lb
            Case -1: Print "Left Button Down - Button Status = "; lb
            Case 1: Print "Left Button Pressed - Button Status ="; lb
            Case 2: Print "Left Button Released - Button Status ="; lb
        End Select
        If lb = 0 Then Print "Number of clicks ="; clkcnt
    End If
    If oldmb <> mb Then
        Select Case mb
            Case 0: Print "Middle Button Up - Button Status ="; mb
            Case -1: Print "Middle Button Down - Button Status = "; mb
            Case 1: Print "Middle Button Pressed - Button Status ="; mb
            Case 2: Print "Middle Button Released - Button Status ="; mb
        End Select
    End If
    If oldrb <> rb Then
        Select Case rb
            Case 0: Print "Right Button Up - Button Status ="; rb
            Case -1: Print "Right Button Down - Button Status = "; rb
            Case 1: Print "Right Button Pressed - Button Status ="; rb
            Case 2: Print "Right Button Released - Button Status ="; rb
        End Select
    End If
    If oldmw <> mw Then
        If mw < 0 Then Print "Mouse Wheel Up - Wheel Status ="; mw
        If mw > 0 Then Print "Mouse Wheel Down - Wheel Status ="; mw
    End If
    If oldalt% <> alt% Then
        If alt% < 0 Then Print "Alt Button Down" Else Print "Alt Button Released"
    End If
    If oldctrl% <> ctrl% Then
        If ctrl% < 0 Then Print "Ctrl Button Down" Else Print "Ctrl Button Released"
    End If
    If oldshift% <> shift% Then
        If shift% < 0 Then Print "Shift Button Down" Else Print "Shift Button Released"
    End If
    If oldalt <> alt And alt < 0 Then
        Print "Alt Key Pressed";
        If AltToggle Then Print " / Alt Toggle Status: On" Else Print " / Alt Toggle Status: Off"
    End If
    If k& < 0 Then oldb$ = ""
    Select Case Len(b$)
        Case 1
            If oldb$ <> b$ Then Print "You Pressed: ";: x = CVI(MKI$(Asc(b$))): Print Chr$(x); "  Chr$(" + LTrim$(Str$(x)) + ")"
            oldb$ = b$
        Case 2
            If oldb$ <> b$ Then Print "You Pressed: "; "nul + " + LTrim$(Str$(Asc(Mid$(b$, 2, 1)))) + "  Chr$(0) + " + Chr$(34) + Mid$(b$, 2, 1) + Chr$(34)
            oldb$ = b$
    End Select

    oldlb = lb: oldrb = rb: oldmb = mb: oldmw = mw: oldalt% = alt%: oldctrl% = ctrl%: oldshift% = shift%: oldalt = alt
    If CsrLin > _Height - 2 Then Cls: PCopy 1, 0
Loop

Sub MyMouse_and_Keyboard (lb, mb, rb, my, mx, mw, shift%, alt, AltToggle, alt%, ctrl%, clkcnt, drag, k&, b$, autokey$, nob, button$())
    Dim As Integer b_hover, i, oldmw
    Static As Integer oldmy, oldmx, hover, mwy, oldmwy, b_active
    Static z1 As Single
    _Limit 60
    If alt Then alt = 0
    If Len(autokey$) Then
        b$ = Mid$(autokey$, 1, InStr(autokey$ + ",", ",") - 1)
        autokey$ = Mid$(autokey$, InStr(autokey$ + ",", ",") + 1)
        Exit Sub
    Else
        k& = _KeyHit
        If k& = 100307 Or k& = 100308 Then
            alt = -1
            AltToggle = 1 - AltToggle
            Exit Sub
        End If
        If k& > 0 Then
            b$ = MKI$(k&)
            If Mid$(b$, 2, 1) = Chr$(135) Then b$ = "" ' <------------------------------------- Keys like Shift, Alt, and Ctrl create this same value.
            If Right$(b$, 1) = Chr$(0) Then b$ = Left$(b$, 1)
        Else
            b$ = ""
        End If
    End If
    If z1 Then If Abs(Timer - z1) > .25 Then z1 = 0: clkcnt = 0
    If lb > 0 Then
        If lb = 1 Then
            lb = -1
        Else
            lb = 0
        End If
    End If
    If rb > 0 Then If rb = 1 Then rb = -1 Else rb = 0
    If mb > 0 Then If mb = 1 Then mb = -1 Else mb = 0
    While _MouseInput
        mwy = mwy + _MouseWheel
    Wend
    my = _MouseY
    mx = _MouseX
    b_hover = 0
    For i = 1 To nob ' number of buttons.
        If my >= y_btl(i) And my <= y_bbr(i) And mx >= x_btl(i) And mx <= x_bbr(i) Then
            b_hover = i
            Exit For
        End If
    Next
    If lb = -1 Then
        If oldmy And oldmx <> mx Or oldmy And oldmy <> my Then
            If mx <> oldmx Then drag = Sgn(mx - oldmx) ' Prevent zero which can occur if mouse moves off row when being dragged horizontally.
        End If
    End If
    If drag = 0 Then
        If mwy <> oldmw Then
            mw = Sgn(mwy - oldmwy): mwy = 0
        Else
            mw = 0
        End If
        oldmwy = mwy
        If _KeyDown(100303) Or _KeyDown(100304) Then shift% = -1 Else If shift% Then shift% = 0
        If _KeyDown(100305) Or _KeyDown(100306) Then ctrl% = -1 Else If ctrl% Then ctrl% = 0
        If _KeyDown(100307) Or _KeyDown(100308) Then alt% = -1 Else If alt% Then alt% = 0
    End If
    If lb = -1 And _MouseButton(1) = 0 Then
        lb = 2: drag = 0: hover = 0
    ElseIf rb = -1 And _MouseButton(2) = 0 Then
        rb = 2
    ElseIf mb = -1 And _MouseButton(3) = 0 Then
        mb = 2
    End If
    If _MouseButton(1) Then
        If lb = 0 Then
            lb = 1: z1 = Timer
            clkcnt = clkcnt + 1
        End If
    ElseIf _MouseButton(2) And rb = 0 Then
        rb = 1
    ElseIf _MouseButton(3) And mb = 0 Then
        mb = 1
    End If
    If b_active Then
        If b_hover Then
            If lb = 2 Then Sound 1000, 1
        Else
            s1 = CsrLin: s2 = Pos(0)
            c1 = _DefaultColor: c2 = _BackgroundColor
            Color 15, 1
            Locate y_btl(b_active), x_btl(b_active): Print Chr$(218) + String$(10, 196) + Chr$(191)
            Locate , x_btl(b_active): Print Chr$(179);: Locate , Pos(0) + 10: Print Chr$(179)
            Locate , x_btl(b_active): Print Chr$(192) + String$(10, 196) + Chr$(217);
            Locate y_btl(b_active) + 1, x_btl(b_active) + 1: Print button$(b_active);
            Color c1, c2
            Locate s1, s2
            b_active = 0
        End If
    Else
        If b_hover And oldmy <> 0 Then
            If b_active = 0 Then
                s1 = CsrLin: s2 = Pos(0)
                c1 = _DefaultColor: c2 = _BackgroundColor
                Color 1, 3
                Locate y_btl(b_hover), x_btl(b_hover): Print Chr$(218) + String$(10, 196) + Chr$(191)
                Locate , x_btl(b_hover): Print Chr$(179);: Locate , Pos(0) + 10: Print Chr$(179)
                Locate , x_btl(b_hover): Print Chr$(192) + String$(10, 196) + Chr$(217);
                Locate y_btl(b_hover) + 1, x_btl(b_hover) + 1: Print button$(b_hover);
                Color c1, c2
                Locate s1, s2
                b_active = b_hover
            End If
        End If
    End If
    oldmy = my: oldmx = mx
End Sub

So I'm mostly just curious to learn why the different values for k& representing keys like Shift, Ctrl, and Alt (10034, 10036, 10038) respectively, all get converted to Chr$(0) + Chr$(135) with MKI$().

Thanks,

Pete
Reply
#2
I think if you check the other byte you'll find it's not actually `CHR$(0)`. Unlike with the arrow keys and such, where they produce `CHR$(0) + CHR(x)`, the modifiers are mapped in the 10030X range so they'll all have the top byte be the same 135 and the bottom byte be the one that changes. 100304 turns into `CHR$(208) + CHR$(135)`.

Part of the issue is that INKEY$ did not return the state of the modifier keys, so there's no corresponding INKEY$ value (hence why the values 10030X, larger than an INTEGER and past the range that INKEY$ returns). If you want to make an INKEY$ replacement you're probably best just ignoring the modifier keys, as you don't need them anyway (`_KEYHIT` already returns values with the modifiers applied. Ex. 'A' vs. 'a'). If you do want to keep them then you'll have to consider whether you want to return the actual 4-byte value or have some kind of weird aliasing with the 2-byte key values (though I don't think `CHR$(208) + CHR$(135)` is a value INKEY$ could ever return anyway, so maybe it's not a real issue).
Reply
#3
Doesn't INKEY$ stop reporting values above 127?  ANSI input ranges?

Or am I wrong on that?  I'll have to test it later.



Testing and reading the docs, it's seems I'm right and wrong both. Tongue

INKEY$ only uses values below 128 for the first byte, but for 2-byte combos, it uses the whole ASCII range. F12 for example is CHR$(0) + CHR$(137).
Reply
#4
(Today, 07:59 AM)Pete Wrote: So I'm mostly just curious to learn why the different values for k& representing keys like Shift, Ctrl, and Alt (10034, 10036, 10038) respectively, all get converted to Chr$(0) + Chr$(135) with MKI$().

Thanks,

Pete

The simple answer here, I think, is overflow values.

INTEGER can only hold values up to 5 digits.   _KEYHIT returns 6-digit numbers.  You're going to overflow the bucket ya trying to cram yo numbers into, like that par'ner!
Reply




Users browsing this thread: 1 Guest(s)