TALKER32.CPP
资源名称:tapi3.zip [点击查看]
上传用户:chinamans
上传日期:2013-03-17
资源大小:202k
文件大小:18k
源码类别:
TAPI编程
开发平台:
Visual C++
- // talker32.cpp : Defines the class behaviors for the application.
- // (c) Dialogic corp 1995, 1996
- #include "stdafx.h"
- #include <tapi.h>
- #include "tapiapp.h"
- #include "tapiline.h"
- #include "tapicall.h"
- #include "talker32.h"
- #include "talkdlg.h"
- #include "helpid.h"
- #include "devspec.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CTalkApp
- BEGIN_MESSAGE_MAP(CTalkApp, CTapiApp)
- //{{AFX_MSG_MAP(CTalkApp)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- ON_COMMAND(ID_HELP, OnHelp)
- //}}AFX_MSG
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CTalkApp construction
- CTalkApp::CTalkApp()
- {
- m_dwTapiAlert = 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- // The one and only CTalkApp object
- CTalkApp theApp;
- /////////////////////////////////////////////////////////////////////////////
- // CTalkApp initialization
- BOOL CTalkApp::InitInstance()
- {
- DWORD i, dwrc;
- CString csTemp, csAA;
- if(!CTapiApp::InitInstance()) // failed to initialize
- return FALSE;
- memset((PBYTE)m_ctlLines, 0, sizeof(m_ctlLines));
- CStatusBox sbDlg;
- sbDlg.m_csStatus = "Initializing TAPI...";
- sbDlg.Create(IDD_STATUSDLG);
- if(m_dwLines > MAXLINES)
- {
- AfxMessageBox("This program supports up to 16 lines", MB_ICONEXCLAMATION);
- m_dwLines = MAXLINES;
- }
- // Read optional info
- memset((LPBYTE)m_wLineOptions, 0, sizeof(m_wLineOptions));
- SetRegistryKey("Dialogic\SystemRelease 4.x");
- for(i = 0; i < m_dwLines; i++)
- {
- dwrc = 0L;
- if(NULL == (m_ctlLines[i] = new CTapiLine(i))) //constructor dn open the line
- MessageBox(NULL, "Failed to get Cline", NULL, MB_OK);
- else dwrc = m_ctlLines[i]->ctlLineOpen(i);
- if(dwrc)
- {
- char szErr[48];
- if(!Code2Error(dwrc, szErr, 46))
- csTemp.Format("Failed to open line %d reason=%lx", i, dwrc);
- else
- csTemp.Format("Failed to open line %d, reason=%s", i, szErr);
- MessageBox(NULL, (LPCTSTR)csTemp, NULL, MB_ICONSTOP);
- }
- else sbDlg.m_csStatus.Format("Line %d opened", i);
- sbDlg.UpdateData(FALSE);
- csTemp.Format("Line%d", i);
- csAA = GetProfileString((LPCTSTR)csTemp, "AutoAnswer", "");
- if(!csAA.IsEmpty()) // Default mode is no autoanswer
- {
- csAA.MakeUpper();
- if((-1 != csAA.Find("YES")) || (-1 != csAA.Find("ON")))
- m_wLineOptions[i] |= AUTOANSWER; // set bit
- }
- csAA = GetProfileString((LPCTSTR)csTemp, "AutoPlay", "");
- if(!csAA.IsEmpty()) // Default mode is no autoplay
- {
- csAA.MakeUpper();
- if((-1 != csAA.Find("YES")) || (-1 != csAA.Find("ON")))
- m_wLineOptions[i] |= AUTOPLAY; // set bit
- }
- }
- sbDlg.DestroyWindow();
- CTalkDlg dlg;
- m_pMainWnd = &dlg;
- int nResponse = dlg.DoModal();
- if (nResponse == IDOK)
- {
- // TODO: Place code here to handle when the dialog is
- // dismissed with OK
- }
- else if (nResponse == IDCANCEL)
- {
- // TODO: Place code here to handle when the dialog is
- // dismissed with Cancel
- }
- // Since the dialog has been closed, return FALSE so that we exit the
- // application, rather than start the application's message pump.
- return FALSE;
- }
- // Check for active calls, close them properly; called from the front end before shutting down the app
- void CTalkApp::Cleanup()
- {
- DWORD i;
- for(i=0; i<m_dwLines; i++)
- m_ctlLines[i]->ctlLineDrop();
- }
- // close the lines; if there are active calls shut them
- int CTalkApp::ExitInstance()
- {
- DWORD i;
- for(i=0; i<m_dwLines; i++)
- {
- if(m_ctlLines[i])
- delete m_ctlLines[i];
- }
- return CTapiApp::ExitInstance();
- }
- // Get CTapiLine by hLine
- CTapiLine * CTalkApp::GetLineByHLine(HLINE hLine)
- {
- DWORD i;
- for(i=0; i < m_dwLines; i++)
- {
- if(m_ctlLines[i] && m_ctlLines[i]->ctlGetHLine() == hLine)
- {
- return m_ctlLines[i];
- }
- }
- return NULL;
- }
- // Get CTapiLine by hcall
- CTapiLine * CTalkApp::GetLineByCall(HCALL hCall)
- {
- LPLINECALLINFO lpLCI = GetCallInfo(hCall);
- if(lpLCI == NULL) return NULL; // failed for some reason
- // implement additional logic here to search thru inactive calls
- CTapiLine *pLine = GetLineByHLine(lpLCI->hLine);
- delete (LPBYTE) lpLCI;
- return pLine;
- }
- // Find pCall by specified parameter
- LPVOID CTalkApp::GetCallByParm(WORD wKey, DWORD dwValue)
- {
- DWORD i;
- CTapiCall *pCall;
- for(i=0; i< m_dwLines; i++)
- {
- if(NULL == m_ctlLines[i] || (NULL == (pCall = m_ctlLines[i]->ctlGetActiveCall()))) continue;
- switch(wKey)
- {
- case KEY_LINE:
- if(m_ctlLines[i] == (CTapiLine *)dwValue) return (LPVOID)pCall;
- break;
- case KEY_WAVEINHANDLE:
- if(NULL != dwValue && pCall->GetHWaveIn() == dwValue)
- return (LPVOID)pCall;
- break;
- case KEY_WAVEOUTHANDLE:
- if(NULL != dwValue && pCall->GetHWaveOut() == dwValue)
- return (LPVOID)pCall;
- break;
- default:
- break;
- }
- }
- return NULL; // not found
- }
- // override of CTapiApp implementation
- void CTalkApp::OnLineReply(DWORD dwCallback, DWORD dwRequest, DWORD dwStatus)
- {
- // first, find the request
- TRACE("*** TALKER32 *** :enter OnReply ID=%lx Status=%lxn", dwRequest, dwStatus);
- PASYNCCALL pAC = FindAsyncID(dwRequest, FIND_ID);
- if(pAC == NULL) // not found for some reason (???)
- {
- TRACE1("*** TALKER32 *** :Request ID=%lx not found!n", dwRequest);
- return;
- }
- ASSERT(pAC->dwID == dwRequest); // sanity check
- CTapiLine *pCurLine = (CTapiLine *) pAC->pvLine;
- switch (pAC->wFunction)
- {
- case FUNCTION_MAKECALL:
- if(dwStatus & 0x80000000) // makecall failed, try to drop
- {
- TRACE("*** TALKER32 *** :MakeCall ID=%lx failed, err=%lxn", dwRequest, dwStatus);
- // notify the line, let it find out what to do
- }
- pCurLine->ctlUpdateCallStatus(pAC->wFunction, dwStatus, (CTapiCall *)(pAC->pvCall));
- break;
- case FUNCTION_DROP:
- if(dwStatus & 0x80000000) // drop failed
- TRACE("*** TALKER32 *** :Drop ID=%lx failed, err=%lxn", dwRequest, dwStatus);
- // notify the line, let it find out what to do
- pCurLine->ctlUpdateCallStatus(pAC->wFunction, dwStatus, (CTapiCall *)(pAC->pvCall));
- break;
- case FUNCTION_ANSWER:
- // Answer succeeded?...
- if(dwStatus & 0x80000000) // answer failed
- TRACE("*** TALKER32 *** :Answer ID=%lx failed, err=%lxn", dwRequest, dwStatus);
- pCurLine->ctlUpdateCallStatus(pAC->wFunction, dwStatus, (CTapiCall *)(pAC->pvCall));
- break;
- case FUNCTION_DIAL:
- if(dwStatus & 0x80000000) // answer failed
- TRACE("*** TALKER32 *** :Dial ID=%lx failed, err=%lxn", dwRequest, dwStatus);
- pCurLine->ctlUpdateCallStatus(pAC->wFunction, dwStatus, (CTapiCall *)(pAC->pvCall));
- break;
- case FUNCTION_DEVSPEC: // device specific...
- if(dwStatus & 0x80000000)
- TRACE("*** TALKER32 *** :Devspec ID=%lx failed, err=%lxn", dwRequest, dwStatus);
- pCurLine->ctlUpdateCallStatus(pAC->wFunction, dwStatus, (CTapiCall *)(pAC->pvCall));
- break;
- default:
- TRACE("*** TALKER32 ***: Undefined async function calln");
- break;
- } // end of switch(wFunction)
- TRACE("*** TALKER32 *** :exit OnReply ID=%lxn", dwRequest);
- FindAsyncID(dwRequest, REMOVE_ID); // Done, remove the ID from list
- }
- // Override of CTapiApp OnLineCallInfo implementation
- void CTalkApp::OnLineCallInfo(HCALL hCall, DWORD dwCallBack, DWORD dwParm)
- {
- BOOL brc, bFound = FALSE;
- DWORD i;
- LPLINECALLINFO lpCI = GetCallInfo(hCall);
- TRACE("*** TALKER32 *** :OnLineCallinfo hCall=%lx, DevID=%dn",
- hCall, lpCI->dwLineDeviceID);
- if(lpCI == NULL) return;
- for(i=0; i < m_dwLines; i++)
- {
- if(m_ctlLines[i] && m_ctlLines[i]->ctlGetHLine() == lpCI->hLine)
- {
- bFound = TRUE;
- break;
- }
- }
- if(bFound) brc = m_ctlLines[i]->ctlUpdateCallInfo(hCall, lpCI);
- if(!bFound || (bFound && brc == FALSE)) delete lpCI;
- }
- // Override of CTapiApp OnCallState implementation
- void CTalkApp::OnCallState(HCALL hCall, DWORD hCallback, DWORD dwCallState,
- DWORD dwCallStateDetail, DWORD dwCallPrivilege)
- {
- // May issue lineGetCallStatus here to get info
- CString csTemp;
- DWORD dwDiscMode;
- LONG lrc;
- TRACE("*** TALKER32 *** :OnLineCallState hCall=%lx, state=%lx, detail=%lxn",
- hCall, dwCallState, dwCallStateDetail);
- CTapiLine *pclTemp = GetLineByCall(hCall);
- if(pclTemp == NULL) // line not found
- {
- TRACE("*** TALKER32 ***: OnCallState failed to find linen");
- return;
- }
- CTapiCall *pCall = pclTemp->ctlGetActiveCall();
- if(pCall == NULL && dwCallState != LINECALLSTATE_OFFERING
- && dwCallState != LINECALLSTATE_ACCEPTED ) // call not found - probably offering
- {
- TRACE("*** TALKER32 ***: OnCallState failed to find calln");
- return;
- }
- switch(dwCallState)
- {
- case LINECALLSTATE_DIALING:
- case LINECALLSTATE_DIALTONE:
- case LINECALLSTATE_PROCEEDING:
- // not clear what to do if this collides w/Drop -so do nothing
- TRACE("*** TALKER32 ***: Callstate = %sn", dwCallState==LINECALLSTATE_DIALTONE ? "Dialtone" :
- dwCallState==LINECALLSTATE_DIALING ? "Dialing" : "Proceeding");
- // pCall->UpdateCallState(CONNECTED, 0xffff, dwCallState);
- NotifyFrontEnd(pclTemp->ctlGetLineID());
- break;
- case LINECALLSTATE_OFFERING:
- case LINECALLSTATE_ACCEPTED:
- TRACE("*** TALKER32 ***: Callstate = %sn", dwCallState==LINECALLSTATE_OFFERING ? "Offering" : "Accepted");
- if(pCall)
- {
- TRACE("*** TALKER32 ***: Cannot answer, another call is active on this linen");
- csTemp.Format("Cannot answer call on line %d, another call still activen", pclTemp->ctlGetLineID());
- m_pMainWnd->MessageBox(csTemp);
- }
- else if(pclTemp != NULL)
- pclTemp->ctlOfferCall(hCall); // line allocates call & alerts front end
- break;
- case LINECALLSTATE_CONNECTED:
- TRACE("*** TALKER32 ***: Callstate = Connectedn");
- pCall->UpdateCallState(CONNECTED, 0xffff, dwCallState);
- m_wLineOptions[pclTemp->ctlGetLineID()] |= PLAY_ONCE;
- NotifyFrontEnd(pclTemp->ctlGetLineID());
- break;
- case LINECALLSTATE_DISCONNECTED:
- case LINECALLSTATE_SPECIALINFO:
- case LINECALLSTATE_BUSY:
- if (dwCallState == LINECALLSTATE_DISCONNECTED)
- TRACE("*** TALKER32 ***: Callstate = Disconnected, reason=%lxn", dwCallStateDetail);
- else if (dwCallState == LINECALLSTATE_BUSY)
- TRACE("*** TALKER32 ***: Callstate = BUSY, mode = %lxn", dwCallStateDetail);
- else if (dwCallState == LINECALLSTATE_SPECIALINFO)
- TRACE("*** TALKER32 ***: Callstate = SPECIALINFO, mode = %lxn", dwCallStateDetail);
- dwDiscMode = dwCallStateDetail;
- if (dwDiscMode == 0) dwDiscMode = LINEDISCONNECTMODE_NORMAL;
- pCall->UpdateCallState(DISCONNECTED, 0xffff, dwCallState);
- /* fCallOK = (discMode == LINEDISCONNECTMODE_NORMAL
- || discMode == LINEDISCONNECTMODE_UNKNOWN
- || discMode == LINEDISCONNECTMODE_PICKUP
- || discMode == LINEDISCONNECTMODE_FORWARDED
- || discMode == LINEDISCONNECTMODE_UNAVAIL);
- */
- lrc = pclTemp->ctlLineDrop(pCall); // which will notify front end
- if(lrc <0)
- TRACE("*** TALKER32 ***: lineDrop failed rc = %lxn", lrc);
- break;
- case LINECALLSTATE_IDLE:
- TRACE("*** TALKER32 ***: Callstate IDLE for hcall=%lxn", hCall);
- pCall->UpdateCallState(IDLE, IDLE, dwCallState);
- pclTemp->ctlLineDeallocateCall(pCall);
- break;
- default:
- break;
- } // switch CALLSTATE
- }
- // LINE_MONITORDIGITS processor
- void CTalkApp::OnMonitorDigits(HCALL hCall, DWORD dwCallBack, DWORD dwDigit, DWORD dwDigitMode)
- {
- TRACE("***: OnMonitorDigits digit = %lxn", dwDigit);
- CTapiLine *pclTemp = GetLineByCall(hCall);
- if(pclTemp == NULL) // line not found
- {
- TRACE("*** TALKER32 ***: OnMonitorDigits failed to find linen");
- return;
- }
- CTapiCall *pCall = pclTemp->ctlGetActiveCall();
- if(pCall == NULL)
- {
- TRACE("*** TALKER32 ***: OnMonitorDigits failed to find calln");
- return;
- }
- pCall->UpdateMonitorState(MONITOR_DIGITS, dwDigit, dwDigitMode); // new status
- pCall->NotifyCallWindow((UINT)dwDigit, (LONG)dwDigitMode); // post a message that status has changed
- }
- // LINE_GATHERDIGITS processor
- void CTalkApp::OnGatherDigits(HCALL hCall, DWORD dwCallBack, DWORD dwTermination)
- {
- CString csTemp;
- CTapiLine *pclTemp = GetLineByCall(hCall);
- TRACE("***: OnGatherDigits term = %lxn", dwTermination);
- if(pclTemp == NULL) // line not found
- {
- TRACE("*** TALKER32 ***: OnGatherDigits failed to find linen");
- return;
- }
- CTapiCall *pCall = pclTemp->ctlGetActiveCall();
- if(pCall == NULL)
- {
- TRACE("*** TALKER32 ***: OnGatherDigits failed to find calln");
- return;
- }
- pCall->UpdateMonitorState(END_GATHER_DIGITS, dwTermination, 0L); // new status
- // pCall->NotifyCallWindow(); // post a message that status has changed
- pCall->NotifyCallWindow(0, (LONG)dwTermination); // post a message that status has changed
- }
- // Process LINE_MONITORMEDIA callback
- void CTalkApp::OnMonitorMedia(DWORD hCall, DWORD dwCallBack, DWORD dwParm1, DWORD dwParm2, DWORD dwParm3)
- {
- // This is a temp workaround until MS fixes remotesp.tsp to process Devspecific & Generate events
- if(dwParm1) return;
- switch(dwParm2)
- {
- case PLAY_WAVE:
- case RECORD_WAVE:
- OnLineDevSpec(hCall, dwCallBack, dwParm2, dwParm3==55 ? 0 : dwParm3, 1111);
- return;
- default:
- return;
- }
- }
- // Process LINE_DEVSPECIFIC callback
- void CTalkApp::OnLineDevSpec(DWORD hCall, DWORD dwCallBack, DWORD dwParm1, DWORD dwParm2, DWORD dwParm3)
- {
- // the action depends on the meaning of parm1
- if(dwParm1 != PLAY_WAVE && dwParm1 != RECORD_WAVE) return;
- CTapiLine *pLine = (dwParm3 == 1111 ? GetLineByCall((HCALL) hCall) :
- GetLineByHLine((HLINE)hCall));
- if(pLine)
- pLine->ctlUpdateDevSpecStatus(dwParm2 ? DEVSPEC_RESULTFAILED : DEVSPEC_IDLE);
- }
- // translate code into verbal call state
- BOOL CTalkApp::Code2CallState(DWORD dwState, LPSTR lpBuf, int nSize)
- {
- BOOL brc = TRUE;
- switch(dwState)
- {
- case LINECALLSTATE_IDLE:
- strncpy(lpBuf, "LINECALLSTATE_IDLE", nSize);
- break;
- case LINECALLSTATE_OFFERING:
- strncpy(lpBuf, "LINECALLSTATE_OFFERING", nSize);
- break;
- case LINECALLSTATE_ACCEPTED:
- strncpy(lpBuf, "LINECALLSTATE_ACCEPTED", nSize);
- break;
- case LINECALLSTATE_DIALTONE:
- strncpy(lpBuf, "LINECALLSTATE_DIALTONE", nSize);
- break;
- case LINECALLSTATE_DIALING:
- strncpy(lpBuf, "LINECALLSTATE_DIALING", nSize);
- break;
- case LINECALLSTATE_RINGBACK:
- strncpy(lpBuf, "LINECALLSTATE_RINGBACK", nSize);
- break;
- case LINECALLSTATE_BUSY:
- strncpy(lpBuf, "LINECALLSTATE_BUSY", nSize);
- break;
- case LINECALLSTATE_SPECIALINFO:
- strncpy(lpBuf, "LINECALLSTATE_SPECIALINFO", nSize);
- break;
- case LINECALLSTATE_CONNECTED:
- strncpy(lpBuf, "LINECALLSTATE_CONNECTED", nSize);
- break;
- case LINECALLSTATE_PROCEEDING:
- strncpy(lpBuf, "LINECALLSTATE_PROCEEDING", nSize);
- break;
- case LINECALLSTATE_ONHOLD:
- strncpy(lpBuf, "LINECALLSTATE_ONHOLD", nSize);
- break;
- case LINECALLSTATE_DISCONNECTED:
- strncpy(lpBuf, "LINECALLSTATE_DISCONNECTED", nSize);
- break;
- case LINECALLSTATE_UNKNOWN:
- strncpy(lpBuf, "LINECALLSTATE_UNKNOWN", nSize);
- break;
- case LINECALLSTATE_ONHOLDPENDTRANSFER:
- strncpy(lpBuf, "LINECALLSTATE_ONHOLDPENDTRANSFER", nSize);
- break;
- default:
- brc = FALSE; // not found
- break;
- }
- return brc;
- }
- BOOL CTalkApp::Code2Error(DWORD dwErr, LPSTR lpBuf, int nSize)
- {
- BOOL brc = TRUE;
- switch(dwErr)
- {
- case LINEERR_BADDEVICEID:
- strncpy(lpBuf, "LINEERR_BADDEVICEID", nSize);
- break;
- case LINEERR_INCOMPATIBLEAPIVERSION:
- strncpy(lpBuf, "LINEERR_INCOMPATIBLEAPIVERSION", nSize);
- break;
- case LINEERR_INCOMPATIBLEEXTVERSION:
- strncpy(lpBuf, "LINEERR_INCOMPATIBLEEXTVERSION", nSize);
- break;
- case LINEERR_INUSE:
- strncpy(lpBuf, "LINEERR_INUSE", nSize);
- break;
- case LINEERR_INVALCALLHANDLE:
- strncpy(lpBuf, "LINEERR_INVALCALLHANDLE", nSize);
- break;
- case LINEERR_INVALCALLPRIVILEGE:
- strncpy(lpBuf, "LINEERR_INVALCALLPRIVILEGE", nSize);
- break;
- case LINEERR_INVALCALLSTATE:
- strncpy(lpBuf, "LINEERR_INVALCALLSTATE", nSize);
- break;
- case LINEERR_INVALMEDIAMODE:
- strncpy(lpBuf, "LINEERR_INVALMEDIAMODE", nSize);
- break;
- case LINEERR_INVALPARAM:
- strncpy(lpBuf, "LINEERR_INVALPARAM", nSize);
- break;
- case LINEERR_INVALPOINTER:
- strncpy(lpBuf, "LINEERR_INVALPOINTER", nSize);
- break;
- case LINEERR_OPERATIONFAILED:
- strncpy(lpBuf, "LINEERR_OPERATIONFAILED", nSize);
- break;
- case LINEERR_OPERATIONUNAVAIL:
- strncpy(lpBuf, "LINEERR_OPERATIONUNAVAIL", nSize);
- break;
- default:
- brc = FALSE; // not found
- break;
- }
- return brc;
- }
- void CTalkApp::OnHelp()
- {
- // if(m_pMainWnd->GetSafeHwnd() == ::GetActiveWindow())
- // WinHelp(HIDD_TALKER32_DialogMain, HELP_CONTEXT);
- // else
- // WinHelp(HIDD_TALKER32_DialogLineInfo, HELP_CONTEXT);
- WinHelp(m_nHelpId, HELP_CONTEXT);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CStatusBox dialog
- CStatusBox::CStatusBox(CWnd* pParent /*=NULL*/)
- : CDialog(CStatusBox::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CStatusBox)
- m_csStatus = _T("");
- //}}AFX_DATA_INIT
- }
- void CStatusBox::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CStatusBox)
- DDX_Text(pDX, IDC_STATUS, m_csStatus);
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CStatusBox, CDialog)
- //{{AFX_MSG_MAP(CStatusBox)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CStatusBox message handlers
- BOOL CStatusBox::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // TODO: Add extra initialization here
- return TRUE; // return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
- }