How should I create a custom graphical console/terminal on Windows? How should I create a custom graphical console/terminal on Windows? windows windows

How should I create a custom graphical console/terminal on Windows?


I once implemented a text output window from scratch - I wanted one that works like the Output window in Visual Studio. It turned out to be more complicated than I expected, and that was without any input capabilities.

Unfortunately the code is in C++ and belongs to a former employer, so I can't share it with you. But I can give you an idea of what to expect.

You need a way to store the lines of output that you can index quickly. If you're going to place a limit on the number of lines displayed it will also need to be easy to erase lines from the top. In C++ a deque<string> was perfect, I don't know what the equivalent is (if any) in C#.

You'll need handlers for the following Windows messages, in no particular order.

  • WM_LBUTTONDOWN - to start a selection. Use SetCapture to track the mouse while the button is down.
  • WM_LBUTTONUP - to end a selection.
  • WM_RBUTTONUP - translate into WM_CONTEXTMENU.
  • WM_CONTEXTMENU - to display a menu with Copy/Cut/Paste and whatever else you want.
  • WM_KEYDOWN - to respond to the 4 cursor keys, Home/End, PageUp/PageDown. Ctrl-A/Ctrl-C/Ctrl-X/Ctrl-V/Ctrl-D.
  • WM_PAINT - to paint the contents of the window.
  • WM_SIZE - to update the scrollbars when the window size changes.
  • WM_VSCROLL - to update the visible portion of the window during vertical scrolling.
  • WM_HSCROLL - to update the visible portion of the window during horizontal scrolling.
  • WM_CREATE - for initialization when the window is created.
  • WM_SETFOCUS - to create a system caret to show the current position in the window.
  • WM_KILLFOCUS - to kill the caret since only the currently focused window should show a caret.
  • WM_MOUSEMOVE - to track changes to the selection while the left mouse button is down.
  • WM_CAPTURECHANGED - to end a selection.
  • WM_TIMER - to auto-scroll when the cursor leaves the window during a selection.
  • WM_GETDLGCODE - to add DLGC_WANTARROWS so that the arrow keys will get through.
  • WM_MOUSEWHEEL - to respond to the mouse wheel for scrolling.

As lines are added to the text buffer, adjust the range of the scrollbars. The vertical scrollbar range will be the total number of lines, and the horizontal scrollbar range will be the width of the widest line.

It is best to have a single font which is monospaced - it makes the calculations a lot easier. The specific font technology doesn't matter so much. You just need to be able to track the positions of the characters.

How is scrolled performed so efficiently? You track the top and bottom lines of the window as it scrolls, and when a paint message comes you only paint the lines that are currently visible. The others are still in the buffer but they don't get touched. It's possible to blit the contents of the window as it scrolls and only paint the parts that come in from the top or bottom, but with today's processors it's a wasted effort - the window will do a full repaint so quickly that you won't notice.

Edit: Coincidentally I came across this Microsoft guide to scroll bars which should be essential reading for this task. http://msdn.microsoft.com/en-us/library/windows/desktop/bb787527.aspx


If you want to create a beautiful .NET based command prompt replacement, then I suggest looking at http://poshconsole.codeplex.com/ It uses WPF for graphical elements and it implements a PowerShell script host. PowerShell is Microsoft's replacement for the venerable command prompt. PowerShell is installed by default with Windows 7, but you can download it for XP and Vista. PowerShell is highly extensible though scripting of using .NET objects directly. It can also be embedded in other programs.

WPF + PowerShell would be a great starting place for what you want to do. If you wanted you could then swap out PowerShell for your own command/scripting engine. If you were really ambitious you could take a whack at implementing your own scripting language on the DLR to act as your command interpreter.

Best of luck.


I had a big success with RichTextBox for output. Actually it does everything you may wish for: color customization, effective rendering and scrolling, clipboard operations etc. Input was organized by intercepting KeyPress events of the window.