[Mono-list] Console.ReadKey() => no spezial chars on Linux

Paebbels Paebbels at gmail.com
Mon Feb 16 16:33:25 EST 2009


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 allowed 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. 
Then I changed encoding to UTF-8, but nothing happend. 


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/p22011524/ExtendedConsole.vb ExtendedConsole.vb 
-- 
View this message in context: http://www.nabble.com/Console.ReadKey%28%29-%3D%3E-no-spezial-chars-on-Linux-tp22011524p22011524.html
Sent from the Mono - General mailing list archive at Nabble.com.



More information about the Mono-list mailing list