⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapt15.cpp

📁 DOS下采用中断接收数据的串口通讯的例子,很难找到的好东西!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    AnsiTapiTerm *pTerm;
    MySimpleTapi *pTapi;
    pTerm = (AnsiTapiTerm *) GetWindowLong( hWnd, 0 );
    pTapi = (MySimpleTapi *) GetWindowLong( hWnd, 4 );

    switch ( message ) 
    {
        //
        // When my window is first created, I immediately
        // create the terminal window as a child window. I
        // get the pointer to the C++ object and store it as
        // a window long word, giving me access to it whenever
        // I need it without using a global variable. 
        //
        case WM_CREATE:
            pTerm = new AnsiTapiTerm( hWnd, "AnsiTerm Window", 25, 80 );
            SetWindowLong( hWnd, 0, (LONG) pTerm );
            if ( pTerm->m_hWnd == NULL )
                MessageBox( hWnd, "Can't open child window", "Chapter 15", MB_OK );
            SetFocus( hWnd );
            break;
        //
        // When I am being destroyed, I take it upon myself 
        // to destroy both the terminal object and the Tapi 
        // object, if one exists.
        //
        case WM_DESTROY: 
            delete pTerm;
            pTerm = 0;
            if ( pTapi ) {
                delete pTapi;
                pTapi = 0;
            }
            PostQuitMessage( 0 );
            break;
        //
        // Just for the sake of esthetics, I respond to this message
        // with a minimum size large enough to prevent somebody from
        // resizing me down to the point of ridiculousness.
        //
        case WM_GETMINMAXINFO:
            {
                LPMINMAXINFO lp = (LPMINMAXINFO) lParam;
                POINT ptTemp = { 
                    lp->ptMinTrackSize.x,
                    GetSystemMetrics( SM_CYMENU )        + 
                       GetSystemMetrics( SM_CYCAPTION )  +
                       2 * GetSystemMetrics( SM_CYFRAME )
                };
                lp->ptMinTrackSize = ptTemp;
            }        
            break;

        //
        // When the frame window is resized, I immediately 
        // resize the terminal window. Size the terminal window
        // is supposed to completely fill my client area, I
        // can figure out what size it is supposed to be by
        // simply getting the size of my client rect. When
        // the terminal window processes this command it will
        // potentially add scroll bars and offset the display.
        //
        case WM_SIZE:
            {
                RECT rc;
                ::GetClientRect( hWnd, &rc );
                if ( lParam != 0 )
                ::MoveWindow( pTerm->m_hWnd, 
                              0, 0, 
                              rc.right - rc.left + 1,
                              rc.bottom - rc.top + 1,
                              TRUE );
            }
            break;
        //
        // I don't want the framing window to get the focus,
        // so whenever I get it, I immediately foist it upon
        // the terminal window.
        //
        case WM_SETFOCUS :
            SetFocus( pTerm->m_hWnd );
            return 0;
        //
        // The rest of the code in the message loop 
        // is the set of command handlers for menu
        // items.
        //
        case WM_COMMAND:       
            switch ( LOWORD( wParam ) ) {
            //
            // Telling a window to close itself is a fast way 
            // of shutting the program down, so that's how
            // we deal with the File|Exit menu item.
            //
            case ID_FILE_EXIT :
                PostMessage( hWnd, WM_CLOSE, 0, 0 );
                break;
            //
            // The base class, SimpleTapi, has a trace object
            // that receives various messages as the object
            // does its TAPI stuff. This trace window can be
            // open or closed. This command toggles it back
            // and forth between these two states. Since the
            // trace object is static, we don't even need to
            // use a pointer to the TAPI object. When the 
            // object is opened, a completely separate 
            // console window is opened up to receive trace
            // information.
            //
            case ID_TAPI_OPEN_TRACE_WINDOW :
                if ( SimpleTapi::m_Trace.IsOpen() ) 
                    SimpleTapi::m_Trace.Close();
                else 
                    SimpleTapi::m_Trace.Open();
                UpdateMenu( hWnd, pTapi );
                break;
            //
            // We can't do much of anything interesting
            // with this program until the simple TAPI 
            // object is created. This command handler
            // will either create or destroy the object,
            // depending on whether or not it currently
            // exists. The value of the pTapi after the
            // operation has to be stuffed in the window
            // storage area so it will persist past the 
            // end of this command processing.
            //
            case ID_TAPI_CREATE_TAPI_OBJECT :
                if ( pTapi ) {
                    delete pTapi;
                    pTapi = 0;
                } else 
                    pTapi = new MySimpleTapi( hWnd );
                SetWindowLong( hWnd, 4, (LONG) pTapi );
                UpdateMenu( hWnd, pTapi );
                break;
            //
            // This menu object should be grayed out unless
            // the pTapi object has been created. If it has,
            // we can either open or close the line. Note 
            // that this call is hard coded to open the first
            // TAPI line. A better program would let you
            // select from among the available lines via
            // some sort of selection dialog. Note that the
            // two functions called here both return 
            // immediately, we don't have to wait for a
            // delayed response.
            //
            case ID_TAPI_OPEN_LINE :
                if ( pTapi->IsOpen() ) 
                    pTapi->CloseLine();
                else 
                    pTapi->OpenLine( 0 );
                UpdateMenu( hWnd, pTapi );
                break;
            //
            // This menu item should only be enabled if a
            // line has been opened. It will then either 
            // place a call or drop a call, depending on
            // whether a call is active. This is a little
            // bit tricky, because we have to deal with the
            // fact that both of these calls don't return
            // an immediate result
            //
            case ID_TAPI_PLACE_CALL :
                if ( pTapi->CallActive() )
                    pTapi->DropCall();
                else
                    pTapi->MakeCall( pTapi->m_NumberToDial );
                break;
            //
            // The followign three menu items are enabled as
            // long as a TAPI object is alive. All three are
            // used to configure the parameters surrounding 
            // a TAPI call. The first two just invoke the 
            // standard dialogs supplied by TAPI to configure
            // modems and the way they place calls. The final
            // of the three pops up a dialog that optionally
            // modifies the current outbound phone number.
            //
            case ID_TAPI_CONFIGURE_LINE :
                pTapi->ConfigureDevice( 0 );
                break;
            case ID_TAPI_CONFIGURE_CALL :
                pTapi->ConfigureCall( 0, pTapi->m_NumberToDial );
                break;
            case ID_TAPI_SET_PHONE_NUMBER :
                DialogBox( GetModuleHandle( NULL ), 
                           MAKEINTRESOURCE(IDD_GET_PHONE_NUMBER),
                           hWnd, 
                           (DLGPROC) DlgProc );
                break;

            }
            break;
        //
        // My specialized class derived from SimpleTapi
        // is called MySimpleTapi. I've configured it to
        // send the following Windows messages to a specific
        // window as part of its notification process. I use
        // the notification event to update the UI, mostly
        // by printing a message on the terminal screen and
        // 
        case WM_TAPI_CONNECTED_NOTIFY :
            *pTerm << "\r\nConnected\r\n";
            UpdateMenu( hWnd, pTapi );
            break;
        case WM_TAPI_DISCONNECTED_NOTIFY :
            *pTerm << "\r\nDisconnected\r\n";
            UpdateMenu( hWnd, pTapi );
            break;
        case WM_TAPI_STATE_CHANGE_NOTIFY :
            UpdateMenu( hWnd, pTapi );
            break;
        default:
            return DefWindowProc( hWnd, message, wParam, lParam );
    }
    return 0L;
}

//
// This program was written without the use of MFC or any
// other application framework, which means that using a
// dialog box to get a text string is a bit of trouble. The
// sole use of a dialog box in this program is to get the 
// phone number that is to be dialed upon selection of the
// Place Call menu item.
//
// This dialog box assumes that its parent is the Chapter 15
// main window. Because of that, it can extract a pointer to 
// the TAPI object from the storage area associated with that
// window. The phone number is stored in that structure, 
// which means we can preload the text box with the number, 
// then update the structure with the new value if the user
// clicks on the OK box to exit.
//

BOOL CALLBACK DlgProc( HWND hWnd,
                       UINT uMsg,
                       WPARAM wParam,
                       LPARAM lParam )
{
    HWND hParent = GetParent( hWnd );
    MySimpleTapi *pTapi;
    pTapi = (MySimpleTapi *) GetWindowLong( hParent, 4 );
  
    switch ( uMsg ) {

    //
    // When the dialog is first being created, we load up
    // the edit text box with a copy of the phone number
    // currently loaded into the text box.
    //
    case WM_INITDIALOG :
        SetDlgItemText( hWnd, 
                        IDC_PHONE_NUMBER,
                        pTapi->m_NumberToDial.c_str() );
        return TRUE;
    
    case WM_COMMAND :
        switch ( LOWORD( wParam ) ) {
        //
        // If the user clicks on the cancel button, we just
        // exit without updating any data.
        //
        case IDCANCEL :
            EndDialog( hWnd, 0 );
            return TRUE;
        //
        // If the user clicks OK, we update the phone number
        // field in the TAPI object with whatever was typed
        // into the field. No checks are made to ensure that
        // it is a legal number.
        //
        case IDOK :
            {
                char number[ 25 ];
                ::GetDlgItemText( hWnd,
                                  IDC_PHONE_NUMBER,
                                  number,
                                  24 );
                pTapi->m_NumberToDial = number;
                EndDialog( hWnd, 0 );
            }
            return TRUE;
        }
    }
    return FALSE;
}

// End of CHAPT15.CPP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -