// // AnsiWinTerm.h // // Source code from: // // Serial Communications: A C++ Developer's Guide, 2nd Edition // by Mark Nelson, M&T Books, 1999 // // Please see the book for information on usage. // // This file contains the declarations for class AnsiWinTerm, // the glue class that holds together all the pieces needed to // create a Win32 terminal emulator. This class is used in the // example program for Chapter 13. // #ifndef _ANSI_WIN_TERM_DOT_H #define _ANSI_WIN_TERM_DOT_H #include "AnsiTerm.h" #include "Win32Port.h" #include "Win32Term.h" // // To use notification with class Win32Port, you need to // create a derived class that overrides all of the notification // functions that you plan on using. This class, MyWin32Port, // does just that, overriding the RxNotify() function so that // we can be notified every time new data comes in. // // The notification function is simple as can be, it just // sends a proprietary message to the window that was specified // in the constructor. It's then up to that window to decide // what to do. // // This is a stripped down port class, it uses a fixed baud // rate, only allowing you to specify the actual port to be // opened. The steps that would be needed to beef up the class // to production quality should be pretty straightforward. // // Fortunately, if you need to modify the baud rate or any // other parameters you can do so immediately after opening // the port. // const int WM_SERIAL_RX_NOTIFY = WM_USER + 0x1000; class MyWin32Port : public Win32Port { public: MyWin32Port( const string &name, HWND notify_window ) : Win32Port( name, 19200, 'N', 8, 1 ), m_hNotifyWindow( notify_window ) {} virtual ~MyWin32Port(){} protected : void RxNotify( int byte_count ) { ::PostMessage( m_hNotifyWindow, WM_SERIAL_RX_NOTIFY, byte_count, 0 ); } const HWND m_hNotifyWindow; }; // // Class AnsiWinTerm is the only class in the entire book // that uses multiple inheritance. This class inherits all // the attributes of Win32Term, which is capable of // keeping a console-style text window up on the screen. // To work with the Emulator classes, it also has to support // the abstract interface defined for BaseWindow, so it // derives itself from that as well. It then has to implement // the eight pure virtual functions defined for class // BaseWindow. Fortunately, all of those functions turn out // to be trivially simple. // class AnsiWinTerm : public Win32Term, public BaseWindow { public: // // The parameters we need to construct the window are // actually only used by the base class. We pass all the // arguments up to the Win32Term constructor without // any changes. All we do with our data is to make sure // the two members are set to null pointers, so we don't // inadvertently treat them as if they were instantiated. // AnsiWinTerm( HWND hParent, const char *window_name, int rows, int cols ) : Win32Term( hParent, window_name, rows, cols ) { m_pPort = 0; m_pTerminal = 0; } // // Upon destruction we need to be sure that we // destroy our two member objects. // virtual ~AnsiWinTerm() { if ( m_pTerminal ) delete m_pTerminal; if ( m_pPort ) delete m_pPort; } public: bool OpenPort( const string &name ); void ClosePort(); // // The eight pure virtual functions from // class BaseWindow. Each of them is implemented // as a simple inline function. // virtual BaseWindow &operator<<( char c ) { Output( c ); return *this; } virtual BaseWindow &operator<<( char *pStr ) { Output( pStr ); return *this; } virtual void Clear( void ) { Win32Term::Clear(); } virtual void Goto( void ) { ::SetFocus( m_hWnd ); } virtual void AnsiWinTerm::SetAttribute( int att ) { attribute = (DisplayAttribute) att; SetForegroundColor( ForegroundPalette[ att & 0xf ] ); SetBackgroundColor( BackgroundPalette[ (att >> 4) & 0x7 ] ); } virtual int SetPosition( int row, int col ) { return Win32Term::SetCursorPosition( row, col ); } virtual void GetPosition( int &row, int &col ) { Win32Term::GetCursorPosition( row, col ); } virtual void GetDimensions( int &width, int &height ) { width = m_ScreenText[ 0 ].size(); height = m_ScreenText.size(); } static const COLORREF ForegroundPalette[ 16 ]; static const COLORREF BackgroundPalette[ 8 ]; protected : // // This is the dispatcher for all window messages // that are sent to the terminal emulator window. // We intercept the RX notification messages and // any keystroke messages, but pass everything else // up to the base class for handling. // virtual LRESULT Dispatch( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); protected : // // The two data member used here, an RS232 port and // a terminal emulator. Add in the window that this // class implements and you have all the components // needed for a terminal emulation program. // MyWin32Port * m_pPort; AnsiTerminal * m_pTerminal; }; #endif //#ifndef _ANSI_WIN_TERM_DOT_H