// // AnsiTapiTerm.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 AnsiTapiTerm, // the glue class that holds together all the pieces needed to // create a Tapi based terminal emulator. This class is used // in the example program for Chapter 15. Note that the code // in this class is very nearly identical to that of the // class AnsiWinTerm in Chapter 13. The main difference is // that the latter uses a Win32Port object for communications, // while this class uses a Tapi32Port object. // #ifndef _ANSI_TAPI_TERM_DOT_H #define _ANSI_TAPI_TERM_DOT_H #include "Win32Term.h" #include "AnsiTerm.h" #include "Tapi32Port.h" // // To use notification with class Tapi32Port, you need to // create a derived class that overrides all of the // notification functions that you plan on using. This class, // MyTapi32Port, 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. // // const int WM_SERIAL_RX_NOTIFY = WM_USER + 0x1000; class MyTapi32Port : public Tapi32Port { public: MyTapi32Port( HANDLE h, HWND notify_window ) : Tapi32Port( h ), m_hNotifyWindow( notify_window ) {} virtual ~MyTapi32Port(){} protected : void RxNotify( int byte_count ) { ::PostMessage( m_hNotifyWindow, WM_SERIAL_RX_NOTIFY, byte_count, 0 ); } const HWND m_hNotifyWindow; }; // // Class AnsiTapiTerm is one of only two classes in the // entire book that use 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 AnsiTapiTerm : 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. // AnsiTapiTerm( 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 ~AnsiTapiTerm() { if ( m_pTerminal ) delete m_pTerminal; if ( m_pPort ) delete m_pPort; } public: bool OpenPort( HANDLE h ); 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 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. // MyTapi32Port * m_pPort; AnsiTerminal * m_pTerminal; }; #endif //#ifndef _ANSI_TAPI_TERM_DOT_H