⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapiline.cpp

📁 基于TAPI 2.0的软电话源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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 + -