📄 tapiline.cpp
字号:
else
m_Parent.m_Dlg.AddText("Error(UnholdCall: No Held Call)");
}
// ----------------------------------------------------------------------------
// Conference the current call with the call on hold - only works if call
// is currently connected and there is a call on hold.
void TapiLine::ConferenceCall()
{
if (m_hConnectedCall && m_hHeldCall)
{
HRESULT tr = ::lineCompleteTransfer(m_hHeldCall, m_hConnectedCall, &m_hConferenceCall,
LINETRANSFERMODE_CONFERENCE);
if (tr > 0)
{
REQUEST_INFO ri = { "ConferenceCall", m_hConferenceCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "ConferenceCall");
if (m_hConferenceCall == 0)
m_Parent.m_Dlg.AddText("Error(ConferenceCall: No Conference Call Handle returned)");
}
else
{
if (!m_hConnectedCall)
m_Parent.m_Dlg.AddText("Error(ConferenceCall: No Active Call)");
if (!m_hHeldCall)
m_Parent.m_Dlg.AddText("Error(ConferenceCall: No Held Call)");
}
}
// ----------------------------------------------------------------------------
// Transfer the call on hold to the current call
// - only works if call is currently connected
void TapiLine::BlindTransferCall(LPCTSTR pszAddress)
{
if (m_hConnectedCall)
{
HRESULT tr = ::lineBlindTransfer(m_hConnectedCall, pszAddress, 0);
if (tr > 0)
{
REQUEST_INFO ri = { "BlindTransferCall", m_hConnectedCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "BlindTransferCall");
}
else
m_Parent.m_Dlg.AddText("Error(BlindTransferCall: No Active Call)");
}
// ----------------------------------------------------------------------------
// If the current call is connected, then lineSetupTransfer will put the call
// on hold and create a new consultation call. If the current call is already
// on hold, then lineSetupTransfer will just create a new consultation call.
void TapiLine::SetupTransfer()
{
if (m_hConnectedCall)
{
HRESULT tr = ::lineSetupTransfer(m_hConnectedCall, &m_hConsultationCall, 0);
if (tr > 0)
{
REQUEST_INFO ri = { "SetupTransfer", m_hConnectedCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "SetupTransfer");
}
else if (m_hHeldCall)
{
HRESULT tr = ::lineSetupTransfer(m_hHeldCall, &m_hConsultationCall, 0);
if (tr > 0)
{
REQUEST_INFO ri = { "SetupTransfer", m_hHeldCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "SetupTransfer");
}
else
m_Parent.m_Dlg.AddText("Error(lineSetupTransfer: No Active or Held Call)");
}
// ----------------------------------------------------------------------------
// Dial will dial the given number on the currently active call, where the call
// has been created using lineSetupTransfer.
void TapiLine::Dial(LPCTSTR pszAddress)
{
if (!m_hHeldCall)
m_Parent.m_Dlg.AddText("Error(lineSetupTransfer: No Held Call)");
else if (!m_hConsultationCall)
m_Parent.m_Dlg.AddText("Error(lineSetupTransfer: No Consultation Call)");
else
{
HRESULT tr = ::lineDial(m_hConsultationCall, pszAddress, 0);
if (tr > 0)
{
REQUEST_INFO ri = { "Dial", m_hConnectedCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "Dial");
}
}
// ----------------------------------------------------------------------------
// CompleteTransfer will transfer the held call to the currently connected call
void TapiLine::CompleteTransfer()
{
if (!m_hHeldCall)
m_Parent.m_Dlg.AddText("Error(lineCompleteTransfer: No Held Call)");
else
if (!m_hConsultationCall)
{
if(!m_hConnectedCall)
{
m_Parent.m_Dlg.AddText("Error(lineSetupTransfer: No Consultation Call)");
return;
}
else m_hConsultationCall = m_hConnectedCall;
}
HRESULT tr = ::lineCompleteTransfer(m_hHeldCall, m_hConsultationCall, NULL, LINETRANSFERMODE_TRANSFER);
if (tr > 0)
{
REQUEST_INFO ri = { "CompleteTransfer", m_hConnectedCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "CompleteTransfer");
}
// ----------------------------------------------------------------------------
// SwapHold puts the currently active call on hold and retrieves the held call.
void TapiLine::SwapHold()
{
if (!m_hHeldCall)
m_Parent.m_Dlg.AddText("Error(lineSwapHold: No Held Call)");
else if (!m_hConnectedCall)
m_Parent.m_Dlg.AddText("Error(lineSwapHold: No Active Call)");
else
{
HRESULT tr = ::lineSwapHold(m_hConnectedCall, m_hHeldCall);
if (tr > 0)
{
REQUEST_INFO ri = { "SwapHold", m_hConnectedCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "SwapHold");
}
}
// ----------------------------------------------------------------------------
// Park will park a call. Note that only a directed park will succeed on
// IP Office
void TapiLine::Park(LPCTSTR pszAddress)
{
if (!m_hConnectedCall)
m_Parent.m_Dlg.AddText("Error(linePark: No Active Call)");
else
{
HRESULT tr = 0;
if (pszAddress)
tr = ::linePark(m_hConnectedCall, LINEPARKMODE_DIRECTED, pszAddress, NULL);
else
{
DWORD size = 512;
VARSTRING* pAddress = (VARSTRING*) new char[size]; // This should be big enough
ZeroMemory(&pAddress[0], size);
pAddress->dwTotalSize = size;
tr = ::linePark(m_hConnectedCall, LINEPARKMODE_NONDIRECTED, NULL, pAddress);
}
if (tr > 0)
{
REQUEST_INFO ri = { "Park", m_hConnectedCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "Park");
}
}
// ----------------------------------------------------------------------------
// Unpark retrieves a parked call from the given park address
void TapiLine::Unpark(LPCTSTR pszAddress)
{
HRESULT tr = ::lineUnpark(m_hLine, 0, &m_hConnectedCall, pszAddress);
if (tr > 0)
{
REQUEST_INFO ri = { "Unpark", m_hConnectedCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "Unpark");
}
// ----------------------------------------------------------------------------
// This function redirects an alerting call to the given extension
void TapiLine::Redirect(LPCTSTR pszAddress)
{
if (!m_hPendingCall)
m_Parent.m_Dlg.AddText("Error(linePark: No Offering Call)");
else
{
HRESULT tr = ::lineRedirect(m_hPendingCall, pszAddress, 0);
if (tr > 0)
{
REQUEST_INFO ri = { "Redirect", m_hPendingCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "Redirect");
}
}
// ----------------------------------------------------------------------------
// AddToConference adds the connected call to a held conference
void TapiLine::AddToConference()
{
if (m_hConnectedCall && m_hHeldCall)//m_hConferenceCall)
{
HRESULT tr = ::lineAddToConference(m_hHeldCall/*m_hConferenceCall*/, m_hConnectedCall);
if (tr > 0)
{
REQUEST_INFO ri = { "AddToConference", m_hConferenceCall };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "AddToConference");
m_hLastCallIntoConf = m_hConnectedCall;
}
else
{
if (!m_hConnectedCall)
m_Parent.m_Dlg.AddText("Error(lineAddToConference: No Active Call)");
if (!m_hConferenceCall)
m_Parent.m_Dlg.AddText("Error(lineAddToConference: No Conference Call)");
}
}
// ----------------------------------------------------------------------------
// RemoveFromConference removes the last call added to the conference
void TapiLine::RemoveFromConference()
{
if (m_hLastCallIntoConf)
{
HRESULT tr = ::lineRemoveFromConference(m_hLastCallIntoConf);
if (tr > 0)
{
REQUEST_INFO ri = { "RemoveFromConference", m_hLastCallIntoConf };
m_Requests.SetAt(tr, ri);
}
m_Parent.CheckError(tr, "RemoveFromConference");
}
else
{
if (!m_hLastCallIntoConf)
m_Parent.m_Dlg.AddText("Error(lineRemoveFromConference: No Active Call)");
}
}
// ----------------------------------------------------------------------------
// Retrieves the address status for the TAPI line (IP Office lines only have
// one address) and displays the details.
void TapiLine::AddressStatus()
{
LINEADDRESSSTATUS* pAddressStatus = NULL;
loopLineGetAddressStatus(m_hLine, 0, pAddressStatus);
if (pAddressStatus)
{
CString txt;
txt.Format("lineAddressStatus: NumInUse<%d> NumActiveCalls<%d> NumOnHoldCalls<%d> NumOnHoldPendCalls<%d> NumRingsNoAnswer<%d>",
pAddressStatus->dwNumInUse, pAddressStatus->dwNumActiveCalls,
pAddressStatus->dwNumOnHoldCalls, pAddressStatus->dwNumOnHoldPendCalls,
pAddressStatus->dwNumRingsNoAnswer);
m_Parent.m_Dlg.AddText(txt);
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_FORWARD)
m_Parent.m_Dlg.AddText("lineAddressStatus: The address can be forwarded.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_MAKECALL)
m_Parent.m_Dlg.AddText("lineAddressStatus: An outgoing call can be placed on the address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_PICKUP)
m_Parent.m_Dlg.AddText("lineAddressStatus: A call can be picked up at the address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_PICKUPDIRECT)
m_Parent.m_Dlg.AddText("lineAddressStatus: The linePickup function can be used to pick up a call on a specific address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_PICKUPGROUP)
m_Parent.m_Dlg.AddText("lineAddressStatus: The linePickup function can be used to pick up a call in the group.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_PICKUPHELD)
m_Parent.m_Dlg.AddText("lineAddressStatus: The linePickup function (with a null destination address) can be used to pick up a call that is held on the address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_PICKUPWAITING)
m_Parent.m_Dlg.AddText("lineAddressStatus: The linePickup function (with a null destination address) can be used to pick up a call waiting call.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_SETMEDIACONTROL)
m_Parent.m_Dlg.AddText("lineAddressStatus: Media control can be set on this address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_SETTERMINAL)
m_Parent.m_Dlg.AddText("lineAddressStatus: The terminal modes for this address can be set.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_SETUPCONF)
m_Parent.m_Dlg.AddText("lineAddressStatus: A conference call with a NULL initial call can be set up at this address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_UNCOMPLETECALL)
m_Parent.m_Dlg.AddText("lineAddressStatus: Call completion requests can be canceled at this address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_UNPARK)
m_Parent.m_Dlg.AddText("lineAddressStatus: Calls can be unparked using this address.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_FORWARDDND)
m_Parent.m_Dlg.AddText("lineAddressStatus: The lineForward function (with an empty destination address) can be used to turn on the Do Not Disturb feature on the address. LINEADDRFEATURE_FORWARD will also be set.");
if (pAddressStatus->dwAddressFeatures & LINEADDRFEATURE_FORWARDFWD)
m_Parent.m_Dlg.AddText("lineAddressStatus: The lineForward function can be used to forward calls on the address to other numbers.");
}
delete [] pAddressStatus;
}
// ----------------------------------------------------------------------------
// Retrieves call info for one of the call handles (see the order below) and
// displays the details.
void TapiLine::GetCallInfo()
{
HCALL hCall = NULL;
if (m_hConnectedCall)
hCall = m_hConnectedCall;
else if (m_hWaitingCall)
hCall = m_hWaitingCall;
else if (m_hHeldCall)
hCall = m_hHeldCall;
else if (m_hPendingCall)
hCall = m_hPendingCall;
else if (m_hConferenceCall)
hCall = m_hConferenceCall;
else if (m_hConsultationCall)
hCall = m_hConsultationCall;
if (hCall)
{
OnCallInfo(hCall, 0);
}
}
// ----------------------------------------------------------------------------
// Open a specified TAPI line
HRESULT TapiLine::Open(DWORD LineID, DWORD CallPrivilege, DWORD MediaModes)
{
// Reset the line
ASSERT(m_hLine == 0);
m_hLine = 0;
// Ask TAPI for a new line
HLINE hNewLine;
HRESULT tr = ::lineOpen(m_Parent.m_hLineApp, LineID,
&hNewLine, m_Parent.m_ApiVersions[LineID],
0, (DWORD)this, CallPrivilege, MediaModes, 0);
m_Parent.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);
m_Parent.CheckError(tr, "SetStatusMessages");
}
return tr;
}
// ----------------------------------------------------------------------------
// Retrieve the status of one of the calls (see order below) and display the
// details.
void TapiLine::GetCallStatus()
{
LINECALLSTATUS* pCallStatus;
HCALL hCall = 0;
if (m_hConnectedCall)
hCall = m_hConnectedCall;
if (m_hWaitingCall)
hCall = m_hWaitingCall;
if (m_hHeldCall)
hCall = m_hHeldCall;
if (m_hPendingCall)
hCall = m_hPendingCall;
if (m_hConferenceCall)
hCall = m_hConferenceCall;
if (hCall)
{
HRESULT tr = loopLineGetCallStatus(hCall, pCallStatus);
if (tr < 0)
m_Parent.CheckError(tr, "lineGetCallStatus");
else
{
CString state;
DescribeCallState(state, pCallStatus->dwCallState);
CString txt;
txt.Format("Call Status: %s", (LPCTSTR)state);
m_Parent.m_Dlg.AddText(txt);
delete [] pCallStatus;
}
}
}
// ----------------------------------------------------------------------------
// Log On an extension
void TapiLine::LogOn(LPCTSTR pszAddress)
{
TCHAR buffer[10];
buffer[0] = 8;
UINT length = strlen(pszAddress);
for (UINT i=0; i < length; i++)
{
buffer[i + 1] = pszAddress[i];
}
buffer[length + 1] = 0; // NULL terminate
HRESULT tr = ::lineDevSpecific(m_hLine,0,NULL,buffer,length + 2);
m_Parent.CheckError(tr, "LogOn");
}
// ----------------------------------------------------------------------------
// Log Off an extension
void TapiLine::LogOff()
{
TCHAR buffer[3];
buffer[0] = 9;
buffer[1] = 47;
buffer[2] = 0; // NULL terminate
HRESULT tr = ::lineDevSpecific(m_hLine,0,NULL,buffer,3);
m_Parent.CheckError(tr, "LogOff");
}
// ----------------------------------------------------------------------------
// Display the IP Office TAPI Config Dialog
void TapiLine::ConfigDialog()
{
HRESULT tr = ::lineConfigDialog(m_LineID, m_Parent.m_Dlg.m_hWnd, NULL);
m_Parent.CheckError(tr, "ConfigDialog");
}
// ----------------------------------------------------------------------------
// Set the divert destination
void TapiLine::DivertDestination(LPCTSTR pszAddress)
{
TCHAR buffer[10];
buffer[0] = 9;
buffer[1] = 6;
UINT length = strlen(pszAddress);
for (UINT i=0; i < length; i++)
{
buffer[i + 2] = pszAddress[i];
}
buffer[length + 2] = 0; // NULL terminate
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -