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

📄 tapicode.c

📁 一份有用的TAPI编程源码
💻 C
📖 第 1 页 / 共 5 页
字号:

//
//  FUNCTION: DoLineClose(..)
//
//  PURPOSE: Handle LINE_CLOSE asynchronous messages.
//
//  PARAMETERS:
//    dwDevice  - Line Handle that was closed.
//    dwMsg     - Should always be LINE_CLOSE.
//    dwCallbackInstance - Unused by this sample.
//    dwParam1  - Unused.
//    dwParam2  - Unused.
//    dwParam3  - Unused.
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
//    This message is sent when something outside our app shuts
//    down a line in use.
//
//    The hLine (and any hCall on this line) are no longer valid.
//
//

void DoLineClose(
    DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
    DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
    // Line has been shut down.  Clean up our internal variables.
    g_hLine = (HLINE)((ULONG_PTR)NULL);
    g_hCall = (HCALL)((ULONG_PTR)NULL);
    UpdateStatusBar("Call was shut down.",1,0);
    MessageBox(g_hDlgParentWindow,
        "Call was shut down.","Warning",MB_OK);
    HangupCall();
}


//
//  FUNCTION: DoLineDevState(..)
//
//  PURPOSE: Handle LINE_LINEDEVSTATE asynchronous messages.
//
//  PARAMETERS:
//    dwDevice  - Line Handle that was closed.
//    dwMsg     - Should always be LINE_LINEDEVSTATE.
//    dwCallbackInstance - Unused by this sample.
//    dwParam1  - LINEDEVSTATE constant.
//    dwParam2  - Depends on dwParam1.
//    dwParam3  - Depends on dwParam1.
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
//    The LINE_LINEDEVSTATE message is received if the state of the line
//    changes.  Examples are RINGING, MAINTENANCE, MSGWAITON.  Very few of
//    these are relevant to this sample.
//
//    Assuming that any LINEDEVSTATE that removes the line from use by TAPI
//    will also send a LINE_CLOSE message.
//
//

void DoLineDevState(
    DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
    DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
    switch(dwParam1)
    {
        case LINEDEVSTATE_RINGING:
            UpdateStatusBar("Line Ringing",1,0);
            OutputDebugString("Line Ringing.\n");
            break;

        case LINEDEVSTATE_REINIT:
        // This is an important case!  Usually means that a service provider
        // has changed in such a way that requires TAPI to REINIT.  
        // Note that there are both 'soft' REINITs and 'hard' REINITs.
        // Soft REINITs don't actually require a full shutdown but is instead
        // just an informational change that historically required a REINIT
        // to force the application to deal with.  TAPI API Version 1.3 apps
        // will still need to do a full REINIT for both hard and soft REINITs.

            switch(dwParam2)
            {
                // This is the hard REINIT.  No reason given, just REINIT.
                // TAPI is waiting for everyone to shutdown.
                // Our response is to immediately shutdown any calls,
                // shutdown our use of TAPI and notify the user.
                case 0:
                    ShutdownTAPI();
                    WarningBox("Tapi line configuration has changed.");
                    break;

                case LINE_CREATE:
                    OutputDebugString("Soft REINIT: LINE_CREATE.\n");
                    DoLineCreate(dwDevice, dwParam2, dwCallbackInstance,
                        dwParam3, 0, 0);
                    break;

                case LINE_LINEDEVSTATE:
                    OutputDebugString("Soft REINIT: LINE_LINEDEVSTATE.\n");
                    DoLineDevState(dwDevice, dwParam2, dwCallbackInstance,
                        dwParam3, 0, 0);
                    break;

                // There might be other reasons to send a soft reinit.
                // No need to to shutdown for these.
                default:
                    OutputDebugString("Ignoring soft REINIT\n");
                    break;
            }
            break;

        case LINEDEVSTATE_OUTOFSERVICE:
            WarningBox("Line selected is now Out of Service.");
            HangupCall();
            break;

        case LINEDEVSTATE_DISCONNECTED:
            WarningBox("Line selected is now disconnected.");
            HangupCall();
            break;

        case LINEDEVSTATE_MAINTENANCE:
            WarningBox("Line selected is now out for maintenance.");
            HangupCall();
            break;

        case LINEDEVSTATE_TRANSLATECHANGE:
            if (g_hDialog)
                PostMessage(g_hDialog, WM_COMMAND, IDC_CONFIGURATIONCHANGED, 0);
            break;

        case LINEDEVSTATE_REMOVED:
            OutputDebugString("A Line device has been removed;"
                " no action taken.\n");
            break;

        default:
            OutputDebugString("Unhandled LINEDEVSTATE message\n");
    }
}


//
//  FUNCTION: DoLineCreate(..)
//
//  PURPOSE: Handle LINE_LINECREATE asynchronous messages.
//
//  PARAMETERS:
//    dwDevice  - Unused.
//    dwMsg     - Should always be LINE_CREATE.
//    dwCallbackInstance - Unused.
//    dwParam1  - dwDeviceID of new Line created.
//    dwParam2  - Unused.
//    dwParam3  - Unused.
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
//    This message is new for Windows 95.  It is sent when a new line is
//    added to the system.  This allows us to handle new lines without having
//    to REINIT.  This allows for much more graceful Plug and Play.
//
//    This sample just changes the number of devices available and can use
//    it next time a call is made.  It also tells the "Dial" dialog.
//
//

void DoLineCreate(
    DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
    DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
    // dwParam1 is the Device ID of the new line.  
    // Add one to get the number of total devices.
    if (g_dwNumDevs <= dwParam1)
        g_dwNumDevs = dwParam1+1;
    if (g_hDialog)
        PostMessage(g_hDialog, WM_COMMAND, IDC_LINECREATE, 0);

}


//
//  FUNCTION: DoLineCallState(..)
//
//  PURPOSE: Handle LINE_CALLSTATE asynchronous messages.
//
//  PARAMETERS:
//    dwDevice  - Handle to Call who's state is changing.
//    dwMsg     - Should always be LINE_CALLSTATE.
//    dwCallbackInstance - Unused by this sample.
//    dwParam1  - LINECALLSTATE constant specifying state change.
//    dwParam2  - Specific to dwParam1.
//    dwParam3  - LINECALLPRIVILEGE change, if any.
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
//    This message is received whenever a call changes state.  Lots of
//    things we do, ranging from notifying the user to closing the line
//    to actually connecting to the target of our phone call.
//
//    What we do is usually obvious based on the call state change.
//

void DoLineCallState(
    DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
    DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{

    // Error if this CALLSTATE doesn't apply to our call in progress.
    if ((HCALL) dwDevice != g_hCall)
    {
        OutputDebugPrintf("LINE_CALLSTATE: Unknown device ID '0x%lx'.",
            dwDevice);
        return;
    }

    // This sets the global g_dwCallState variable so if we are waiting
    // for a specific call state change, we will know when it happens.
    g_dwCallState = dwParam1;
    g_bCallStateReceived = TRUE;

    // dwParam3 contains changes to LINECALLPRIVILEGE, if there are any.
    switch (dwParam3)
    {
        case 0:
            break; // no change to call state

         // close line if we are made monitor.  Shouldn't happen!
         case LINECALLPRIVILEGE_MONITOR:
            OutputDebugString("line given monitor privilege; closing\n");
            HangupCall();
            return;

         // close line if we are made owner.  Shouldn't happen!
        case LINECALLPRIVILEGE_OWNER:
            OutputDebugString("line given owner privilege; closing\n");
            HangupCall();
            break;

        default: // Shouldn't happen!  All cases handled.
            OutputDebugString("Unknown LINECALLPRIVILEGE message: closing\n");
            HangupCall();
            return;
    }

    // dwParam1 is the specific CALLSTATE change that is occurring.
    switch (dwParam1)
    {
        case LINECALLSTATE_DIALTONE:
            UpdateStatusBar("Dial Tone",1,0);
            OutputDebugString("Dial Tone\n");
            break;

        case LINECALLSTATE_DIALING:
            UpdateStatusBar("Dialing Call",1,0);
            OutputDebugString("Dialing\n");
            break;

        case LINECALLSTATE_PROCEEDING:
            UpdateStatusBar("Call is Proceeding",1,0);
            OutputDebugString("Proceeding\n");
            break;

        case LINECALLSTATE_RINGBACK:
            UpdateStatusBar("RingBack",1,0);
            OutputDebugString("RingBack\n");
            break;

        case LINECALLSTATE_BUSY:
            UpdateStatusBar("Line is busy",1,0);
            OutputDebugString("Line busy, shutting down\n");
            HangupCall();
            break;

        case LINECALLSTATE_IDLE:
            UpdateStatusBar("Line is idle",1,0);
            OutputDebugString("Line idle\n");
            HangupCall();
            break;

        case LINECALLSTATE_SPECIALINFO:
            UpdateStatusBar(
                "Special Info, probably couldn't dial number",1,0);
            OutputDebugString(
                "Special Info, probably couldn't dial number\n");
            HangupCall();
            break;

        case LINECALLSTATE_DISCONNECTED:
        {
            LPSTR pszReasonDisconnected;

            switch (dwParam2)
            {
                case LINEDISCONNECTMODE_NORMAL:
                    pszReasonDisconnected = "Remote Party Disconnected";
                    break;

                case LINEDISCONNECTMODE_UNKNOWN:
                    pszReasonDisconnected = "Disconnected: Unknown reason";
                    break;

                case LINEDISCONNECTMODE_REJECT:
                    pszReasonDisconnected = "Remote Party rejected call";
                    break;

                case LINEDISCONNECTMODE_PICKUP:
                    pszReasonDisconnected = 
                        "Disconnected: Local phone picked up";
                    break;

                case LINEDISCONNECTMODE_FORWARDED:
                    pszReasonDisconnected = "Disconnected: Forwarded";
                    break;

                case LINEDISCONNECTMODE_BUSY:
                    pszReasonDisconnected = "Disconnected: Busy";
                    break;

                case LINEDISCONNECTMODE_NOANSWER:
                    pszReasonDisconnected = "Disconnected: No Answer";
                    break;

                case LINEDISCONNECTMODE_BADADDRESS:
                    pszReasonDisconnected = "Disconnected: Bad Address";
                    break;

                case LINEDISCONNECTMODE_UNREACHABLE:
                    pszReasonDisconnected = "Disconnected: Unreachable";
                    break;

                case LINEDISCONNECTMODE_CONGESTION:
                    pszReasonDisconnected = "Disconnected: Congestion";
                    break;

                case LINEDISCONNECTMODE_INCOMPATIBLE:
                    pszReasonDisconnected = "Disconnected: Incompatible";
                    break;

                case LINEDISCONNECTMODE_UNAVAIL:
                    pszReasonDisconnected = "Disconnected: Unavail";
                    break;

                case LINEDISCONNECTMODE_NODIALTONE:
                    pszReasonDisconnected = "Disconnected: No Dial Tone";
                    break;

                default:
                    pszReasonDisconnected = 
                        "Disconnected: LINECALLSTATE; Bad Reason";
                    break;

            }

            UpdateStatusBar(pszReasonDisconnected,1,0);
            OutputDebugString(pszReasonDisconnected);
            OutputDebugString("\n");
            HangupCall();
            break;
        }

        
        case LINECALLSTATE_CONNECTED:  // CONNECTED!!!
        {
            LPVARSTRING lpVarString = NULL;
            DWORD dwSizeofVarString = sizeof(VARSTRING) + 1024;
            HANDLE hCommFile = NULL;
            long lReturn;

            // Very first, make sure this isn't a duplicated message.
            // A CALLSTATE message can be sent whenever there is a
            // change to the capabilities of a line, meaning that it is
            // possible to receive multiple CONNECTED messages per call.
            // The CONNECTED CALLSTATE message is the only one in TapiComm
            // where it would cause problems if it where sent more
            // than once.

            if (g_bConnected)
                break;

            g_bConnected = TRUE;

            // Get the handle to the comm port from the driver so we can start
            // communicating.  This is returned in a LPVARSTRING structure.
            do
      

⌨️ 快捷键说明

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