📄 chapt15.cpp
字号:
//
// CHAPT15.CPP
//
// Source code from:
//
// Serial Communications: A C++ Developer's Guide, 2nd Edition
// by Mark Nelson, IDG Books, 1999
//
// Please see the book for information on usage.
//
// This file contains the source code for the Chapter 15
// demo program. To build this file, use the Visual C++
// project file included in the same directory as the
// sample code. CHAPT15.CPP shows how you might use TAPI
// to take care of modem management in a communications
// program. The terminal emulation portion of this program
// is essentially identical to that of Chapter 13. Where
// it differs is in the use of TAPI to set up the connection
// to a distant modem.
//
#include <windows.h>
#include "resource.h"
#include "AnsiTapiTerm.h"
#include "MySimpleTapi.h"
//
// A couple of forward references needed throughout the
// program.
//
LRESULT CALLBACK WinProc( HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam );
BOOL CALLBACK DlgProc( HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam );
//
// The WinMain() function for this program looks
// very generic. It has to register the class we
// will create for this demo program, being sure
// to include our menu and WinProc. Once the class
// is registered, we can just create the window and
// let it do all the rest of the work. From that
// point on, all we have to do in this routine is
// run the message loop until somebody decides it's
// time to exit.
//
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE /* hPrevInstance */,
LPSTR /* lpCmdLine */,
int nShowCmd )
{
//
// Note that we store enough space extra in our class
// to hold two pointers. The two pointers that will
// be stored in the extra storage space are a pointer to
// the Terminal Emulation object and another to the
// Tapi object.
//
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WinProc;
wc.hInstance = hInstance;
wc.lpszMenuName = MAKEINTRESOURCE( IDR_MENU );
wc.hbrBackground = (HBRUSH) ( COLOR_WINDOW + 1 );
wc.lpszClassName = "Chapter15Class";
wc.cbWndExtra = sizeof( Win32Term * ) + sizeof( MySimpleTapi * );
if ( !RegisterClass( &wc ) ) {
MessageBox( NULL, "Could not register Chapter 15 class!", NULL, MB_OK );
return 0;
}
HWND hwnd = CreateWindow( "Chapter15Class",
"Chapter 15 Test Program",
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
CW_USEDEFAULT,
CW_USEDEFAULT,
647, // hand picked size to fit exactly 25 x 80
347,
NULL,
NULL,
hInstance,
NULL );
if ( hwnd == NULL ) {
MessageBox( NULL, "Chapter15.exe couldn't start!", NULL, MB_OK );
return 0;
}
ShowWindow( hwnd, nShowCmd );
UpdateWindow( hwnd );
MSG msg;
while ( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg ) ;
DispatchMessage( &msg ) ;
}
return 1;
}
//
// To make the user interface a bit easier to fololow, the
// Tapi menu has quite a few entries that can be enabled or
// disabled, and in many cases have two different meanings.
// For example, the menu entry ID_TAPI_PLACE_CALL is set
// to have a string of "Place Call" when the there is no
// active call up, and "Drop Call" when there is an active
// call. Likewise, the menu item is grayed/disabled when
// the TAPI line is closed, and enabled when the TAPI line
// is open.
//
// This routine is called to fix up all the various TAPI
// menu options whenever anything happens that might require
// a change. Clearly it is a bit of overkill to redo all the
// menu options when maybe just one thing changes, but it
// is easier to do it this way than attempting to be clever.
//
void UpdateMenu( HWND hwnd,
MySimpleTapi *pTapi )
{
HMENU menu = GetSubMenu( GetMenu( hwnd ), 1 );
//
// The Open Trace Window item is always enabled, we
// only have to determine what the appropriate text
// should be, based on the state of the trace window.
//
if ( SimpleTapi::m_Trace.IsOpen() )
ModifyMenu( menu,
ID_TAPI_OPEN_TRACE_WINDOW,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_OPEN_TRACE_WINDOW,
"Close Trace Window" );
else
ModifyMenu( menu,
ID_TAPI_OPEN_TRACE_WINDOW,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_OPEN_TRACE_WINDOW,
"Open Trace Window" );
//
// Likewise, the second menu item, Create TAPI Object,
// will always be enabled. The menu text will be set
// to either Create or Destroy the TAPI object.
//
if ( pTapi )
ModifyMenu( menu,
ID_TAPI_CREATE_TAPI_OBJECT,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_CREATE_TAPI_OBJECT,
"Destroy TAPI Object" );
else
ModifyMenu( menu,
ID_TAPI_CREATE_TAPI_OBJECT,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_CREATE_TAPI_OBJECT,
"Create TAPI Object" );
//
// The Open Line menu item should be disabled unless
// a TAPI object exists. If a TAPI object exists,
// the text will depend strictly on whether a line
// is open or not.
//
if ( pTapi && pTapi->IsOpen() )
ModifyMenu( menu,
ID_TAPI_OPEN_LINE,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_OPEN_LINE,
"Close Line" );
else
ModifyMenu( menu,
ID_TAPI_OPEN_LINE,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_OPEN_LINE,
"Open Line" );
if ( pTapi )
EnableMenuItem( menu,
ID_TAPI_OPEN_LINE,
MF_BYCOMMAND | MF_ENABLED );
else
EnableMenuItem( menu,
ID_TAPI_OPEN_LINE,
MF_BYCOMMAND | MF_GRAYED );
//
// The Place Call menu item has text that changes
// back and forth between Place Call and Drop Call,
// depending on whether a call is active. It should
// only be enabled if a line is open.
//
if ( pTapi && pTapi->IsOpen() && pTapi->CallActive() )
ModifyMenu( menu,
ID_TAPI_PLACE_CALL,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_PLACE_CALL,
"Drop Call" );
else
ModifyMenu( menu,
ID_TAPI_PLACE_CALL,
MF_BYCOMMAND | MF_STRING,
ID_TAPI_PLACE_CALL,
"Place Call" );
if ( pTapi && pTapi->IsOpen() )
EnableMenuItem( menu,
ID_TAPI_PLACE_CALL,
MF_BYCOMMAND | MF_ENABLED );
else
EnableMenuItem( menu,
ID_TAPI_PLACE_CALL,
MF_BYCOMMAND | MF_GRAYED );
//
// The three configuration menu items are all enabled
// if the TAPI object is alive, disabled if not. Their
// text never changes.
//
if ( pTapi )
EnableMenuItem( menu,
ID_TAPI_CONFIGURE_LINE,
MF_BYCOMMAND | MF_ENABLED );
else
EnableMenuItem( menu,
ID_TAPI_CONFIGURE_LINE,
MF_BYCOMMAND | MF_GRAYED );
if ( pTapi )
EnableMenuItem( menu,
ID_TAPI_CONFIGURE_CALL,
MF_BYCOMMAND | MF_ENABLED );
else
EnableMenuItem( menu,
ID_TAPI_CONFIGURE_CALL,
MF_BYCOMMAND | MF_GRAYED );
if ( pTapi )
EnableMenuItem( menu,
ID_TAPI_SET_PHONE_NUMBER,
MF_BYCOMMAND | MF_ENABLED );
else
EnableMenuItem( menu,
ID_TAPI_SET_PHONE_NUMBER,
MF_BYCOMMAND | MF_GRAYED );
}
//
// The WinProc given here starts with the same core message
// handlers that were seen in Chapter 13. The main window has
// a single child window that acts as a terminal emulator when
// the port is open. The message handlers for WM_CREATE,
// WM_DESTROY, WM_GETMINMAXINFO, WM_SIZE, and WM_SETFOCUS
// all deal with issues related to that child window. I
// stripped the commands that dealt with the fonts, colors,
// and so on for the child window, but they could easily be
// restored with no more than cut and paste operations.
//
// The remaining message handlers for this window all have
// to deal with issues related to TAPI. All but two of the
// handlers are called as a result of making selections from
// the main menu, and are under the WM_COMMAND handler. The
// other two are messages sent from the TAPI notification
// routines.
//
// Details on exactly what these message handlers do are
// found inline with the code. In general, the way to use
// this program is to:
//
// 1) Open the trace window for help with debugging.
// 2) Create a TAPI object.
// 3) Open a Line
// 4) Wait for an incoming call
// -- or --
// 4) Set the outbound phone number
// 5) Place a call
//
// Either way, the goal at this point is to wait for the
// modem to connect to another modem. When that happens,
// the port is opened, and you are then operating a
// terminal emulator.
//
LRESULT CALLBACK WinProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam )
{
//
// These two pointers reference objects that are stored
// in the excess storage area for this window. The
// pointers are used far and wide among various message
// handlers, so we set them up here for anyone who wants
// to use them. Note that once the window has been
// created, pTerm should always point to a valid terminal
// emulator window, but pTapi may or may not be null
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -