Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Transparent Console Application

0.00/5 (No votes)
30 Aug 2004 1  
Implementing a transparent console application.

Sample Image - transparentconsole.gif

Sample screenshot - another

Introduction

Have you ever seen those nice Unix\Linux transparent terminals and thought - why can't I get one of those for Windows?

Well, the search is over - well, not really, still some way to go, but this will be a good place to start.

Credits

First things first though, this article (and project for that matter) is based on articles and code from The Code Project site and I mainly integrated the code. I will go over a few of the problems I've encountered but without further ado, here they are:

  1. Transparency.
  2. Fonts.
  3. Completion ComboBox.
  4. Resize and Move messages.
  5. Color picker control.
  6. Fancy controls.
  7. Console I\O redirector.
  8. Anybody I forgot and deserves credit.

Implementation Notes

I encountered a few problems while writing this little application, and it might be interesting for some to understand what these problems where so they\you can avoid them (or solve them faster) in the future.

Sending the commands from the combo to the I\O redirector

You would expect a ComboBox to have an OnEnter event, wouldn't you? Nope, it doesn't. So what do you do when you type your command and want to send it to the console? Here's how I did it:

First, I provided an interface for the event handler. The handler registers itself on the combo and can handle events like keystrokes etc. The combo's job is to call the handler's function when the event occurs. In this case, I handled the ENTER event and F1 (restarting the console when an operation takes too long for my liking - anybody said "tracert" ?).

class Eventer
  {
     public:     
     Eventer(void);
     virtual ~Eventer(void);
     virtual void PerformAction(const CString& strCmd) = 0;
     virtual void PerformSpecialAction(UINT nAction) = 0;
  };

The next thing to do was to inherit the interface and register on the combo:

 class CTConsoleView : public CFormView, Eventer
 m_combo.Register(this);

Now we need to catch those events like ENTER and perform the action we want - in this case, pass the input to the console. Another event that is caught is F1 - it's much harder to handle a CTRL+C in the combo, but you might want to imitate the functionality of the command, hence F1 - F12 keystrokes are caught and can be handled. As an example, I handled F1 to restart the console.

BOOL CHMXComboBox::PreTranslateMessage(MSG* pMsg) 
{
  InitToolTip();
  m_tt.RelayEvent(pMsg);
  // catching the key down events 

  if (pMsg->message == WM_KEYDOWN)
  {
    // making sure we are going to auto complete

    // what is written

    m_bAutoComplete = TRUE;
    int nVirtKey = (int) pMsg->wParam;
    if (nVirtKey == VK_DELETE || nVirtKey == VK_BACK)
       m_bAutoComplete = FALSE;
    // On enter we call our eventer to perform 

    // it's job

    if (nVirtKey == VK_RETURN) 
    { 
      CString sText; 
      GetWindowText(sText); 

      if(FindString(0,sText) == CB_ERR) 
         AddString(sText);
      for(int i(0);i < m_arrEventers.GetSize(); i++) 
      { 
        Eventer* pEvent = (Eventer*)m_arrEventers[i]; 
        // eventer performs action here 

        Event->PerformAction(sText); 
      }
    }
    // Use F1 - F12 keys on the console instead of CTRL+C etc' 

    if (nVirtKey >= VK_F1 && nVirtKey <= VK_F12) 
    { 
      for(int i(0);i < m_arrEventers.GetSize(); i++) 
      { 
        Eventer* pEvent = (Eventer*)m_arrEventers[i]; 
        pEvent->PerformSpecialAction(nVirtKey); 
      } 
    } 
}

And finally, handling the event (for example, we wouldn't want to send the "edit" command to the console because the cmd.exe process opens the DOS edit utility). So, in order to override it, we have to perform some sort of string parsing on the command.

void CTConsoleView::PerformAction(const CString& strCmd) 
{ 
  // if the user typed edit we do not want to open the 

  // edit utility on the cmd process. 

  if(!strCmd.Left(4).CompareNoCase("edit")) 
  { 
    CString cmd = "notepad.exe "; 
    cmd += strCmd.Right(strCmd.GetLength()-4); 
    WinExec(cmd, SW_SHOW);
    return; 
  }
  // otherwise we send it to the console 

  m_redir.Printf("%s\r\n", strCmd); 
  m_combo.SetWindowText(""); 
}

Final Notes

Well, I think that's enough for now. If you have any questions, you are welcome to submit them in the comments section, or email me.

Good coding.

Asa.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here