📄 tapiline.cpp
字号:
DWORD CallPrivilege,
DWORD MediaModes)
{
// Reset the line
ASSERT(m_hLine == 0);
m_hLine = 0;
// Safety checks.
ASSERT(hLineApp != 0);
ASSERT(ApiVersions != 0);
// Ask TAPI for a new line
HLINE hNewLine;
HRESULT tr = ::lineOpen(hLineApp, LineID,
&hNewLine, ApiVersions[LineID],
// 0, (DWORD)this, CallPrivilege, MediaModes, 0);
0, (DWORD)this, CallPrivilege, 6, 0);
CheckError(tr, "Open");
if (S_OK == tr)
{
// Use the results
m_hLine = hNewLine;
m_LineID = LineID;
ASSERT(m_hLine);
// Set all status messages
tr = ::lineSetStatusMessages(m_hLine, LINEDEVSTATE_ALL, LINEADDRESSSTATE_ALL);
CheckError(tr, "SetStatusMessages");
}
return tr;
}
// ----------------------------------------------------------------------------
// Handle messages from TAPI
void TAPILine::OnEvent(
DWORD Device,
DWORD Msg,
DWORD Param1,
DWORD Param2,
DWORD Param3)
{
switch (Msg)
{
case LINE_REPLY:
OnReply(Param1, Param2);
break;
case LINE_CLOSE:
OnClose();
break;
case LINE_ADDRESSSTATE:
ASSERT(m_hLine == (HLINE) Device);
OnAddressState(Param1, Param2);
break;
case LINE_CALLINFO:
OnCallInfo((HCALL) Device, Param1);
break;
case LINE_CALLSTATE:
OnCallState((HCALL) Device, Param1, Param2, Param3);
break;
case LINE_LINEDEVSTATE:
ASSERT(m_hLine == (HLINE) Device);
OnLineDevState(Param1, Param2, Param3);
break;
case LINE_APPNEWCALL: // TAPI v2.0
OnNewCall(Param1, (HCALL) Param2, Param3);
break;
case LINE_DEVSPECIFIC:
break;
case LINE_DEVSPECIFICFEATURE:
break;
case LINE_GATHERDIGITS:
break;
case LINE_GENERATE:
// AfxMessageBox("LINE_GENERATE");
break;
case LINE_MONITORDIGITS:
{
CString mess;
if (Param2 == LINEDIGITMODE_DTMFEND)
mess.Format("Digit Lift <%c> detected", (char) Param1);
else if (Param2 == LINEDIGITMODE_DTMF)
mess.Format("Digit Press <%c> detected", (char) Param1);
else
mess = ("LINE_MONITORDIGITS");
AfxMessageBox(mess);
break;
}
case LINE_MONITORMEDIA:
break;
case LINE_MONITORTONE:
if (Param1 == TEST_FOR_SILENCE)
AfxMessageBox("Test for silence detection successful.");
break;
case LINE_REQUEST:
break;
default:
ASSERT(FALSE);
break;
}
}
// ----------------------------------------------------------------------------
// Handle a LINE_REPLY message from TAPI
void TAPILine::OnReply(LONG RequestID, HRESULT Result)
{
CString info;
REQUEST_INFO ri = { "Unknown", 0 };
if (m_Requests.Lookup(RequestID, ri))
m_Requests.RemoveKey(RequestID);
if (Result == 0)
info.Format("Reply(%s: OK)", ri.Name);
else
{
// Describe the error message returned from TAPI
info.Format("Reply(%s: 0x%08lx = %s)", ri.Name,
Result, DescribeError(Result));
}
SendInfoMsg(info);
}
// ----------------------------------------------------------------------------
// Handle a LINE_CLOSE message from TAPI
void TAPILine::OnClose()
{
// This line (us) has been closed down
m_hLine = 0;
// Describe this event
CString info;
info.Format("Close()");
SendInfoMsg(info);
}
// ----------------------------------------------------------------------------
// Handle a LINE_ADDRESSSTATE message from TAPI
void TAPILine::OnAddressState(DWORD AddressID, DWORD AddressState)
{
CString state;
CString info;
info.Format("Address(%d, %s)", AddressID,
DescribeAddressStatus(state, AddressState));
SendInfoMsg(info);
// Get further information about the address change
LINEADDRESSSTATUS AddressStatus = { sizeof(LINEADDRESSSTATUS) };
HRESULT hr = ::lineGetAddressStatus(m_hLine, AddressID, &AddressStatus);
CheckError(hr, "GetAddressStatus");
info.Format("[NumInUse=%d, NumActiveCalls=%d, NumOnHoldCalls=%d, "
"NumOnHoldPendCalls=%d]",
AddressStatus.dwNumInUse, AddressStatus.dwNumActiveCalls,
AddressStatus.dwNumOnHoldCalls, AddressStatus.dwNumOnHoldPendCalls);
SendInfoMsg(info);
}
// ----------------------------------------------------------------------------
// Handle a LINE_CALLINFO message from TAPI
void TAPILine::OnCallInfo(HCALL hCall, DWORD CallInfoState)
{
CString state, which, info;
// Which call is this information about?
which.Format("%d/", hCall);
if (hCall == m_hConnectedCall) which += "Active";
else if (hCall == m_hWaitingCall) which += "Waiting";
else if (hCall == m_hHeldCall) which += "Held";
else if (hCall == m_hPendingCall) which += "Pending";
else if (hCall == m_hConferenceCall) which += "Conference";
else which += "Unknown";
// Put the information into the dialog box
info.Format("CallInfo(%s: %s)", LPCTSTR(which), DescribeCallInfo(state, CallInfoState));
SendInfoMsg(info);
// Get further information about the call info
CString s1, s2, Trunk, CallerID, CalledID;
LINECALLINFO* pCallInfo = NULL;
HRESULT hr = loopLineGetCallInfo(hCall, pCallInfo);
if (pCallInfo->dwTrunk == 0xffffffff)
Trunk = "Unknown";
else
Trunk.Format("%ld", pCallInfo->dwTrunk);
getTapiString(CallerID, pCallInfo, pCallInfo->dwCallerIDSize, pCallInfo->dwCallerIDOffset);
getTapiString(CalledID, pCallInfo, pCallInfo->dwCalledIDSize, pCallInfo->dwCalledIDOffset);
info.Format("[AddressID=%d, Origin=%s, Reason=%s, Trunk=%s, "
"CallerID=%s, CalledID=%s]",
pCallInfo->dwAddressID,
DescribeCallOrigin(s1, pCallInfo->dwOrigin),
DescribeCallReason(s2, pCallInfo->dwReason),
LPCTSTR(Trunk), LPCTSTR(CallerID), LPCTSTR(CalledID));
SendInfoMsg(info);
delete [] pCallInfo;
}
// ----------------------------------------------------------------------------
// Handle a LINE_CALLSTATE message from TAPI
void TAPILine::OnCallState(HCALL hCall, DWORD CallState, DWORD CallStateDetail, DWORD CallPrivilege)
{
CString info, which, s1, s2;
// Which call is this information about?
which.Format("%d/", hCall);
if (hCall == m_hConnectedCall) which += "Active";
else if (hCall == m_hWaitingCall) which += "Waiting";
else if (hCall == m_hHeldCall) which += "Held";
else if (hCall == m_hPendingCall) which += "Pending";
else if (hCall == m_hConferenceCall) which += "Conference";
else which += "Unknown";
// Describe the event to the dialog box
info.Format("CallState(%s: %s, %s, %s)",
LPCTSTR(which),
DescribeCallState(s1, CallState),
DescribeCallStateDetail(CallState, CallStateDetail),
DescribePrivilege(s2, CallPrivilege));
SendInfoMsg(info);
// Handle releasing resources when they go idle
// This is necessary to allow another call to be made!
/* if (CallState & LINECALLSTATE_DISCONNECTED)
HangUp();
else*/ if (CallState & LINECALLSTATE_IDLE)
{
HRESULT Result = ::lineDeallocateCall(hCall);
// Describe the error message returned from TAPI
if (Result)
{
info.Format("LineDeallocate(0x%08lx = %s)",
Result, DescribeError(Result));
SendInfoMsg(info);
}
else
{
if (hCall == m_hConnectedCall) m_hConnectedCall = 0;
else if (hCall == m_hWaitingCall) m_hWaitingCall = 0;
else if (hCall == m_hHeldCall) m_hHeldCall = 0;
else if (hCall == m_hPendingCall) m_hPendingCall = 0;
else if (hCall == m_hConferenceCall) m_hConferenceCall = 0;
}
}
// Has a call been answered / retrieved?
else if (CallState & LINECALLSTATE_CONNECTED)
{
if (hCall == m_hWaitingCall) m_hWaitingCall = 0;
if (hCall == m_hPendingCall) m_hPendingCall = 0;
if (hCall == m_hHeldCall) m_hHeldCall = 0;
if (hCall == m_hConferenceCall) m_hConferenceCall = 0;
m_hConnectedCall = hCall;
}
// Has a call been put on hold?
else if (CallState & (LINECALLSTATE_ONHOLDPENDTRANSFER | LINECALLSTATE_ONHOLD
| LINECALLSTATE_ONHOLDPENDCONF))
{
if (hCall == m_hConnectedCall) m_hConnectedCall = m_hHeldCall;
m_hHeldCall = hCall;
}
// Is a call proceeding?
else if (CallState & (LINECALLSTATE_DIALING | LINECALLSTATE_PROCEEDING))
{
m_hWaitingCall = hCall;
}
StatusChange();
}
// ----------------------------------------------------------------------------
// Handle a LINE_APPNEWCALL message from TAPI
void TAPILine::OnNewCall(DWORD AddressID, HCALL hCall, DWORD CallPrivilege)
{
// We can answer this if we want
m_hPendingCall = hCall;
StatusChange();
// Mention the new call
CString info, s1;
info.Format("NewCall(%d, %s)", AddressID, DescribePrivilege(s1, CallPrivilege));
SendInfoMsg(info);
LINECALLINFO CallInfo;
CallInfo.dwTotalSize = sizeof(LINECALLINFO);
lineGetCallInfo(hCall, &CallInfo);
// Get further information about the address change
LINEADDRESSSTATUS AddressStatus = { sizeof(LINEADDRESSSTATUS) };
HRESULT hr = ::lineGetAddressStatus(m_hLine, AddressID, &AddressStatus);
CheckError(hr, "GetAddressStatus");
info.Format("[NumInUse=%d, NumActiveCalls=%d, NumOnHoldCalls=%d, "
"NumOnHoldPendCalls=%d]",
AddressStatus.dwNumInUse, AddressStatus.dwNumActiveCalls,
AddressStatus.dwNumOnHoldCalls, AddressStatus.dwNumOnHoldPendCalls);
SendInfoMsg(info);
}
// ----------------------------------------------------------------------------
// Handle a LINE_LINEDEVSTATE message from TAPI
void TAPILine::OnLineDevState(DWORD DeviceState, DWORD DeviceStateDetail1, DWORD DeviceStateDetail2)
{
CString state;
CString info;
info.Format("DeviceState(%s, %d, %d)",
DescribeDeviceStatus(state, DeviceState),
DeviceStateDetail1, DeviceStateDetail2);
SendInfoMsg(info);
}
// ----------------------------------------------------------------------------
// Note an immediate error message
void TAPILine::CheckError(HRESULT hr, LPCTSTR pszCommand)
{
if (hr < 0)
{
CString info;
info.Format("Error(%s:0x%lx)", pszCommand, hr);
SendInfoMsg(info);
}
}
// ----------------------------------------------------------------------------
// Tell parent that a info/error message is pending.
void TAPILine::SendInfoMsg(LPCTSTR pszCommand)
{
// Store info and SendMessage to parent which will be actioned synchronuslyouly
if (m_pTAPIConnection)
{
m_pTAPIConnection->SendInfoMsg(pszCommand);
}
}
// ----------------------------------------------------------------------------
// Tell parent that the line status has changed.
void TAPILine::StatusChange()
{
// Store info and SendMessage to parent which will be actioned synchronuslyouly
if (m_pTAPIConnection)
m_pTAPIConnection->StatusChange();
// CheckButtons()
}
// ----------------------------------------------------------------------------
// Queried first/default extension on this line.
void TAPILine::SetDefaultExt(LPCTSTR pszExt)
{
this->m_strDefaultExt = pszExt;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -