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

📄 acdclnt.c

📁 TAPI ACD Samples
💻 C
📖 第 1 页 / 共 4 页
字号:
//////////////////////////////////////////////////////////////////////////////
//
//  ACDCLNT.C
//
//  ACDClient app
//
//////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <tapi.h>
#include "acdclnt.h"
#include "resource.h"



//////////////////////////////////////////////////////////////////////////////
//  PROTOTYPES
//////////////////////////////////////////////////////////////////////////////
static BOOL CreateMainWindow (int nCmdShow);

static LRESULT CALLBACK MainWndProc (HWND   hwnd,
                                     UINT   uMsg,
                                     WPARAM wParam,
                                     LPARAM lParam);

LRESULT CALLBACK AgentStateDlgProc (HWND   hwnd,
                                    UINT   uMsg,
                                    WPARAM wParam,
                                    LPARAM lParam);

VOID CALLBACK LineCallback (DWORD hDevice,
                            DWORD dwMsg,
                            DWORD dwCallbackInstance, 
                            DWORD dwParam1,
                            DWORD dwParam2, 
                            DWORD dwParam3);
BOOL InitTapi();

BOOL CloseTapi();

BOOL RedoWindow();

BOOL SetStatusMessage(LPTSTR lpszMessage);

BOOL SetButton(DWORD dwAddress,
               BOOL bAnswer,
               BOOL bEnable);

LRESULT WaitForLineReply();

LONG ThreadRoutine(LPVOID lpv);

//////////////////////////////////////////////////////////////////////////////
//
//  GLOBALS
//
//////////////////////////////////////////////////////////////////////////////
HINSTANCE       ghInstance;                 // main instance
HWND            ghMainWnd;                  // main window
PADDRESSINFO    pAddressInfo = NULL;        // array of info about each address
HLINEAPP        ghLineApp;                  // hlineapp
DWORD           gdwAddresses;               // number of addresses on our line
DWORD           gdwDeviceID;                // our device
HLINE           ghLine;                     // our line

HANDLE          ghCompletionPort;           // tapi message completionport
CRITICAL_SECTION csLineReply;
   
// using global variables to keep track of line
// replies, since the main thread will only have at most one outstanding
// line reply at a time
BOOL            gbReply;
LONG            glResult;


//////////////////////////////////////////////////////////////////////////////
//
// WinMain()
//
//////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain (HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR     lpszCmdLine,
                    int       nCmdShow)
{
    MSG msg;

    ghInstance = hInstance;

    if(!InitTapi())
    {
        MessageBox(NULL,
                   TEXT("Failed to initialize TAPI"),
                   TEXT("Cannot start ACDClient"),
                   MB_OK);

        return 0;
    }

    if (!CreateMainWindow(nCmdShow))
    {
        return 0;
    }

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 1;
}


///////////////////////////////////////////////////////////////////////////////
//
// CreateMainWindow()
//
///////////////////////////////////////////////////////////////////////////////
BOOL CreateMainWindow (int nCmdShow)
{

    // main window
    ghMainWnd = CreateDialog(ghInstance,
                             MAKEINTRESOURCE(IDD_MAINDLG),
                             NULL,
                             MainWndProc);

    if (ghMainWnd == NULL)
    {
        return FALSE;
    }

    SetStatusMessage(TEXT("Waiting for call"));

    // create buttons
    RedoWindow();

    ShowWindow(ghMainWnd, nCmdShow);

    UpdateWindow(ghMainWnd);
    
    return TRUE;
}


/////////////////////////////////////////////////////////////////////////////////
//
//  BOOL SetStatusMessage(LPTSTR lpszMessage)
//
//  Sets text in the static control at the bottom of the main window to
//  lpszMessage
//
/////////////////////////////////////////////////////////////////////////////////
BOOL SetStatusMessage(LPTSTR lpszMessage)
{
    return (SetWindowText(GetDlgItem(ghMainWnd,
                                     IDC_STATIC1),
                          lpszMessage));

}


