[mono-vb] Mono and .NET using Console.ReadKey()

Paebbels Paebbels at gmail.com
Wed Nov 19 16:48:07 EST 2008


Hi,

I programmed a console application in VB .NET with VS08 which uses
cmd-InputBuffer to display an history of old commands in my application.

After porting this application to Mono (Debian, v1.9.1) my application has
no history feature (my shell is bash).

Then I decided to uses Console.ReadKey() instead of ReadLine().
I usesd the Microsoft MSDN example to display the KeyChars, KeyCodes and
Modifiers

--------------------
[...]
Console.TreatControlCAsInput = True
            Console.WriteLine(m1)
            Do
                Console.WriteLine(m2)
                sb.Length = 0
                cki = Console.ReadKey(True)
                sb.Append(m3)
                If cki.Modifiers <> 0 Then
                    If (cki.Modifiers And ConsoleModifiers.Alt) <> 0 Then
                        sb.Append("ALT+")
                    End If
                    If (cki.Modifiers And ConsoleModifiers.Shift) <> 0 Then
                        sb.Append("SHIFT+")
                    End If
                    If (cki.Modifiers And ConsoleModifiers.Control) <> 0
Then
                        sb.Append("CTL+")
                    End If
                End If
                sb.Append(cki.Key.ToString())
                sb.AppendFormat(m4, cki.KeyChar,
Convert.ToInt32(cki.KeyChar))
                sb.AppendLine().AppendLine()
                Console.WriteLine(sb.ToString())
            Loop While cki.Key <> ConsoleKey.Escape
--------------------

My ConsoleExtended Class has a mask with all allowd keys assoziated with an
delegate e.g. AddCharToBuffer for normal alphanumeric-chars.


Compiled on Windows this application does what it should do ^^
After porting it to Mono some ConsoleKeyInfo-Instances have an abnormal
value ...

Enter returns ConsoleKey.Enter which has ASCII Char 13 on Windows, on Mono
it has 10 (I know the differnet behavior of \n und \r\n ....)
Home returns on Windows ConsoleKey.Home, on Mono ConsoleKey.Esc with ASCII
Char 27 (also: End, Delete)
Backspace returns on Windows ConsoleKey.Backspace ASCII Char 8, on Mono
ConsoleKey.Backspace with ASCII Char 0

After some experiments I noticed that Console.In has differnet Encodings.
After setting them to UTF-8 nothing changed. 


Why is there a differnet behavior?
What ConsoleKeyInfo-Values are used in Mono?
How to use spezial Keys like Home, End, Delete, Backspace, ...


Here are some code fragments:
--------------------------
        Public Sub New()
            With OutputBufferSize
                .Width = Console.BufferWidth
                .Height = Console.BufferHeight
            End With

            Dim DefaultMask As New Dictionary(Of ConsoleKeyInfo,
InputAction)
            KeyMasks.Add(DefaultMaskName, DefaultMask)
            CurrentKeyMask = DefaultMask

            AddKeyToMask("rtn", DefaultMaskName, Function() False)
            AddKeyToMask("esc", DefaultMaskName, AddressOf ClearInputBuffer)
            AddKeyToMask("del", DefaultMaskName, AddressOf
DeleteAtInputBufferPos)
            AddKeyToMask("bsp", DefaultMaskName, AddressOf
DeleteBeforeInputBufferPos)
            AddKeyToMask("home", DefaultMaskName, AddressOf
InputBufferPosHome)
            AddKeyToMask("end", DefaultMaskName, AddressOf
InputBufferPosEnd)
            AddKeyToMask("left", DefaultMaskName, AddressOf
InputBufferPosLeft)
            AddKeyToMask("right", DefaultMaskName, AddressOf
InputBufferPosRight)
            AddKeyToMask("up", DefaultMaskName, AddressOf HistoryBack)
            AddKeyToMask("down", DefaultMaskName, AddressOf HistoryNext)
            AllowAlphaNumForMask(DefaultMaskName)
            AllowSpezialCharsForMask(DefaultMaskName)

        End Sub


        Public Sub AddKeyToMask(ByVal KeyName As String, ByVal MaskName As
String, ByVal KeyAction As Action)
            If KeyMasks.ContainsKey(MaskName) Then
                Select Case KeyName
                    Case "a"
                        KeyMasks(MaskName).Add(New ConsoleKeyInfo("a"c,
ConsoleKey.A, False, False, False), New InputAction With {.DisplayChar =
"a", .BufferChar = "a", .Action = KeyAction})
                    Case "b"
                        KeyMasks(MaskName).Add(New ConsoleKeyInfo("b"c,
ConsoleKey.B, False, False, False), New InputAction With {.DisplayChar =
"b", .BufferChar = "b", .Action = KeyAction})
                    Case "c"
                        KeyMasks(MaskName).Add(New ConsoleKeyInfo("c"c,
ConsoleKey.C, False, False, False), New InputAction With {.DisplayChar =
"c", .BufferChar = "c", .Action = KeyAction})
[...]
Case "rtn"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(13), ConsoleKey.Enter, False, False, False),
New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case "esc"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(27), ConsoleKey.Escape, False, False, False),
New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case "del"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(0), ConsoleKey.Delete, False, False, False),
New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case "bsp"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(8), ConsoleKey.Backspace, False, False,
False), New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case "home"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(0), ConsoleKey.Home, False, False, False), New
InputAction With {.DisplayChar = "", .BufferChar = "", .Action = KeyAction})
                    Case "end"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(0), ConsoleKey.End, False, False, False), New
InputAction With {.DisplayChar = "", .BufferChar = "", .Action = KeyAction})
                    Case "left"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(0), ConsoleKey.LeftArrow, False, False,
False), New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case "right"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(0), ConsoleKey.RightArrow, False, False,
False), New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case "up"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(0), ConsoleKey.UpArrow, False, False, False),
New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case "down"
                        KeyMasks(MaskName).Add(New
ConsoleKeyInfo(Convert.ToChar(0), ConsoleKey.DownArrow, False, False,
False), New InputAction With {.DisplayChar = "", .BufferChar = "", .Action =
KeyAction})
                    Case Else
                        Throw New Exception("Unknown Key")
                End Select
            End If
        End Sub


        Public Sub AllowLowerAlphaForMask(ByVal MaskName)
            If KeyMasks.ContainsKey(MaskName) Then
                For Each LowerAlpha As String In
"abcdefghijklmnopqrstuvwxyz"
                    AddKeyToMask(LowerAlpha, MaskName, AddressOf
AddToInputBuffer)
                Next
            End If
        End Sub


        Private Function AddToInputBuffer(ByVal Key As ConsoleKeyInfo, ByVal
InputAction As InputAction) As Boolean
            If InputBufferPos = InputBuffer.Length Then
                InputBuffer &= InputAction.BufferChar
                InputBufferPos += 1

                Console.Write(InputAction.DisplayChar)
                OutputBufferPos.Left += 1
            ElseIf InputBufferPos < InputBuffer.Length Then
                InputBuffer = InputBuffer.Insert(InputBufferPos,
InputAction.BufferChar)
                InputBufferPos += 1

                Console.Write(InputAction.DisplayChar)
                OutputBufferPos.Left += 1
                Console.Write(InputBuffer.Substring(InputBufferPos,
InputBuffer.Length - InputBufferPos))
                Console.CursorLeft = OutputBufferPos.Left
            Else
                Throw New OverflowException("BufferPos behind last Buffer
element.")
            End If

            Return True
        End Function


        Public Function ReadExended() As String
            InputBuffer = ""
            InputBufferPos = 0

            With OutputBufferPos
                .Left = Console.CursorLeft
                .Top = Console.CursorTop
            End With

            ReadLineRootPoint = OutputBufferPos

            While (True)
                Dim Key As ConsoleKeyInfo = Console.ReadKey(True)

                Try
                    Dim IA As InputAction = CurrentKeyMask(Key)
                    Dim IAR As Boolean = IA.Action.Invoke(Key, IA)

                    If IAR = False Then Exit While
                Catch ex As Exception
                    Console.WriteLine()
                    Console.WriteLine("nicht gefunden - {0}", ex.ToString())
                    Console.WriteLine("Key: {0}, KeyChar: {1}, KeyCharCHR:
{2}, Modifier: {3}", Key.Key.ToString(), Key.KeyChar.ToString(),
Convert.ToInt32(Key.KeyChar).ToString(), Key.Modifiers.ToString())
                End Try
            End While

            If _EnableHistory = True Then
                InputBufferHistory.Enqueue(InputBuffer)
            End If

            Return InputBuffer
        End Function

http://www.nabble.com/file/p20589984/ExtendedConsole.vb ExtendedConsole.vb 
-- 
View this message in context: http://www.nabble.com/Mono-and-.NET-using-Console.ReadKey%28%29-tp20589984p20589984.html
Sent from the Mono - VB mailing list archive at Nabble.com.



More information about the Mono-vb mailing list