A Simple Command Line Interface with a Custom Scrollbar

The CCommandLine control can be used to add a command line interface to any application. It supports a "scrollback buffer" of the last 100 lines typed in, as well as a custom scrollbar whose functionality mirrors that found under certain versions of KDE and Gnome.

Note: It makes use of the CMemDC class written by Keith Rule, and downloaded from codeguru.com.

Some may find this project useful for the scrollbar alone because it is totally drawn from scratch. What makes it different is the up/down buttons usually found at the top and bottom of the average windows scrollbar are both at the bottom. This makes it easier for the user to scroll up and down without moving the mouse from the top of the window to the bottom, and vice versa. A duplicate "up" button is positioned at the top for users who feel more comfortable with the traditional placement. It is not yet as perfect as I would like it to be, but it is very serviceable. If you have any suggestions that will make it better, let me know.

The scrollback buffer is another interesting feature that mirrors a feature found it good old DOS (remember DOS?). Pressing F3 or the arrow up/down buttons recalls the last command typed in, and by pressing Enter that command can be used. The scrollback is stored as a vector, so increasing its size is a simple matter of changing a constant. The same goes for the number of display lines. It too is a vector, and increasing its size is a matter of changing a constant.

To use this control in a dialog based project, add this to your dialog's header file:

#include "CommandLine.h"
#define ID_CTRL_COMMAND_LINE (WM_USER+100)    //  some valid control Id.

Then, declare an instance of it in the dialog's class definition.

   CCommandLine m_CommandLine;

To create an instance of this control, place the following in "OnInitDialog":

m_CommandLine.Create(CRect(0, 0, 200, 100), uiFlags, this,

The "WS_TABSTOP" ensures that keystrokes will be captured by this control if only the keyboard is being used. The "SetReceiver" method tells the control where to send notification messages. If this attribute is not set, you will not be able to detect when a command has been sent.

To perform an action, such as parsing a command, add a handler for "NM_COMMAND_SENT" to your dialog:

In the dialog header file:

afx_msg void OnCommandSent(NMHDR* pNMHDR, LRESULT* pResult);

In the dialog .cpp file message map:


In the dialog .cpp file:

void CTestDlg::OnCommandSent(NMHDR* pNMHDR, LRESULT* pResult)
   //  get the last command...
   CString szCmd = m_CommandLine.GetLastCommand();
   //  other stuff here...

To show a response within the control, call the "AddRecv" method with either char pointer or a CString.

//  some code...
m_CommandLine.AddRecv("This is a response to your command.");
//  some more code...

This will appear as:

<  This is a response to your command.

The "<" before the text indicates that it is a "incoming" command or response. Commands typed in have a ">" to the left of them to indicate that they are outgoing.

One command is built in: the "cls" command. For those of us who remember DOS, this was the way you would clear the screen. It has the same effect here, in that it empties the control of any past display. "cls" is only the default for clearing the screen; you can change it by calling "SetClsCommand". The prompt, which is defaulted to "Command: " can be set by using "SetPrompt".

Other notable attributes and methods are:

Attribute or Method Description
SetTabSpaces Sets the number of spaces to insert when the tab key is pressed.
SetLocked Ignores any keyboard input.
UpdateLine Changes the text of an existing line. This can be used to show progress by changing a line's text from something like "Percent completed : 98%" to "Percent completed : 99%".
SendChar Sends input to the control one character at a time. Useful in re-directing characters from another control to the command line.

This control is a good starting point if you need to include a command line-like interface with your next killer app. It is generously commented, and is fairly straightforward in its implementation. Additional features such as printing, copy, cut and paste, as well as rich formatting could be added quite easily.

About the Author

Paul Grenz

Paul Grenz is a software engineer with the University of Arizona, located in beautiful, sunny Tucson. His primary focus is writing software to run the LBTO (Large Binocular Telescope Observatory). When he is not writing hardware control/image processing software, he can be found writing about himself in the third person or playing with his wonderful daughter Elizabeth.



  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The open source cloud computing project OpenStack has come a long way since NASA and Rackspace launched it in 2010. Backed by leading technology infrastructure providers including Cisco, Dell, EMC, HP, IBM, Intel, and VMware, OpenStack underpins significant workloads at an increasingly diverse set of organizations, including BWM, CERN, Comcast, eBay, and Wal-Mart. For CIOs engaged in broader programs to win, serve, and retain customers -- and refocus business technology (BT) spend -- a planned and pragmatic …

  • Entire organizations suffer when their networks can't keep up and new opportunities are put on hold. Waiting on service providers isn't good business. In these examples, learn how to simplify network management so that your organization can better manage costs, adapt quickly to business demands, and seize market opportunities when they arise.

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date