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

📄 sampldlg.cpp

📁 TSapi 软件电话源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		// hold call - just set reservation flag to FALSE
		RetCode_t rc = cstaHoldCall(m_TsapiWndPtr->m_AcsHandle, (InvokeID_t)pTsapi,
												&connID, FALSE, NULL);
		if(rc < 0)
		{
			AfxMessageBox("hold call failed");
			return;
		}

		// now that the call has been held, change button text
		m_HoldControl.SetWindowText(_T("Unh&old"));
	}
	
	return;
}

// this method enables/disables buttons (and input fields) based on current status
void CSampleDlg::DoButtonUpdates() 
{
	// get selected list item
	int index = m_CallListControl.GetNextItem(-1, LVNI_ALL | LVNI_SELECTED);
	if(index < 0)
	{
		// if no item is selected, nothing can be done
		m_HoldControl.EnableWindow(FALSE);
		m_AnswerControl.EnableWindow(FALSE);
		m_HangUpControl.EnableWindow(FALSE);
		return;
	}

	// get the local connection state out of selected list control item
	CString connState = m_CallListControl.GetItemText(index, LOCAL_CONNECTION_STATE);

	// enable hold button - for holding or unholding
	m_HoldControl.EnableWindow(TRUE);
	// set hold text based on selected item's state
	m_HoldControl.SetWindowText((connState == _T("Held")) ? _T("Unh&old") : _T("H&old"));
	// enable answer and hang-up buttons based on selected item's state
	m_AnswerControl.EnableWindow(connState == _T("Alerting"));
	m_HangUpControl.EnableWindow(connState == _T("Connected"));	
}

// this method is called when an item in the call list is selected
void CSampleDlg::OnClickCalllist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// update the buttons based on state of the selected item
	DoButtonUpdates();
	*pResult = 0;
}

// this method is called on every update to the "Make Call To" field.
void CSampleDlg::OnChangeTodeviceid() 
{
	// retrieve the data out of the dialog
	UpdateData(TRUE);
	// enable the Call button if the "Make Call To" field is not empty
	m_CallControl.EnableWindow(!m_ToDeviceID.IsEmpty());	
}

// this method is called when the CSTA DLL returns failure on an attempt
//  to retrieve a TSAPI message.
// the failure code is in wParam. It is a RetCode_t and is one of the
//  failure codes defined in acs.h.
LRESULT CSampleDlg::OnTsapiFailure(WPARAM wParam, LPARAM lParam)
{
	char tempStr[10];
	sprintf(tempStr, "TSAPI Message Retrieval Failure: %d", wParam);
	AfxMessageBox(tempStr);
	PostMessage(WM_COMMAND, IDCANCEL, 0);
	return 0;
}

// this method is called when an ACS Unsolicited event is received
LRESULT CSampleDlg::OnTsapiAcsUnsolicited(WPARAM wParam, LPARAM lParam)
{
	char tempStr[10];
	sprintf(tempStr, "TSAPI Stream Failure: %d",
			m_TsapiWndPtr->m_EventBufPtr->event.acsUnsolicited.u.failureEvent.error);
	AfxMessageBox(tempStr);
	PostMessage(WM_COMMAND, IDCANCEL, 0);
	return 0;
}

// this method is called when a CSTA Confirmation event is received
LRESULT CSampleDlg::OnTsapiCstaConfirmation(WPARAM wParam, LPARAM lParam)
{
	switch(m_TsapiWndPtr->m_EventBufPtr->eventHeader.eventType)
	{
	 case CSTA_MAKE_CALL_CONF:
	 case CSTA_CLEAR_CONNECTION_CONF:
	 case CSTA_ANSWER_CALL_CONF:
	 case CSTA_HOLD_CALL_CONF:
	 case CSTA_RETRIEVE_CALL_CONF:
		// let the unsolicited events take care of any updates
		// Generally, nothing should be done with positive confirmation
		//  events - the unsolicited events should drive the application's
		//  behaviour.
		break;
	 case CSTA_UNIVERSAL_FAILURE_CONF:
		// something more elaborate should probably be done when
		//  a request fails!
		AfxMessageBox("requested operation failed");
		break; 
	 default:
		AfxMessageBox("unexpected response to requested operation");
		break; 
	}

	return 0;
}

// this method is called when a CSTA Unsolicited event is received
LRESULT CSampleDlg::OnTsapiCstaUnsolicited(WPARAM wParam, LPARAM lParam)
{
	// Get the device record pointer out of the lParam
	// Get the unsolicited event pointer out of the event buffer (for
	//  code efficiency and typing efficiency)
	CTsapiDevice* pTsapi = (CTsapiDevice*)lParam;
	CSTAUnsolicitedEvent* pUns = &(m_TsapiWndPtr->m_EventBufPtr->event.cstaUnsolicited);

	switch(m_TsapiWndPtr->m_EventBufPtr->eventHeader.eventType)
	{
	 // this is not a call-control event. just end the app if the monitor
	 //  of the device was terminated for any reason.
	 case CSTA_MONITOR_ENDED:
		AfxMessageBox("monitor failure");
		PostMessage(WM_COMMAND, IDCANCEL, 0);
		return 0;

	 // these are call-control events...
	 case CSTA_SERVICE_INITIATED: // null -> initiated (LOCAL only)
	 {
		ConnectionID_t* pConnID = &(pUns->u.serviceInitiated.initiatedConnection);

		// this is a new call - track it
		long callHandle = pTsapi->CreateCallFromLocalConnection(*pConnID);
		if(callHandle == 0)
		{
			AfxMessageBox("no memory to add new call");
			return 0;
		}

		LV_ITEM lvItem;
		lvItem.iItem = 0;
		lvItem.iSubItem = 0;
		lvItem.mask = LVIF_PARAM;
		lvItem.lParam = callHandle;

		// insert the call into the list control
		int listIndex = m_CallListControl.InsertItem(&lvItem);
		if(listIndex < 0)
		{
			pTsapi->RemoveCallViaConnection(*pConnID);
			AfxMessageBox("no memory to add new call");
			return 0;
		}

		// this event is always for the local connection
	 	m_CallListControl.SetItemText(listIndex, LOCAL_CONNECTION_STATE, _T("Initiated"));
		break;
	 }
	 case CSTA_ORIGINATED: // null/initiated -> connected (LOCAL only)
	 {
		ConnectionID_t* pConnID = &(pUns->u.originated.originatedConnection);

		// Attempt to find the call associated with the connection ID
		//  if a SERVICE INITIATED event was received, this call will
		//   be found.
		//  if no SERVICE INITIATED event was received, then this event is the
		//   first event received.
		long callHandle = pTsapi->GetCallHandle(*pConnID, TRUE);

		int listIndex;

		if(callHandle == 0)
		{
			// assume this is a new call - track it
			callHandle = pTsapi->CreateCallFromLocalConnection(*pConnID);
			if(callHandle == 0)
			{
				AfxMessageBox("no memory to add new call");
				return 0;
			}

			LV_ITEM lvItem;
			lvItem.iItem = 0;
			lvItem.iSubItem = 0;
			lvItem.mask = LVIF_PARAM;
			lvItem.lParam = callHandle;

			// insert the call into the list control
			listIndex = m_CallListControl.InsertItem(&lvItem);
			if(listIndex < 0)
			{
				pTsapi->RemoveCallViaConnection(*pConnID);
				AfxMessageBox("no memory to add new call");
				return 0;
			}
		}
		else
		{
			LV_FINDINFO findInfo;
			findInfo.flags = LVFI_PARAM;
			findInfo.lParam = callHandle;
			listIndex = m_CallListControl.FindItem(&findInfo, -1);
		}

		// this event is always for the local connection
		m_CallListControl.SetItemText(listIndex, LOCAL_CONNECTION_STATE, _T("Connected"));

		CString calledDevice;

		// get the number dialed out of calledDevice
		// For calls originated via the phone, this is the first chance to
		//  place the information into the dialog.
		// Modifying the "To Device" here and in other events illustrates
		//  how the PBX and/or PBX Driver what has been dialled. Apps need
		//  to be aware that this can happen.
		if(pUns->u.originated.calledDevice.deviceIDStatus == ID_PROVIDED)
		{
			calledDevice = pUns->u.originated.calledDevice.deviceID;
		}
		else
		{
			calledDevice = _T("Not provided");
		}

		m_CallListControl.SetItemText(listIndex, 0, calledDevice);
		break;
	 }
	 case CSTA_DELIVERED: // null -> alerting
	 {
		ConnectionID_t* pConnID = &(pUns->u.delivered.connection);
 		SubjectDeviceID_t* pSubjectDevice = &(pUns->u.delivered.alertingDevice);
 		CallingDeviceID_t* pCallingDevice = &(pUns->u.delivered.callingDevice);
 		CalledDeviceID_t* pCalledDevice = &(pUns->u.delivered.calledDevice);

		BOOL subjectProvided = (pSubjectDevice->deviceIDStatus == ID_PROVIDED);
		BOOL callingProvided = (pCallingDevice->deviceIDStatus == ID_PROVIDED);
		BOOL calledProvided = (pCalledDevice->deviceIDStatus == ID_PROVIDED);

		BOOL outgoing;
		if(subjectProvided)
		{
			outgoing = !(m_DeviceID == pSubjectDevice->deviceID);
		}
		else if(callingProvided)
		{
			outgoing = (m_DeviceID == pCallingDevice->deviceID);
		}
		else if(calledProvided)
		{
			outgoing = !(m_DeviceID == pCalledDevice->deviceID);
		}
		else
		{
			// nothing we can do if no IDs are provided!
			return 0;
		}

		if(outgoing)
		{
			// don't bother storing remote connection while it is still alerting...

			// Find the call handle based on call ID in given connection ID
			// Unfortunately, we must crack open the ConnID here (the FALSE indicates
			//  an inexact match - just match on callID). Looking at the callID is
			//  not guaranteed to work on 100% of all PBX drivers - some implementations
			//  do not guarantee unique call IDs, only unique connection IDs.
			//  There are 2 alternatives to this, neither one of which is any better
			//  than this (and may even be worse).
			//  1. Look at the calledDevice. The app should know the number that was called,
			//		and could store that number with the local connection ID. When execution
			//		reaches here, search for the called device and return the callHandle. This
			//		has 2 problems: a. calledDevice is not guaranteed to be supplied from all PBX
			//		drivers; b. if 2 calls to the same device are in progress simultaneously, which
			//		callHandle is for which device?
			//  2. Do a cstaSnapshotCall() on the connection ID passed in here. That will give you
			//		a picture of what is happening with that connID - including the connID in the
			//		call that is associated with the monitored device. The snapshot can be used to
			//		match that local connID to what is stored in the app. This delays handling of
			//		the event with asynchronous queries to the server - in the meantime other things
			//		are happening to the call!
			long callHandle = pTsapi->GetCallHandle(*pConnID, FALSE);
			if(callHandle == 0)
			{
				return 0;
			}

			// need to get listIndex for where this message should go
 			LV_FINDINFO findInfo;
			findInfo.flags = LVFI_PARAM;
			findInfo.lParam = callHandle;
			int listIndex = m_CallListControl.FindItem(&findInfo, -1);

			m_CallListControl.SetItemText(listIndex, REMOTE_CONNECTION_STATE, _T("Alerting"));

			CString calledDevice;

			// get the called device out of subjectDevice or calledDevice
			if(subjectProvided)
			{
				calledDevice = pSubjectDevice->deviceID;
			}
			else if(calledProvided)
			{
				calledDevice = pCalledDevice->deviceID;
			}
			else
			{
				calledDevice = _T("Not provided");
			}

		 	m_CallListControl.SetItemText(listIndex, 0, calledDevice);
		}
		else
		{
			// this is a new call (for this device) - track it
			long callHandle = pTsapi->CreateCallFromLocalConnection(*pConnID);
			if(callHandle == 0)
			{
				AfxMessageBox("no memory to add new call");
				return 0;
			}

			LV_ITEM lvItem;
			lvItem.iItem = 0;
			lvItem.iSubItem = 0;
			lvItem.mask = LVIF_PARAM;
			lvItem.lParam = callHandle;

			// insert the call into the list control
			int listIndex = m_CallListControl.InsertItem(&lvItem);
			if(listIndex < 0)
			{
				pTsapi->RemoveCallViaConnection(*pConnID);
				AfxMessageBox("no memory to add new call");
				return 0;
			}

		 	m_CallListControl.SetItemText(listIndex, LOCAL_CONNECTION_STATE, _T("Alerting"));

			CString callingDevice;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -