📄 tapiutils.cpp
字号:
break;
case LINE_CLOSE:
// Line has been shut down.
ASSERT(MyThis);
MyThis->m_hLine = NULL;
MyThis->m_hCall = NULL;
MyThis->HangupCall(); // all handles invalidated by this time
break;
case LINE_REPLY:
if ((long) dwParam2 != SUCCESS)
OutputDebugString("LINE_REPLY error\n");
else
OutputDebugString("LINE_REPLY: successfully replied.\n");
break;
case LINE_CREATE:
ASSERT(MyThis);
if (MyThis->m_dwNumDevs <= dwParam1)
MyThis->m_dwNumDevs = dwParam1+1;
break;
default:
OutputDebugString("lineCallbackFunc message ignored\n");
break;
}
return;
}
//
// FUNCTION: HandleLineCallState(..)
//
// PURPOSE: Handle LINE_CALLSTATE asynchronous messages.
//
void CTapiConnection::HandleLineCallState(
DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
{
// Error if this CALLSTATE doesn't apply to our call in progress.
if ((HCALL) dwDevice != m_hCall)
{
OutputDebugString("LINE_CALLSTATE: Unknown device ID ");
return;
}
// dwParam1 is the specific CALLSTATE change that is occurring.
switch (dwParam1)
{
case LINECALLSTATE_DIALTONE:
OutputDebugString("Dial Tone\n");
break;
case LINECALLSTATE_DIALING:
OutputDebugString("Dialing\n");
break;
case LINECALLSTATE_PROCEEDING:
OutputDebugString("Proceeding\n");
break;
case LINECALLSTATE_RINGBACK:
OutputDebugString("RingBack\n");
break;
case LINECALLSTATE_BUSY:
OutputDebugString("Line busy, shutting down\n");
HangupCall();
break;
case LINECALLSTATE_IDLE:
OutputDebugString("Line idle\n");
HangupCall();
break;
case LINECALLSTATE_SPECIALINFO:
OutputDebugString("Special Info, probably couldn't dial number\n");
HangupCall();
break;
case LINECALLSTATE_DISCONNECTED:
{
LPSTR pszReasonDisconnected;
switch (dwParam2)
{
case LINEDISCONNECTMODE_NORMAL:
pszReasonDisconnected = "Remote Party Disconnected";
break;
case LINEDISCONNECTMODE_UNKNOWN:
pszReasonDisconnected = "Disconnected: Unknown reason";
break;
case LINEDISCONNECTMODE_REJECT:
pszReasonDisconnected = "Remote Party rejected call";
break;
case LINEDISCONNECTMODE_PICKUP:
pszReasonDisconnected =
"Disconnected: Local phone picked up";
break;
case LINEDISCONNECTMODE_FORWARDED:
pszReasonDisconnected = "Disconnected: Forwarded";
break;
case LINEDISCONNECTMODE_BUSY:
pszReasonDisconnected = "Disconnected: Busy";
break;
case LINEDISCONNECTMODE_NOANSWER:
pszReasonDisconnected = "Disconnected: No Answer";
break;
case LINEDISCONNECTMODE_BADADDRESS:
pszReasonDisconnected = "Disconnected: Bad Address";
break;
case LINEDISCONNECTMODE_UNREACHABLE:
pszReasonDisconnected = "Disconnected: Unreachable";
break;
case LINEDISCONNECTMODE_CONGESTION:
pszReasonDisconnected = "Disconnected: Congestion";
break;
case LINEDISCONNECTMODE_INCOMPATIBLE:
pszReasonDisconnected = "Disconnected: Incompatible";
break;
case LINEDISCONNECTMODE_UNAVAIL:
pszReasonDisconnected = "Disconnected: Unavail";
break;
case LINEDISCONNECTMODE_NODIALTONE:
pszReasonDisconnected = "Disconnected: No Dial Tone";
break;
default:
pszReasonDisconnected =
"Disconnected: LINECALLSTATE; Bad Reason";
break;
}
OutputDebugString(pszReasonDisconnected);
OutputDebugString("\n");
HangupCall();
break;
}
case LINECALLSTATE_CONNECTED: // CONNECTED!!!
OutputDebugString("Connected!\n");
break;
default:
OutputDebugString("Unhandled LINECALLSTATE message\n");
break;
}
}
//
// FUNCTION: HandleLineErr(long)
//
// PURPOSE: Handle several of the standard LINEERR errors
//
BOOL CTapiConnection::HandleLineErr(long lLineErr)
{
BOOL bRet = FALSE;
// lLineErr is really an async request ID, not an error.
if (lLineErr > SUCCESS)
return bRet;
// All we do is dispatch the correct error handler.
switch(lLineErr)
{
case SUCCESS:
bRet = TRUE;
break;
case LINEERR_INVALCARD:
case LINEERR_INVALLOCATION:
case LINEERR_INIFILECORRUPT:
OutputDebugString("The values in the INI file are invalid.\n");
break;
case LINEERR_NODRIVER:
OutputDebugString("There is a problem with your Telephony device driver.\n");
break;
case LINEERR_REINIT:
ShutdownTAPI();
break;
case LINEERR_NOMULTIPLEINSTANCE:
OutputDebugString("Remove one of your copies of your Telephony driver.\n");
break;
case LINEERR_NOMEM:
OutputDebugString("Out of memory. Cancelling action.\n");
break;
case LINEERR_OPERATIONFAILED:
OutputDebugString("The TAPI operation failed.\n");
break;
case LINEERR_RESOURCEUNAVAIL:
OutputDebugString("A TAPI resource is unavailable at this time.\n");
break;
// Unhandled errors fail.
default:
break;
}
return bRet;
}
//
// FUNCTION: BOOL HangupCall()
//
// PURPOSE: Hangup the call in progress if it exists.
//
BOOL CTapiConnection::HangupCall()
{
LPLINECALLSTATUS pLineCallStatus = NULL;
long lReturn;
// Prevent HangupCall re-entrancy problems.
if (m_bStoppingCall)
return TRUE;
// If Tapi is not being used right now, then the call is hung up.
if (!m_bTapiInUse)
return TRUE;
m_bStoppingCall = TRUE;
OutputDebugString("Stopping Call in progress\n");
// If there is a call in progress, drop and deallocate it.
if (m_hCall)
{
pLineCallStatus = (LPLINECALLSTATUS)malloc(sizeof(LINECALLSTATUS));
if (!pLineCallStatus)
{
ShutdownTAPI();
m_bStoppingCall = FALSE;
return FALSE;
}
lReturn = ::lineGetCallStatus(m_hCall, pLineCallStatus);
// Only drop the call when the line is not IDLE.
if (!((pLineCallStatus -> dwCallState) & LINECALLSTATE_IDLE))
{
WaitForReply(lineDrop(m_hCall, NULL, 0));
OutputDebugString("Call Dropped.\n");
}
// The call is now idle. Deallocate it!
do
{
lReturn = ::lineDeallocateCall(m_hCall);
if (HandleLineErr(lReturn))
continue;
else
{
OutputDebugString("lineDeallocateCall unhandled error\n");
break;
}
}
while(lReturn != SUCCESS);
OutputDebugString("Call Deallocated.\n");
}
// if we have a line open, close it.
if (m_hLine)
{
lReturn = ::lineClose(m_hLine);
if (!HandleLineErr(lReturn))
OutputDebugString("lineClose unhandled error\n");
OutputDebugString("Line Closed.\n");
}
// Clean up.
m_hCall = NULL;
m_hLine = NULL;
m_bTapiInUse = FALSE;
m_bStoppingCall = FALSE; // allow HangupCall to be called again.
// Need to free buffer returned from lineGetCallStatus
if (pLineCallStatus)
free(pLineCallStatus);
OutputDebugString("Call stopped\n");
return TRUE;
}
//
// FUNCTION: BOOL ShutdownTAPI()
//
// PURPOSE: Shuts down all use of TAPI
//
BOOL CTapiConnection::ShutdownTAPI()
{
long lReturn;
// If we aren't initialized, then Shutdown is unnecessary.
if (m_hLineApp == NULL)
return TRUE;
// Prevent ShutdownTAPI re-entrancy problems.
if (m_bShuttingDown)
return TRUE;
m_bShuttingDown = TRUE;
HangupCall();
do
{
lReturn = ::lineShutdown(m_hLineApp);
if (HandleLineErr(lReturn))
continue;
else
{
OutputDebugString("lineShutdown unhandled error\n");
break;
}
}
while(lReturn != SUCCESS);
m_bTapiInUse = FALSE;
m_hLineApp = NULL;
m_hCall = NULL;
m_hLine = NULL;
m_bShuttingDown = FALSE;
OutputDebugString("TAPI uninitialized.\n");
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -