Click here to Skip to main content
15,893,814 members
Articles / Desktop Programming / MFC

QuickWin - Turn a Console Application into a Windows Program

Rate me:
Please Sign up or sign in to vote.
4.83/5 (51 votes)
17 Oct 2000 538.8K   13.1K   230  
Redirect stdin, stdout and stderr into a window
QuickWin is a very useful program to spawn script programs or console applications in a Windows environment without opening a DOS box. In this article, you will see how QuickWin works.
////////////////////////////////////////////////////////////////
// Main frame window for QuickWin
//
#include "stdafx.h"
#include "Redirect.h"
#include "WinPlace.h"
#include "QuickWin.h"

#include "ToolBar.h"
#include "MainFrm.h"
#include "QuickView.h"

// Registry key for profile settings
//
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	//{{AFX_MSG_MAP(CMainFrame)
	ON_MESSAGE(WM_COPYDATA, OnCopyData)
	ON_WM_CREATE()
	ON_WM_SETFOCUS()
	ON_WM_CLOSE()
	ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
	ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateFileSaveAs)
	ON_COMMAND(ID_KEEP_ON_TOP, OnKeepOnTop)
	ON_UPDATE_COMMAND_UI(ID_KEEP_ON_TOP, OnUpdateKeepOnTop)
	ON_WM_SYSCOMMAND()
	ON_COMMAND(ID_VIEW_SPLITTER, OnViewSplitter)
	ON_UPDATE_COMMAND_UI(ID_VIEW_SPLITTER, OnUpdateViewSplitter)
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

CMainFrame::CMainFrame() 
{
}

CMainFrame::~CMainFrame()
{
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if (!CFrameWnd::PreCreateWindow(cs))
		return FALSE;

	if (theApp.m_bKeepOnTop)
		cs.dwExStyle |= WS_EX_TOPMOST;

	return TRUE;
}

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!m_wndToolBar.Init(this, theApp.GetRecentFileList(), theApp.m_strCmdLine))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}

	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		  sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}

	// TODO: Delete these three lines if you don't want the toolbar to
	//  be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	return 0;
}

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
	// create splitter without views
	m_wndSplitter.CreateStatic(this, 2, 1);

	CCreateContext Context;
	Context.m_pNewViewClass = RUNTIME_CLASS(CQuickView);
	Context.m_pCurrentDoc = NULL;
	Context.m_pNewDocTemplate = NULL;
	Context.m_pLastView = NULL;
	Context.m_pCurrentFrame = this;

	// Create the Stdio QuickView
	m_pStdioView  = (CQuickView*)CreateView(&Context, AFX_IDW_PANE_FIRST);
	if (m_pStdioView == NULL)
	{
		TRACE("Failed to create QuickWin Stdio View\n");
		return FALSE;		// fail to create
	}

	// Create the Stderr QuickView
	m_pStderrView  = (CQuickView*)CreateView(&Context, AFX_IDW_PANE_FIRST);
	if (m_pStderrView == NULL)
	{
		TRACE("Failed to create QuickWin Stderr View\n");
		return FALSE;		// fail to create
	}
	m_pStderrView->SetReadOnly(TRUE);

	ShowSplitter(theApp.m_bShowSplitter);
	return TRUE;
}

void CMainFrame::HideAllViews()
{
	// hide all views and splitter
	m_wndSplitter.SetDlgCtrlID(0);
	m_wndSplitter.ShowWindow(SW_HIDE);
	m_pStdioView->SetDlgCtrlID(0);
	m_pStdioView->ShowWindow(SW_HIDE);
	m_pStdioView->SetParent(NULL);
	m_pStderrView->SetDlgCtrlID(0);
	m_pStderrView->ShowWindow(SW_HIDE);
	m_pStderrView->SetParent(NULL);
}

BOOL CMainFrame::IsSplitter()
{
	return ((m_wndSplitter.GetStyle() & WS_VISIBLE) == WS_VISIBLE) ? TRUE: FALSE;
}

void CMainFrame::ShowSplitter(BOOL bShow) 
{
	HideAllViews();
	if (bShow)
	{
		CRect rect; GetClientRect(&rect);
		m_wndSplitter.ShowWindow(SW_SHOW);
		m_wndSplitter.SetDlgCtrlID(AFX_IDW_PANE_FIRST);

		m_pStdioView->SetParent(&m_wndSplitter);  // connect view to splitter
		m_pStdioView->ShowWindow(SW_SHOW);
		m_pStdioView->SetDlgCtrlID(m_wndSplitter.IdFromRowCol(0, 0));
		m_wndSplitter.SetRowInfo(0, 2 * rect.Height() / 3, 1);

		m_pStderrView->SetParent(&m_wndSplitter);  // connect view to splitter
		m_pStderrView->ShowWindow(SW_SHOW);
		m_pStderrView->SetDlgCtrlID(m_wndSplitter.IdFromRowCol(1, 0));
		m_wndSplitter.SetRowInfo(1, rect.Height() / 3, 1);

		SetActiveView(m_pStdioView);
		m_wndSplitter.RecalcLayout();
	}
	else
	{
		m_pStdioView->SetParent(this);
		m_pStdioView->ShowWindow(SW_SHOW);
		m_pStdioView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
		SetActiveView(m_pStdioView);
	}
	RecalcLayout();
	m_pStdioView->SetFocus();
}

void CMainFrame::OnViewSplitter() 
{
	ShowSplitter(!IsSplitter());
}

void CMainFrame::OnUpdateViewSplitter(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(IsSplitter());
}

void CMainFrame::OnSetFocus(CWnd* pOldWnd)
{
	m_pStdioView->SetFocus();
}

// Got command message: pass to QuickView
// Without this, m_pQuickView doesn't get a chance to handle 
// menu commands with ON_COMMAND, etc.

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra,
	AFX_CMDHANDLERINFO* pHandlerInfo)
{
	if (IsSplitter())
	{
		if (m_wndSplitter.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
			return TRUE;	// handled by QuickView
	}
	else
	{
		if (m_pStdioView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
			return TRUE;	// handled by QuickView
	}
	return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

// Someone sent me a WM_COPYDATA message: take action

LRESULT CMainFrame::OnCopyData(WPARAM wParam, LPARAM lParam)
{
	COPYDATASTRUCT* pcds = (COPYDATASTRUCT*)lParam;

	switch (pcds->dwData)
	{
		case SET_WINDOW_TEXT:
		{
			SetWindowText((LPCSTR)pcds->lpData);
			break;
		}
		case STDIO_WRITE_TEXT:
		{
			m_pStdioView->WriteTTY((LPCSTR)pcds->lpData);
			m_pStdioView->SetFocus();
			break;
		}
		case STDERR_WRITE_TEXT:
		{
			if (!IsSplitter())
				m_pStdioView->WriteTTY((LPCSTR)pcds->lpData);
			else
				m_pStderrView->WriteTTY((LPCSTR)pcds->lpData);
			m_pStdioView->SetFocus();
			break;
		}
	}
	return 0;
}

// Save contents of QuickWin to a file

void CMainFrame::OnFileSaveAs() 
{
	CFileDialog dlg(FALSE);
	if (dlg.DoModal()!=IDOK) 
		return;
    m_pStdioView->Save(dlg.GetPathName());
}

void CMainFrame::OnUpdateFileSaveAs(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(!m_pStdioView->IsEmpty());
}

void CMainFrame::OnKeepOnTop() 
{
	DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
	const CWnd* pWnd = dwStyle & WS_EX_TOPMOST ? &wndNoTopMost : &wndTopMost;
	SetWindowPos(pWnd,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
}

void CMainFrame::OnUpdateKeepOnTop(CCmdUI* pCmdUI) 
{
	DWORD dwStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE);
	pCmdUI->SetCheck(dwStyle & WS_EX_TOPMOST ? TRUE : FALSE);
}

// Frame window closed: save position & size in profile.

void CMainFrame::OnClose() 
{
	// Save current settings
	theApp.m_WinPlace.Save(lpszSetting, this);
	theApp.m_bKeepOnTop = ::GetWindowLong(m_hWnd, GWL_EXSTYLE) & WS_EX_TOPMOST ? TRUE : FALSE;
	theApp.m_bShowSplitter = IsSplitter();
	CFrameWnd::OnClose();
}

void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam) 
{
	if ((nID & 0xFFF0) == SC_CLOSE)
		if (!theApp.CanExitInstance()) return;
	CFrameWnd::OnSysCommand(nID, lParam);
}

void CMainFrame::OnSize(UINT nType, int cx, int cy) 
{
	CFrameWnd::OnSize(nType, cx, cy);
	if (IsSplitter())
	{
		CRect rect; m_wndSplitter.GetClientRect(rect);
		int _cx = rect.Width(), _cy = rect.Height() - 10;
		m_wndSplitter.SetRowInfo(0, 2 * _cy / 3, 1);
		m_wndSplitter.SetRowInfo(1, 1 * _cy / 3, 1);
		m_wndSplitter.RecalcLayout();
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
Switzerland Switzerland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions