Click here to Skip to main content
Click here to Skip to main content

Transparent Console Application

, 30 Aug 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Asa Meltzer
Software Developer
Israel Israel
Software designer and programmer.
Programming languages:
MFC, C++, Java , C#, VB and sometimes C and assembly.

Comments and Discussions

 
QuestionCTrl+C command? PinmemberTcpip200523-Apr-06 16:50 
AnswerRe: CTrl+C command? PinmemberAsa Meltzer24-Apr-06 3:28 
GeneralRe: CTrl+C command? PinmemberTcpip200524-Apr-06 15:53 
GeneralRe: CTrl+C command? PinmemberTcpip200524-Apr-06 15:56 
And use the handler,tconsole will act the same as cmd.exe when you press ctrl+c.
The function CRedirector::OnNewConsole can only seemd to do so.
GeneralRe: CTrl+C command? PinmemberAsa Meltzer25-Apr-06 21:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141030.1 | Last Updated 31 Aug 2004
Article Copyright 2004 by Asa Meltzer
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid