Everyday, almost, I use three different shells, Command Prompt, PowerShell, and Bash for Git. I think the interface of those shells has lots to improve. As I am spoiled by good editors like Visual Studio, TextMate, Sublime, Notepad+, (but no Vim yet), I expected the similar level of maturity and convenience.
Console+ is on github now. Please bear in mind, it is code in progress.
So, I wanted to build an interface to them. I’m not building any shell. I’m going to build just an interface. And in this journey, I start learning a few tips with WPF. A geeky joy, as Kent Beck confesses in his book, “TDD By Example”.
Resources I used
As this is a WPF application with Win API calls, I don’t have enough knowledge or experience. I am more focust on Web development (thought I don’t like being labelled as mere web developer as some windows devs believe wrongly web development is child’s play)
So, I google a lot to understand how it can possibly work. This is the list of my resources.
Adding an icon to your application
I thought I would simply put Icon=”/Resource/Icon.ico”, but it wasn’t. You have to open the property dialog and set it there.
Handling RETURN and TAB on textbox
If “AcceptsReturn” and “AcceptsTab” are on, you can’t capture those key codes in the event. They are handled within the control, and the event is not escalated. So, turn them off.
Color coding in console
Colour is an attribute of the console, and you don’t get it from StandardOutput. You have to do something with windows api, and I’m not ready get my hands dirty with win api yet. I’ll depriortise this story 🙂
Initially, I used System.Timers.Timer to update the screen regularly, but it didn’t work. Timer runs in a separate thread, and can’t update UI thread. You get “The calling thread cannot access this object …” error. In this case, DispatcherTimer is handy, as Tick event is fired in the dispatcher thread.
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromMilliseconds(1000);
_timer.Tick += (o, args) =>
tbxConsole.Text = _console.ReadAll();
_timer.IsEnabled = true;
Sending key event to the console
I need to send user’s key input to “cmd.exe” process. In WPF key event, I get KeyEventArgs, but I need to convert it to a character, and it is not possible with the help of win api.
public class KeyHelper
public enum MapType : uint
MAPVK_VK_TO_VSC = 0x0,
MAPVK_VSC_TO_VK = 0x1,
MAPVK_VK_TO_CHAR = 0x2,
MAPVK_VSC_TO_VK_EX = 0x3,
public static extern int ToUnicode(
[Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)]
public static extern bool GetKeyboardState(byte lpKeyState);
public static extern uint MapVirtualKey(uint uCode, MapType uMapType);
public static char GetCharFromKey(Key key)
char ch = ' ';
int virtualKey = KeyInterop.VirtualKeyFromKey(key);
byte keyboardState = new byte;
uint scanCode = MapVirtualKey((uint)virtualKey, MapType.MAPVK_VK_TO_VSC);
var stringBuilder = new StringBuilder(2);
int result = ToUnicode((uint)virtualKey, scanCode, keyboardState, stringBuilder, stringBuilder.Capacity, 0);
ch = stringBuilder;
ch = stringBuilder;
Sometimes, not often, I want to return empty character in my method. String has string.empty, but until now, I ddin’t know that Char.MinValue exists. It’s really handly. Look at this code.
public char GetCharacterFrom(Key key)
if (key == Key.LeftShift)
if (key == Key.Return)
return (char) 13;
Avalon Text Editor
You can highlight the part of text with VisualLineElement. the Rendering article has more detailed description.
With StackOverflow’s avalonedit tag, you can read through useful tips
You can download the source code, a sample application, and help file from codeproject.
Changing text color in Avalon Text Editor
Changing color of text or highlighting text is quite tricky with Avalon Text Editor. Primarily it’s because Avalon is not RichTextEditor but code editor. Text are treated as string and you put meta data on those text if you want to change the format.
You need to create your own DocumentColorizingTransformer to highlight a part of your text, and then add it to your editor’s LineTransformers collection. I found an example of custom DocumentColorizingTransformer, bud spend some time to find out how to use it.
public void UpdateConsole()
tbxConsole.Document.Text = _console.ReadAll();
public class ColorizeAvalonEdit : DocumentColorizingTransformer
protected override void ColorizeLine(DocumentLine line)
if (line.Length == 0)
int lineStartOffset = line.Offset;
string text = CurrentContext.Document.GetText(line);
int start = 0;
while ((index = text.IndexOf("Microsoft", start)) >= 0)
lineStartOffset + index, // startOffset
lineStartOffset + index + 10, // endOffset
(VisualLineElement element) =>
// This lambda gets called once for every VisualLineElement
// between the specified offsets.
Typeface tf = element.TextRunProperties.Typeface;
// Replace the typeface with a modified version of
// the same typeface
start = index + 1; // search for next occurrence
to be continued…