You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
3.8 KiB
152 lines
3.8 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//=============================================================================// |
|
//------------------------------------------------------------------------------ |
|
// Redirect.cpp : implementation file |
|
// |
|
// Creates a child process that runs a user-specified command and redirects its |
|
// standard output and standard error to a CEdit control. |
|
// |
|
// Written by Matt Brunk (brunk@gorge.net) |
|
// Copyright (C) 1999 Matt Brunk |
|
// All rights reserved. |
|
// |
|
// This code may be used in compiled form in any way. This file may be |
|
// distributed by any means providing it is not sold for profit without |
|
// the written consent of the author, and providing that this notice and the |
|
// author's name is included in the distribution. If the compiled form of the |
|
// source code in this file is used in a commercial application, an e-mail to |
|
// the author would be appreciated. |
|
// |
|
// Thanks to Dima Shamroni (dima@abirnet.co.il) for providing the essential |
|
// code for this class. |
|
// |
|
// Thanks to Chris Maunder (chrismaunder@codeguru.com) for the PeekAndPump() |
|
// function (from his CProgressWnd class). |
|
// |
|
// Initial Release Feb 8, 1999 |
|
//------------------------------------------------------------------------------ |
|
|
|
|
|
#include "stdafx.h" |
|
#include <string.h> |
|
#include <string> |
|
#include "Redirect.h" |
|
|
|
const int BUF_SIZE = 8192; |
|
|
|
CRedirect::~CRedirect() |
|
{ |
|
} |
|
|
|
void CRedirect::Run( LPCTSTR szCommand, CEdit *pEdit, LPCTSTR pszCurrentDirectory ) |
|
{ |
|
m_pEdit = pEdit; |
|
m_bStopped = false; |
|
|
|
if ( !Open( szCommand, pszCurrentDirectory ) ) |
|
{ |
|
AppendText("\nFAILED TO SPAWN PROCESS\n"); |
|
return; |
|
} |
|
|
|
for (;;) |
|
{ |
|
//------------------------------------------------------------------ |
|
// If the child process has completed, break out. |
|
//------------------------------------------------------------------ |
|
if ( !m_hThread || MsgWaitForMultipleObjects( 1, &m_hThread, FALSE, 20, QS_ALLINPUT) == WAIT_OBJECT_0 ) |
|
{ |
|
break; |
|
} |
|
|
|
//------------------------------------------------------------------ |
|
// Peek and pump messages. |
|
//------------------------------------------------------------------ |
|
PeekAndPump(); |
|
|
|
//------------------------------------------------------------------ |
|
// If the user cancelled the operation, terminate the process. |
|
//------------------------------------------------------------------ |
|
if ( m_bStopped ) |
|
{ |
|
Close(); |
|
} |
|
} |
|
} |
|
|
|
|
|
void CRedirect::PeekAndPump() |
|
{ |
|
MSG Msg; |
|
while (::PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE)) |
|
{ |
|
(void)AfxGetApp()->PumpMessage(); //lint !e1924 (warning about C-style cast) |
|
} |
|
} |
|
|
|
void CRedirect::Stop() |
|
{ |
|
m_bStopped = true; |
|
} |
|
|
|
void CRedirect::AppendText(LPCTSTR Text) |
|
{ |
|
char *pszCurrent = const_cast<char *>(Text); |
|
int Length; |
|
|
|
Length = m_pEdit->GetWindowTextLength(); |
|
if ( Length + strlen(Text) > m_pEdit->GetLimitText() ) |
|
m_pEdit->SetLimitText( m_pEdit->GetLimitText() * 2 ); |
|
|
|
if ( *pszCurrent == '\n' ) |
|
pszCurrent++; |
|
|
|
while ( pszCurrent && *pszCurrent ) |
|
{ |
|
char *pszLineEnd = strchr( pszCurrent, '\r' ); |
|
if ( pszLineEnd ) |
|
*pszLineEnd = 0; |
|
|
|
Length = m_pEdit->GetWindowTextLength(); |
|
m_pEdit->SetSel(Length, Length); |
|
m_pEdit->ReplaceSel(pszCurrent); |
|
//OutputDebugString(pszCurrent); |
|
|
|
if ( pszLineEnd ) |
|
{ |
|
Length = m_pEdit->GetWindowTextLength(); |
|
m_pEdit->SetSel(Length, Length); |
|
m_pEdit->ReplaceSel("\r\n"); |
|
//OutputDebugString("\r\n"); |
|
} |
|
|
|
m_pEdit->LineScroll( m_pEdit->GetLineCount() ); |
|
PeekAndPump(); |
|
|
|
if ( pszLineEnd ) |
|
{ |
|
*pszLineEnd = '\r'; |
|
pszCurrent = pszLineEnd + 1; |
|
if ( *pszCurrent == '\n' ) |
|
pszCurrent++; |
|
} |
|
else |
|
pszCurrent = NULL; |
|
}; |
|
} |
|
|
|
|
|
void CRedirect::WriteStdOut(LPCSTR pszOutput) |
|
{ |
|
AppendText( pszOutput ); |
|
} |
|
|
|
void CRedirect::WriteStdError(LPCSTR pszError) |
|
{ |
|
AppendText( CString(pszError) ); |
|
}
|
|
|