source-engine/utils/common/consolewnd.cpp

334 lines
6.6 KiB
C++
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include <windows.h>
#include "consolewnd.h"
#pragma warning( disable : 4311 ) // warning C4311: 'reinterpret_cast' : pointer truncation from 'CConsoleWnd *const ' to 'LONG'
#pragma warning( disable : 4312 ) // warning C4312: 'type cast' : conversion from 'LONG' to 'CConsoleWnd *' of greater size
#define EDITCONTROL_BORDER_SIZE 5
// ------------------------------------------------------------------------------------------------ //
// Functions to manage the console window.
// ------------------------------------------------------------------------------------------------ //
class CConsoleWnd : public IConsoleWnd
{
public:
CConsoleWnd();
~CConsoleWnd();
bool Init( void *hInstance, int dialogResourceID, int editControlID, bool bVisible );
void Term();
virtual void Release();
virtual void SetVisible( bool bVisible );
virtual bool IsVisible() const;
virtual void PrintToConsole( const char *pMsg );
virtual void SetTitle( const char *pTitle );
virtual void SetDeleteOnClose( bool bDelete );
private:
int WindowProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
static int CALLBACK StaticWindowProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
void RepositionEditControl();
private:
HWND m_hWnd;
HWND m_hEditControl;
bool m_bVisible;
bool m_bDeleteOnClose;
int m_nCurrentChars;
};
CConsoleWnd::CConsoleWnd()
{
m_hWnd = m_hEditControl = NULL;
m_bVisible = false;
m_bDeleteOnClose = false;
m_nCurrentChars = 0;
}
CConsoleWnd::~CConsoleWnd()
{
Term();
}
bool CConsoleWnd::Init( void *hInstance, int dialogResourceID, int editControlID, bool bVisible )
{
// Create the window.
m_hWnd = CreateDialog(
(HINSTANCE)hInstance,
MAKEINTRESOURCE( dialogResourceID ),
NULL,
&CConsoleWnd::StaticWindowProc );
if ( !m_hWnd )
return false;
SetWindowLong( m_hWnd, GWL_USERDATA, reinterpret_cast< LONG >( this ) );
if ( bVisible )
ShowWindow( m_hWnd, SW_SHOW );
// Get a handle to the edit control.
m_hEditControl = GetDlgItem( m_hWnd, editControlID );
if ( !m_hEditControl )
return false;
RepositionEditControl();
m_bVisible = bVisible;
return true;
}
void CConsoleWnd::Term()
{
if ( m_hWnd )
{
DestroyWindow( m_hWnd );
m_hWnd = NULL;
}
}
void CConsoleWnd::Release()
{
delete this;
}
void CConsoleWnd::SetVisible( bool bVisible )
{
ShowWindow( m_hWnd, bVisible ? SW_RESTORE : SW_HIDE );
if ( bVisible )
{
ShowWindow( m_hWnd, SW_SHOW );
SetWindowPos( m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );
UpdateWindow( m_hWnd );
int nLen = (int)SendMessage( m_hEditControl, EM_GETLIMITTEXT, 0, 0 );
SendMessage( m_hEditControl, EM_SETSEL, nLen, nLen );
}
else
{
SetWindowPos( m_hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_NOOWNERZORDER );
}
m_bVisible = bVisible;
}
bool CConsoleWnd::IsVisible() const
{
return m_bVisible;
}
void CConsoleWnd::PrintToConsole( const char *pMsg )
{
if ( m_nCurrentChars >= 16*1024 )
{
// Clear the edit control otherwise it'll stop outputting anything.
m_nCurrentChars = 0;
int nLen = (int)SendMessage( m_hEditControl, EM_GETLIMITTEXT, 0, 0 );
SendMessage( m_hEditControl, EM_SETSEL, 0, nLen );
SendMessage( m_hEditControl, EM_REPLACESEL, FALSE, (LPARAM)"" );
}
FormatAndSendToEditControl( m_hEditControl, pMsg );
m_nCurrentChars += (int)strlen( pMsg );
}
void CConsoleWnd::SetTitle( const char *pTitle )
{
SetWindowText( m_hWnd, pTitle );
}
int CConsoleWnd::WindowProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
lParam = lParam; // avoid compiler warning
if ( hwndDlg != m_hWnd )
return false;
switch ( uMsg )
{
case WM_SYSCOMMAND:
{
if ( wParam == SC_CLOSE )
{
if ( m_bDeleteOnClose )
{
Release();
}
else
{
SetVisible( false );
return true;
}
}
}
break;
case WM_SHOWWINDOW:
{
m_bVisible = (wParam != 0);
}
break;
case WM_SIZE:
case WM_INITDIALOG:
{
RepositionEditControl();
}
break;
}
return false;
}
int CConsoleWnd::StaticWindowProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
CConsoleWnd *pDlg = (CConsoleWnd*)GetWindowLong( hwndDlg, GWL_USERDATA );
if ( pDlg )
return pDlg->WindowProc( hwndDlg, uMsg, wParam, lParam );
else
return false;
}
void CConsoleWnd::RepositionEditControl()
{
RECT rcMain;
GetClientRect( m_hWnd, &rcMain );
RECT rcNew;
rcNew.left = rcMain.left + EDITCONTROL_BORDER_SIZE;
rcNew.right = rcMain.right - EDITCONTROL_BORDER_SIZE;
rcNew.top = rcMain.top + EDITCONTROL_BORDER_SIZE;
rcNew.bottom = rcMain.bottom - EDITCONTROL_BORDER_SIZE;
SetWindowPos(
m_hEditControl,
NULL,
rcNew.left,
rcNew.top,
rcNew.right - rcNew.left,
rcNew.bottom - rcNew.top,
SWP_NOZORDER );
}
void CConsoleWnd::SetDeleteOnClose( bool bDelete )
{
m_bDeleteOnClose = bDelete;
}
// ------------------------------------------------------------------------------------ //
// Module interface.
// ------------------------------------------------------------------------------------ //
void SendToEditControl( HWND hEditControl, const char *pText )
{
int nLen = (int)SendMessage( hEditControl, EM_GETLIMITTEXT, 0, 0 );
SendMessage( hEditControl, EM_SETSEL, nLen, nLen );
SendMessage( hEditControl, EM_REPLACESEL, FALSE, (LPARAM)pText );
}
void FormatAndSendToEditControl( void *hWnd, const char *pText )
{
HWND hEditControl = (HWND)hWnd;
// Translate \n to \r\n.
char outMsg[1024];
const char *pIn = pText;
char *pOut = outMsg;
while ( *pIn )
{
if ( *pIn == '\n' )
{
*pOut = '\r';
pOut++;
}
*pOut = *pIn;
++pIn;
++pOut;
if ( pOut - outMsg >= 1020 )
{
*pOut = 0;
SendToEditControl( hEditControl, outMsg );
pOut = outMsg;
}
}
*pOut = 0;
SendToEditControl( hEditControl, outMsg );
}
IConsoleWnd* CreateConsoleWnd( void *hInstance, int dialogResourceID, int editControlID, bool bVisible )
{
CConsoleWnd *pWnd = new CConsoleWnd;
if ( pWnd->Init( hInstance, dialogResourceID, editControlID, bVisible ) )
{
return pWnd;
}
else
{
pWnd->Release();
return NULL;
}
}