📄 tapiapp.cpp
字号:
// 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 sem\n", dwID);
dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
if(dwrc != WAIT_OBJECT_0)
{
TRACE("*** TALKER32 ***: Set ID #%d wait for sem failed rc=%lx\n", 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 mutex\n", 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 sem\n", 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=%lx\n",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 mutex\n", dwID);
ReleaseMutex(m_hAsyncListSem);
return NULL;
}
}
// if found, returns what found
TRACE("*** TALKER32 ***: ID #%d releasing mutex\n", 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 sem\n");
dwrc = WaitForSingleObject(m_hAsyncListSem, 15000);
if(dwrc != WAIT_OBJECT_0)
{
TRACE("*** TALKER32 ***: Purge async queue wait for sem failed rc=%lx\n", 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 mutex\n");
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=%lx\n",
dwMsg, dwParam1,dwParam2,dwParam3);
switch (dwMsg)
{
case LINE_LINEDEVSTATE:
if (dwParam1 & LINEDEVSTATE_REINIT)
{
TRACE("*** TALKER32 *** :LINEDEVSTATE_REINIT\n");
} // see DIALER
if (dwParam1 & LINEDEVSTATE_TRANSLATECHANGE)
{
TRACE("*** TALKER32 *** :LINEDEVSTATE_TRANSLATECHANGE\n");
} // see DIALER
if (dwParam1 & LINEDEVSTATE_CAPSCHANGE)
{
TRACE("*** TALKER32 *** :LINEDEVSTATE_CAPSCHANGE\n");
} // CAPSCHANGE, see DIALER
if (dwParam1 & LINEDEVSTATE_REMOVED)
{ // treat removal like a request to close the line
TRACE("*** TALKER32 *** :LINEDEVSTATE_REMOVED\n");
} // REMOVED, see DIALER
break;
case LINE_ADDRESSSTATE:
TRACE("*** TALKER32 *** :LINE_ADDRESSSTATE\n");
break; // see DIALER
// process state transition
case LINE_CALLSTATE:
TRACE("*** TALKER32 *** :LINE_CALLSTATE\n");
((CTapiApp *)AfxGetApp())->OnCallState((HCALL) hDevice, dwCallbackInstance, dwParam1,
dwParam2, dwParam3);
break; // see DIALER
case LINE_CREATE:
// a new line is created
TRACE("*** TALKER32 *** :LINE_CREATE\n");
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_CLOSE\n");
break;
// handle simple tapi request
case LINE_REQUEST:
TRACE("*** TALKER32 *** :LINE_REQUEST\n");
break;
// handle the async completion of TAPI functions
// lineMakeCall/lineDropCall/lineAnswer
case LINE_REPLY:
TRACE("*** TALKER32 *** :LINE_REPLY\n");
((CTapiApp *)AfxGetApp())->OnLineReply(dwCallbackInstance, dwParam1, dwParam2); // virtual handler
break;
// other messages that can be processed
case LINE_CALLINFO:
TRACE("*** TALKER32 *** :LINE_CALLINFO\n");
((CTapiApp *)AfxGetApp())->OnLineCallInfo((HCALL)hDevice, dwCallbackInstance, dwParam1);
break;
case LINE_DEVSPECIFIC:
TRACE("*** TALKER32 *** :LINE_DEVSPECIFIC\n");
((CTapiApp *)AfxGetApp())->OnLineDevSpec(hDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
break;
case LINE_DEVSPECIFICFEATURE:
TRACE("*** TALKER32 *** :LINE_DEVSPECIFICFEATURE\n");
break;
case LINE_GATHERDIGITS:
TRACE("*** TALKER32 *** :LINE_GATHERDIGITS\n");
((CTapiApp *)AfxGetApp())->OnGatherDigits((HCALL)hDevice, dwCallbackInstance, dwParam1);
break;
case LINE_GENERATE:
TRACE("*** TALKER32 *** :LINE_GENERATE\n");
break;
case LINE_MONITORDIGITS:
TRACE("*** TALKER32 *** :LINE_MONITORDIGITS\n");
((CTapiApp *)AfxGetApp())->OnMonitorDigits((HCALL)hDevice, dwCallbackInstance, dwParam1, dwParam2);
break;
case LINE_MONITORMEDIA:
TRACE("*** TALKER32 *** :LINE_MONITORMEDIA\n");
((CTapiApp *)AfxGetApp())->OnMonitorMedia(hDevice, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
break;
case LINE_MONITORTONE:
TRACE("*** TALKER32 *** :LINE_MONITORTONE\n");
break;
default:
TRACE("*** TALKER32 *** :UNACCOUNTED LINE MESSAGE\n");
break;
} /* switch */
} // LineCallBackProc
} // extern "C"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -