TAPIAPP.CPP
资源名称:tapi3.zip [点击查看]
上传用户:chinamans
上传日期:2013-03-17
资源大小:202k
文件大小:11k
源码类别:
TAPI编程
开发平台:
Visual C++
- // tapiapp.cpp : Defines the class behaviors for the TAPI application.
- // (c) Dialogic corp 1995, 1996
- #include "stdafx.h"
- #include <tapi.h>
- #include "tapiapp.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- //CMap<DWORD, DWORD, ASYNCCALL, ASYNCCALL&> g_cmAsyncCalls; // globally defined
- /////////////////////////////////////////////////////////////////////////////
- // CTapiApp
- BEGIN_MESSAGE_MAP(CTapiApp, CWinApp)
- //{{AFX_MSG_MAP(CTapiApp)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG
- ON_COMMAND(ID_HELP, CWinApp::OnHelp)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CTalkApp construction
- CTapiApp::CTapiApp()
- {
- // TODO: add construction code here,
- // Place all significant initialization in InitInstance
- m_hApp = NULL;
- m_dwLines = 0L;
- m_hAsyncListSem = NULL;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CTapiApp initialization
- BOOL CTapiApp::InitInstance()
- {
- // Standard initialization; MUST be called by the child class & return TRUE
- // if success; the child decides what to do after
- Enable3dControls();
- LoadStdProfileSettings(); // Load standard INI file options (including MRU)
- if(!InitTAPIApp()) // lineInit etc
- {
- MessageBox(NULL, "Failed to initialize TAPI", NULL, MB_ICONSTOP);
- return FALSE;
- }
- return TRUE;
- }
- int CTapiApp::ExitInstance()
- {
- CloseTAPIApp();
- return CWinApp::ExitInstance();
- }
- // Call lineInit
- BOOL CTapiApp::InitTAPIApp()
- {
- LONG lResult, i=0;
- while (LINEERR_REINIT == (lResult = lineInitialize(&m_hApp, m_hInstance,
- LineCallBackProc, "Talker32", &m_dwLines)))
- {
- Sleep(1000);
- i++;
- if(i > 10) return FALSE;
- }
- m_pAsyncList = new CMAPASYNC; // list of asynchronous calls
- if(lResult || m_pAsyncList == NULL) return FALSE;
- m_hAsyncListSem = CreateMutex(NULL, FALSE, "TALKER32_ASYNC_LIST");
- if(m_hAsyncListSem == NULL) return FALSE;
- return TRUE;
- }
- // MUST be protected
- void CTapiApp::SetAsyncID(DWORD dwID, WORD wState, WORD wFunc, LPVOID pvLine, LPVOID pvCall)
- {
- DWORD dwrc;
- PASYNCCALL pAsync = new ASYNCCALL;
- if(!pAsync) return;
- TRACE("*** TALKER32 ***: Set ID #%d entering wait for semn", dwID);
- dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
- if(dwrc != WAIT_OBJECT_0)
- {
- TRACE("*** TALKER32 ***: Set ID #%d wait for sem failed rc=%lxn", dwID, dwrc);
- return;
- }
- pAsync->dwID = dwID;
- pAsync->wState = wState;
- pAsync->wFunction = wFunc;
- pAsync->pvLine = pvLine;
- pAsync->pvCall = pvCall;
- m_pAsyncList->SetAt(pAsync->dwID, pAsync);
- TRACE("*** TALKER32 ***: Set ID #%d releasing mutexn", dwID);
- ReleaseMutex(m_hAsyncListSem);
- }
- // MUST be protected
- PASYNCCALL CTapiApp::FindAsyncID(DWORD dwID, WORD wAction)
- {
- PASYNCCALL pAsync = NULL;
- ASSERT(m_pAsyncList != NULL);
- TRACE("*** TALKER32 ***: %s ID #%d entering wait for semn", wAction==FIND_ID?"find":"remove",dwID);
- DWORD dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
- if(dwrc != WAIT_OBJECT_0)
- {
- TRACE("*** TALKER32 ***: Find async ID #%d wait for sem failed rc=%lxn",dwID, dwrc);
- return NULL;
- }
- if(m_pAsyncList->Lookup(dwID, pAsync))
- {
- if(wAction == REMOVE_ID)
- {
- m_pAsyncList->RemoveKey(dwID);
- delete pAsync;
- TRACE("*** TALKER32 ***: ID#%d releasing mutexn", dwID);
- ReleaseMutex(m_hAsyncListSem);
- return NULL;
- }
- }
- // if found, returns what found
- TRACE("*** TALKER32 ***: ID #%d releasing mutexn", dwID);
- ReleaseMutex(m_hAsyncListSem);
- return pAsync;
- }
- void CTapiApp::CloseTAPIApp()
- {
- lineShutdown(m_hApp);
- PurgeAsyncQue();
- CloseHandle(m_hAsyncListSem);
- m_hAsyncListSem = NULL;
- }
- // Delete the async requests queue; must be protected
- void CTapiApp::PurgeAsyncQue()
- {
- DWORD dwrc;
- if(m_pAsyncList != NULL)
- {
- TRACE("*** TALKER32 ***: Purge queue entering wait for semn");
- dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
- if(dwrc != WAIT_OBJECT_0)
- {
- TRACE("*** TALKER32 ***: Purge async queue wait for sem failed rc=%lxn", dwrc);
- return;
- }
- if(!m_pAsyncList->IsEmpty()) // list not empty, cleanup
- {
- PASYNCCALL pAsyncCall = NULL;
- DWORD dwID;
- int j;
- int nCount = m_pAsyncList->GetCount();
- POSITION pos = m_pAsyncList->GetStartPosition();
- for(j=0; j<nCount && pos != NULL; j++) // iterate thru list, delete all
- {
- m_pAsyncList->GetNextAssoc(pos, dwID, pAsyncCall);
- if(pAsyncCall) delete pAsyncCall;
- }
- }
- delete m_pAsyncList;
- m_pAsyncList = NULL;
- TRACE("*** TALKER32 ***: Purge queue releasing mutexn");
- ReleaseMutex(m_hAsyncListSem);
- }
- }
- void CTapiApp::OnLineReply(DWORD dwCallback, DWORD dwRequest, DWORD dwStatus)
- {
- // first, find the request
- 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
- FindAsyncID(dwRequest, REMOVE_ID); // Done, remove the ID from list
- }
- // get info on incoming call
- LPLINECALLINFO CTapiApp::GetCallInfo(HCALL hCall)
- {
- LPLINECALLINFO lpCallInfo = NULL;
- LONG lrc = 0;
- DWORD dwSize = sizeof(LINECALLINFO)+1000;
- DWORD i;
- // keep trying until buffer is big enough
- for (i=0; i<2; i++)
- {
- lpCallInfo = (LPLINECALLINFO) new char[dwSize];
- if (lpCallInfo == NULL)
- return NULL;
- lpCallInfo->dwTotalSize = dwSize;
- lrc = lineGetCallInfo(hCall,lpCallInfo);
- if(lrc < 0) goto FinishLineCallInfo;
- dwSize = lpCallInfo->dwNeededSize;
- if(dwSize <= lpCallInfo->dwTotalSize) break; // success
- delete (char *) lpCallInfo;
- }
- return lpCallInfo;
- FinishLineCallInfo:
- if (lpCallInfo != NULL)
- delete (LPBYTE) lpCallInfo;
- return NULL;
- }
- // get call status
- LPLINECALLSTATUS CTapiApp::GetCallStatus(HCALL hCall)
- {
- LPLINECALLSTATUS lpCallInfo = NULL;
- LONG lrc = 0;
- DWORD dwSize = sizeof(LINECALLSTATUS)+1000;
- DWORD i;
- // keep trying until buffer is big enough
- for (i=0; i<2; i++)
- {
- lpCallInfo = (LPLINECALLSTATUS) new char[dwSize];
- if (lpCallInfo == NULL)
- return NULL;
- lpCallInfo->dwTotalSize = dwSize;
- lrc = lineGetCallStatus(hCall,lpCallInfo);
- if(lrc < 0) goto FinishLineCallStatus;
- dwSize = lpCallInfo->dwNeededSize;
- if(dwSize <= lpCallInfo->dwTotalSize) break; // success
- delete (char *) lpCallInfo;
- }
- return lpCallInfo;
- FinishLineCallStatus:
- if (lpCallInfo != NULL)
- delete (LPBYTE) lpCallInfo;
- return NULL;
- }
- extern "C" {
- VOID WINAPI LineCallBackProc(DWORD hDevice, DWORD dwMsg,
- DWORD dwCallbackInstance, DWORD dwParam1, DWORD dwParam2,
- DWORD dwParam3)
- {
- // char szDigit[2]={0,0};
- TRACE("*** TALKER32 *** lineCallBack:Message=%ld,P1=%lx, P2=%lx, P3=%lxn",
- dwMsg, dwParam1,dwParam2,dwParam3);
- switch (dwMsg)
- {
- case LINE_LINEDEVSTATE:
- if (dwParam1 & LINEDEVSTATE_REINIT)
- {
- TRACE("*** TALKER32 *** :LINEDEVSTATE_REINITn");
- } // see DIALER
- if (dwParam1 & LINEDEVSTATE_TRANSLATECHANGE)
- {
- TRACE("*** TALKER32 *** :LINEDEVSTATE_TRANSLATECHANGEn");
- } // see DIALER
- if (dwParam1 & LINEDEVSTATE_CAPSCHANGE)
- {
- TRACE("*** TALKER32 *** :LINEDEVSTATE_CAPSCHANGEn");
- } // CAPSCHANGE, see DIALER
- if (dwParam1 & LINEDEVSTATE_REMOVED)
- { // treat removal like a request to close the line
- TRACE("*** TALKER32 *** :LINEDEVSTATE_REMOVEDn");
- } // REMOVED, see DIALER
- break;
- case LINE_ADDRESSSTATE:
- TRACE("*** TALKER32 *** :LINE_ADDRESSSTATEn");
- break; // see DIALER
- // process state transition
- case LINE_CALLSTATE:
- TRACE("*** TALKER32 *** :LINE_CALLSTATEn");
- ((CTapiApp *)AfxGetApp())->OnCallState((HCALL) hDevice, dwCallbackInstance, dwParam1,
- dwParam2, dwParam3);
- break; // see DIALER
- case LINE_CREATE:
- // a new line is created
- TRACE("*** TALKER32 *** :LINE_CREATEn");
- break;
- case LINE_CLOSE:
- // see if the closed line is the line on which we have an active call
- // if it is, do what would have been done if that call went idle
- // if not, see if it is a line for which we have a monitoring handle
- // if it is, mark that line as closed
- // if any calls are being monitored on that line, stop monitoring
- TRACE("*** TALKER32 *** :LINE_CLOSEn");
- break;
- // handle simple tapi request
- case LINE_REQUEST:
- TRACE("*** TALKER32 *** :LINE_REQUESTn");
- break;
- // handle the async completion of TAPI functions
- // lineMakeCall/lineDropCall/lineAnswer
- case LINE_REPLY:
- TRACE("*** TALKER32 *** :LINE_REPLYn");
- ((CTapiApp *)AfxGetApp())->OnLineReply(dwCallbackInstance, dwParam1, dwParam2); // virtual handler
- break;
- // other messages that can be processed
- case LINE_CALLINFO:
- TRACE("*** TALKER32 *** :LINE_CALLINFOn");
- ((CTapiApp *)AfxGetApp())->OnLineCallInfo((HCALL)hDevice, dwCallbackInstance, dwParam1);
- break;
- case LINE_DEVSPECIFIC:
- TRACE("*** TALKER32 *** :LINE_DEVSPECIFICn");
- ((CTapiApp *)AfxGetApp())->OnLineDevSpec(hDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
- break;
- case LINE_DEVSPECIFICFEATURE:
- TRACE("*** TALKER32 *** :LINE_DEVSPECIFICFEATUREn");
- break;
- case LINE_GATHERDIGITS:
- TRACE("*** TALKER32 *** :LINE_GATHERDIGITSn");
- ((CTapiApp *)AfxGetApp())->OnGatherDigits((HCALL)hDevice, dwCallbackInstance, dwParam1);
- break;
- case LINE_GENERATE:
- TRACE("*** TALKER32 *** :LINE_GENERATEn");
- break;
- case LINE_MONITORDIGITS:
- TRACE("*** TALKER32 *** :LINE_MONITORDIGITSn");
- ((CTapiApp *)AfxGetApp())->OnMonitorDigits((HCALL)hDevice, dwCallbackInstance, dwParam1, dwParam2);
- break;
- case LINE_MONITORMEDIA:
- TRACE("*** TALKER32 *** :LINE_MONITORMEDIAn");
- ((CTapiApp *)AfxGetApp())->OnMonitorMedia(hDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
- break;
- case LINE_MONITORTONE:
- TRACE("*** TALKER32 *** :LINE_MONITORTONEn");
- break;
- default:
- TRACE("*** TALKER32 *** :UNACCOUNTED LINE MESSAGEn");
- break;
- } /* switch */
- } // LineCallBackProc
- } // extern "C"