/////////////////////////////////////////////////////////////////////////////////
//
//  BOOL ClearCall(HCALL hCall)
//
//  Called when a CALLSTATE_IDLE message is recieved.  Looks for the call in the
//  global pAddressInfo array.  If it finds it, is clears the appropriate members
//  of the structure
//
/////////////////////////////////////////////////////////////////////////////////
BOOL ClearCall(HCALL hCall)
{
    DWORD       dwCount;

    for (dwCount = 0; dwCount < gdwAddresses; dwCount++)
    {
        if (pAddressInfo[dwCount].hCall == hCall)
        {
            pAddressInfo[dwCount].hCall = (HCALL)((DWORD_PTR)NULL);
            pAddressInfo[dwCount].bCall = FALSE;
            SetButton(dwCount,
                      TRUE,
                      FALSE);
            return TRUE;
        }
    }

    return FALSE;
}


//////////////////////////////////////////////////////////////////////////////////
//
//  BOOL SetButton()
//
//  Sets the status and text of the answer/drop button for a specific address
//
//////////////////////////////////////////////////////////////////////////////////
BOOL SetButton(DWORD dwAddress,
               BOOL bAnswer,
               BOOL bEnable)
{
    if (dwAddress >= gdwAddresses)
        return FALSE;
    
    if (bAnswer)
    {
        SetWindowText(pAddressInfo[dwAddress].hAnswer,
                      TEXT("Answer"));
    }
    else
    {
        SetWindowText(pAddressInfo[dwAddress].hAnswer,
                      TEXT("Hang Up"));
    }

    EnableWindow(pAddressInfo[dwAddress].hAnswer,
                 bEnable);

    return TRUE;
}



///////////////////////////////////////////////////////////////////////////////
//
//  VOID CALLBACK LineCallback ()
//
//  TAPI callback function.  Handles all tapi messages
//
///////////////////////////////////////////////////////////////////////////////
VOID CALLBACK LineCallback (DWORD hDevice,
                            DWORD dwMsg,
                            DWORD dwCallbackInstance, 
                            DWORD dwParam1,
                            DWORD dwParam2, 
                            DWORD dwParam3)
{
    LPLINECALLINFO          pLCI;
    LPLINECALLSTATUS        pLCS;
    TCHAR                   szBuffer[64];
    
    switch (dwMsg)
    {
        case LINE_REPLY:
        {
            EnterCriticalSection(&csLineReply);
            if (dwParam1 == (DWORD)glResult)
            {
                gbReply = TRUE;
                glResult = dwParam2;
            }
            LeaveCriticalSection(&csLineReply);
        }
        break;

        case LINE_CALLSTATE:
        {
            if (dwParam1 == LINECALLSTATE_OFFERING)
            {
                // get the call privilege
                // note note note the new LINE_APPNEWCALL
                // give call privilege
                pLCS = LineGetCallStatus((HCALL)hDevice);

                if (!pLCS)
                    return;

                if (!(pLCS->dwCallPrivilege & LINECALLPRIVILEGE_OWNER))
                {
                    // not our call
                    GlobalFree(pLCS);
                    return;
                }

                GlobalFree(pLCS);
                
                // we're getting offered a call
                // first get the address
                pLCI = LineGetCallInfo((HCALL)hDevice);

                if (!pLCI)
                {
                    // error
                    return;
                }

                // set the status message text
                wsprintf(szBuffer,
                         TEXT("Incoming call on address %lu"),
                         pLCI->dwAddressID);

                pAddressInfo[pLCI->dwAddressID].hCall = (HCALL)hDevice;
                
                SetStatusMessage(szBuffer);

                // set the button to answer
                SetButton(pLCI->dwAddressID,
                          TRUE,
                          TRUE);

                GlobalFree(pLCI);

                break;
            }

            if (dwParam1 == LINECALLSTATE_IDLE)
            {
                // see if we have this call
                ClearCall((HCALL)hDevice);
                // dealloc no matter what
                lineDeallocateCall((HCALL)hDevice);
                
                break;
            }
        }
        
        break;
    }
}


///////////////////////////////////////////////////////////////////////////////
//
//  BOOL GetAddressFromhWnd()
//
///////////////////////////////////////////////////////////////////////////////
BOOL GetAddressFromhWnd(HWND hWnd,
                        LPDWORD pdwAddress,
                        LPBOOL pbStatus)
{
    DWORD       dwAddress;

    // go through the array of addressinfo and see
    // if the hwnd matches
    for (dwAddress = 0; dwAddress < gdwAddresses; dwAddress++)
    {
        if (pAddressInfo[dwAddress].hStatus == hWnd)
        {
            *pdwAddress = dwAddress;
            *pbStatus = TRUE;

            return TRUE;
        }
        if (pAddressInfo[dwAddress].hAnswer == hWnd)
        {
            *pdwAddress = dwAddress;
            *pbStatus = FALSE;

            return TRUE;
        }
    }

    return FALSE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  BOOL DoLineAnswerDrop(DWORD dwAddress)
//
//  Handles what happens when the answer/drop button is pressed
//
/////////////////////////////////////////////////////////////////////////////
BOOL DoLineAnswerDrop(DWORD dwAddress)
{
    // if we have a call, then we want to drop it
    if (pAddressInfo[dwAddress].bCall)
    {

        SetStatusMessage(TEXT("Hanging up call ..."));

        EnterCriticalSection(&csLineReply);
        glResult = lineDrop(pAddressInfo[dwAddress].hCall,
                           NULL,
                           0);

        if (glResult < 0)
        {
            LeaveCriticalSection(&csLineReply);
            // error
        }

        else if (WaitForLineReply())
        {
            // error
        }

        // error or not, deallocate and set button
        lineDeallocateCall(pAddressInfo[dwAddress].hCall);
        
        SetButton(dwAddress,
                  TRUE,
                  FALSE);
        
        pAddressInfo[dwAddress].hCall = (HCALL)((DWORD_PTR)NULL);
        pAddressInfo[dwAddress].bCall = FALSE;
        
        SetStatusMessage(TEXT("Waiting for a call"));

    }
    else
    {
        BOOL bError = FALSE;

        
        // answer
        SetStatusMessage(TEXT("Answering call..."));

        EnterCriticalSection(&csLineReply);
        glResult = lineAnswer(pAddressInfo[dwAddress].hCall,
                             NULL,
                             0);

        if (glResult < 0)
        {
            LeaveCriticalSection(&csLineReply);
            bError = TRUE;
            //error
        }
        else if (WaitForLineReply())
        {
            bError = TRUE;
            // error
        }

        if (bError)
        {
            SetStatusMessage(TEXT("Hanging up call ..."));
            lineDeallocateCall(pAddressInfo[dwAddress].hCall);
            pAddressInfo[dwAddress].hCall = (HCALL)((DWORD_PTR)NULL);
            SetButton(dwAddress,
                      TRUE,
                      FALSE);

            SetStatusMessage(TEXT("Waiting for a call"));
            return FALSE;
        }

        SetStatusMessage(TEXT("On a call"));
        
        pAddressInfo[dwAddress].bCall = TRUE;

        SetButton(dwAddress,
                  FALSE,
                  TRUE);
    }
    
    return TRUE;
}

//////////////////////////////////////////////////////////////////////
//
//  LRESULT DoCommand(WPARAM wParam,
//                    LPARAM lParam)
//
//  Handles WM_COMMAND messages for the main window
//
//////////////////////////////////////////////////////////////////////
LRESULT DoCommand(WPARAM wParam,
                  LPARAM lParam)
{
    DWORD       dwAddress;
    BOOL        bStatus;

    // check to see if a button is being clicked
    if (HIWORD(wParam) == BN_CLICKED)
    {
        // check to see if it is a button we care about
        if (GetAddressFromhWnd((HWND)lParam,
                               &dwAddress,
                               &bStatus))
        {

            // if it's the status button, display the status
            // dialog
            if (bStatus)
            {
                DialogBoxParam(ghInstance,
                               MAKEINTRESOURCE(IDD_AGENTSTATE),
                               ghMainWnd,
                               AgentStateDlgProc,
                               (LPARAM)dwAddress);
            }
            // else it's the answer/drop button
            else
            {
                DoLineAnswerDrop(dwAddress);

⌨️ 快捷键说明

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