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

📄 tapicode.c

📁 一份有用的TAPI编程源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (HandleLineErr(lReturn))
            continue;
        else
        {
            OutputDebugLineError(lReturn, 
                "lineInitialize unhandled error: ");
            g_bInitializing = FALSE;
            return FALSE;
        }
    }
    while(lReturn != SUCCESS);

    // if hWndParent is a valid hWnd, we keep it as the parent for
    // all dialogs.
    if (IsWindow(hWndParent))
    {
        g_hDlgParentWindow = g_hWndMainWindow = hWndParent;
    }
    else
    {
        // Has the old g_hWndMainWindow gone away?
        if (!IsWindow(g_hWndMainWindow))
        {
            OutputDebugString("Main window unavailable.\n");
            g_hDlgParentWindow = g_hWndMainWindow = NULL;
        }
    }

    g_hCall = (HCALL)((ULONG_PTR)NULL);
    g_hLine = (HLINE)((ULONG_PTR)NULL);

    OutputDebugString("Tapi initialized.\n");
    g_bInitializing = FALSE;
    return TRUE;
}


//
//  FUNCTION: BOOL ShutdownTAPI()
//
//  PURPOSE: Shuts down all use of TAPI
//
//  PARAMETERS:
//    None
//
//  RETURN VALUE:
//    True if TAPI successfully shut down.
//
//  COMMENTS:
//
//    If ShutdownTAPI fails, then its likely either a problem
//    with the service provider (and might require a system
//    reboot to correct) or the application ran out of memory.
//
//

BOOL ShutdownTAPI()
{
    long lReturn;

    // If we aren't initialized, then Shutdown is unnecessary.
    if (g_hLineApp == (HLINE)((ULONG_PTR)NULL))
        return TRUE;

    // Prevent ShutdownTAPI re-entrancy problems.
    if (g_bShuttingDown)
        return TRUE;

    g_bShuttingDown = TRUE;

    HangupCall();
    
    do
    {
        lReturn = lineShutdown(g_hLineApp);
        if (HandleLineErr(lReturn))
            continue;
        else
        {
            OutputDebugLineError(lReturn, "lineShutdown unhandled error: ");
            break;
        }
    }
    while(lReturn != SUCCESS);

    g_bTapiInUse = FALSE;
    g_bConnected = FALSE;
    g_hLineApp = (HLINE)((ULONG_PTR)NULL);
    g_hCall = (HCALL)((ULONG_PTR)NULL);
    g_hLine = (HLINE)((ULONG_PTR)NULL);
    g_bShuttingDown = FALSE;
    OutputDebugString("TAPI uninitialized.\n");
    return TRUE;
}



//
//  FUNCTION: BOOL HangupCall()
//
//  PURPOSE: Hangup the call in progress if it exists.
//
//  PARAMETERS:
//    none
//
//  RETURN VALUE:
//    TRUE if call hung up successfully.
//
//  COMMENTS:
//
//    If HangupCall fails, then its likely either a problem
//    with the service provider (and might require a system
//    reboot to correct) or the application ran out of memory.
//
//

BOOL HangupCall()
{         
    LPLINECALLSTATUS pLineCallStatus = NULL;
    long lReturn;

    // Prevent HangupCall re-entrancy problems.
    if (g_bStoppingCall)
        return TRUE;

    // if the 'Call' dialog is up, dismiss it.
    if (g_hDialog)
        PostMessage(g_hDialog, WM_COMMAND, IDCANCEL, 0);

    // If Tapi is not being used right now, then the call is hung up.
    if (!g_bTapiInUse)
        return TRUE;

    g_bStoppingCall = TRUE;
    OutputDebugString("Stopping Call in progress\n");

    // Disable the 'hangup call' user interface.
    EnableHangupCall(g_hWndMainWindow, FALSE);

    // Stop any data communications on the comm port.
    StopComm();

    // If there is a call in progress, drop and deallocate it.
    if (g_hCall)
    {
        // I_lineGetCallStatus returns a LocalAlloc()d buffer
        pLineCallStatus = I_lineGetCallStatus(pLineCallStatus, g_hCall);
        if (pLineCallStatus == NULL)
        {
            ShutdownTAPI();
            g_bStoppingCall = FALSE;
            return FALSE;
        }

        // Only drop the call when the line is not IDLE.
        if (!((pLineCallStatus -> dwCallState) & LINECALLSTATE_IDLE))
        {
            do
            {
                lReturn = WaitForReply(lineDrop(g_hCall, NULL, 0));

                if (lReturn == WAITERR_WAITTIMEDOUT)
                {
                    OutputDebugString("Call timed out in WaitForReply.\n");
                    break;
                }

                if (lReturn == WAITERR_WAITABORTED)
                {
                    OutputDebugString("lineDrop: WAITERR_WAITABORTED.\n");
                    break;
                }

                // Was the call already in IDLE?
                if (lReturn == LINEERR_INVALCALLSTATE)
                    break;

                if (HandleLineErr(lReturn))
                    continue;
                else
                {
                    OutputDebugLineError(lReturn, 
                        "lineDrop unhandled error: ");
                    break;
                }
            }
            while(lReturn != SUCCESS);

            // Wait for the dropped call to go IDLE before continuing.
            lReturn = WaitForCallState(LINECALLSTATE_IDLE);

            if (lReturn == WAITERR_WAITTIMEDOUT)
                OutputDebugString("Call timed out waiting for IDLE state.\n");

            if (lReturn == WAITERR_WAITABORTED)
                OutputDebugString(
                    "WAITERR_WAITABORTED while waiting for IDLE state.\n");

            OutputDebugString("Call Dropped.\n");
        }

        // The call is now idle.  Deallocate it!
        do
        {
            lReturn = lineDeallocateCall(g_hCall);
            if (HandleLineErr(lReturn))
                continue;
            else
            {
                OutputDebugLineError(lReturn,
                    "lineDeallocateCall unhandled error: ");
                break;
            }
        }
        while(lReturn != SUCCESS);
            
        OutputDebugString("Call Deallocated.\n");
    }


    // if we have a line open, close it.
    if (g_hLine)
    {
        do
        {
            lReturn = lineClose(g_hLine);
            if (HandleLineErr(lReturn))
                continue;
            else
            {
                OutputDebugLineError(lReturn, 
                    "lineClose unhandled error: ");
                break;
            }
        }
        while(lReturn != SUCCESS);
        
        OutputDebugString("Line Closed.\n");
    }

    // Call and Line are taken care of.  Finish cleaning up.

    // If there is device configuration information, free the memory.
    if (g_lpDeviceConfig)
        LocalFree(g_lpDeviceConfig);
    g_lpDeviceConfig = NULL;

    g_hCall = (HCALL)((ULONG_PTR)NULL);
    g_hLine = (HLINE)((ULONG_PTR)NULL);
    g_bConnected = FALSE;

    g_bTapiInUse = FALSE;
    g_bStoppingCall = FALSE; // allow HangupCall to be called again.
    OutputDebugString("Call stopped\n");

    // Update the user interface.
    UpdateStatusBar("Ready to make a call.",1,0);
    EnableMakeCall(g_hWndMainWindow, TRUE);

    // Need to free LocalAlloc()d buffer returned from I_lineGetCallStatus
    if (pLineCallStatus)
        LocalFree(pLineCallStatus);  
        
    return TRUE;
}


//
//  FUNCTION: PostHangupCall()
//
//  PURPOSE: Posts a message to the main TAPI thread to hangup the call.
//
//  PARAMETERS:
//    none
//
//  RETURN VALUE:
//    none
//
//  COMMENTS:
//
//    TAPI is thread specific, meaning that only the thread that does the
//    lineInitialize can get asynchronous messages through the callback.
//    Since the HangupCall can potentially go into a loop waiting for 
//    specific events, any other threads that call HangupCall can cause
//    timing confusion.  Best to just have other threads 'ask' the main thread
//    to hangup the call.
//

void PostHangupCall()
{
    PostMessage(g_hWndMainWindow, WM_COMMAND, IDM_HANGUPCALL, 0);
}



//
//  FUNCTION: DialCall()
//
//  PURPOSE: Get a number from the user and dial it.
//
//  PARAMETERS:
//    none
//
//  RETURN VALUE:
//    TRUE if able to get a number, find a line, and dial successfully.
//
//  COMMENTS:
//
//    This function makes several assumptions:
//    - The number dialed will always explicitly come from the user.
//    - There will only be one outgoing address per line.
//

BOOL DialCall()
{
    long lReturn;
    LPLINEADDRESSSTATUS lpLineAddressStatus = NULL;
    LPLINEDEVCAPS lpLineDevCaps = NULL;

    if (g_bTapiInUse)
    {
        OutputDebugString("A call is already being handled\n");
        return FALSE;
    }

    // If TAPI isn't initialized, its either because we couldn't initialize
    // at startup (and this might have been corrected by now), or because
    // a REINIT event was received.  In either case, try to init now.

    if (!g_hLineApp)
    {
        if (!InitializeTAPI(NULL))
            return FALSE;
    }

    // If there are no line devices installed on the machine, lets give
    // the user the opportunity to install one.
    if (g_dwNumDevs < 1)
    {
        if (!HandleNoDevicesInstalled())
            return FALSE;
    }

    // We now have a call active.  Prevent future calls.
    g_bTapiInUse = TRUE;
    EnableMakeCall(g_hWndMainWindow, FALSE);


    // Get a phone number from the user.
    // Phone number will be placed in global variables if successful
    if (!GetAddressToDial())
    {
        HangupCall();
        goto DeleteBuffers;
    }

    // Negotiate the API version to use for this device.
    g_dwAPIVersion = I_lineNegotiateAPIVersion(g_dwDeviceID);
    if (g_dwAPIVersion == 0)
    {
        MessageBox(g_hDlgParentWindow,
            "Line Version unsupported by this Sample",
            "Unable to Use Line",MB_OK);
        HangupCall();
        goto DeleteBuffers;
    }

    // Need to check the DevCaps to make sure this line is usable.
    // The 'Dial' dialog checks also, but better safe than sorry.
    lpLineDevCaps = I_lineGetDevCaps(lpLineDevCaps,
        g_dwDeviceID, g_dwAPIVersion);
    if (lpLineDevCaps == NULL)
    {
        HangupCall();
        MessageBox(g_hDlgParentWindow,
            "Error on Requested line",
            "Unable to Use Line",MB_OK);
        goto DeleteBuffers;
    }

    if (!(lpLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE ))
    {
        HangupCall();
        MessageBox(g_hDlgParentWindow,
            "Error on Requested line",
            "The selected line doesn't support VOICE capabilities",
            MB_OK);
        goto DeleteBuffers;
    }

    if (!(lpLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM))
    {
        HangupCall();
        MessageBox(g_hDlgParentWindow,
            "Error on Requested line",
            "The selected line doesn't support DATAMODEM capabilities",
            MB_OK);
        goto DeleteBuffers;
    }

    // Does this line have the capability to make calls?
    // It is possible that some lines can't make outbound calls.

⌨️ 快捷键说明

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