//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //=============================================================================// #include #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; } }