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

📄 tsapi.cpp

📁 TSapi 软件电话源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			}
		}
	}
	else
	{
		for(int i=0; i<MAX_CALLS_AT_DEVICE; i++)
		{
			if(m_ConnIDList[i][0].callID == connID.callID)
			{
				return (long)(&(m_ConnIDList[i][0]));
			}
		}
	}

	return 0;
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CTsapiWnd object

CTsapiWnd theTsapiWnd;

// For non-MFC folks, this map replaces the large "switch" statement found in
//  straight C Windows programs. The ON_MESSAGE() line can be read as
//  "when a message of type {first argument} is recieved, call
//   the method {second argument}"
BEGIN_MESSAGE_MAP(CTsapiWnd, CWnd)
	ON_MESSAGE(WM_TSAPIMSG, OnTsapiMsg)
END_MESSAGE_MAP()

CTsapiWnd::CTsapiWnd()
{
	m_AcsHandle = 0;
	m_EventBufPtr = (CSTAEvent_t*)&m_EventBuf;
	m_EventBufSize = sizeof(CSTAEvent_t);
}

CTsapiWnd::~CTsapiWnd()
{
	// free any allocated memory            
	if(m_EventBufPtr != (CSTAEvent_t*)&m_EventBuf)
	{ 
		GlobalFreePtr(m_EventBufPtr);   
	}
	// terminate the stream connection
	if(m_AcsHandle)
	{
		acsAbortStream(m_AcsHandle, 0);
	}
}

// public interface to the private CreateEx() method
void CTsapiWnd::DoCreate()
{
	CreateEx(0, AfxRegisterWndClass(CS_GLOBALCLASS), "", 0, 0, 0, 0, 0, 0, 0);
}

// This method is called when a TSAPI message (WM_TSAPIMSG) is received.
// The WM_TSAPIMSG is just a notification that there is a message waiting in the
//  CSTA DLL. Use acsGetEventPoll() to retrieve the actual message.
//
// If the static buffer is too small for the message, dynamically allocate a buffer
//  that is big enough. Debug tracing should be used to fine tune the size of the
//  static buffer such that a dynamic buffer doesn't need to be created every time.
// The event is then forwarded to the appropriate window.
// If there are more events waiting (numEvents > 0), then post ourselves another
//  WM_TSAPIMSG.  This is done instead of a while(numEvents >0) loop to allow for
//  processing of other windows events and to allow for the TSAPI event to process-to-
//  completion
LRESULT CTsapiWnd::OnTsapiMsg(WPARAM wParam, LPARAM lParam)
{
	RetCode_t rc;
	unsigned short numEvents;

	// free any previously allocated memory before continuing            
	if(m_EventBufPtr && (m_EventBufPtr != (CSTAEvent_t*)&m_EventBuf))
	{ 
		GlobalFreePtr(m_EventBufPtr);
		m_EventBufPtr = 0;   
	}

	// attempt to retrieve the event from the CSTA DLL	
	m_EventBufSize = sizeof(m_EventBuf);
	rc = acsGetEventPoll(m_AcsHandle, &m_EventBuf, &m_EventBufSize, 0, &numEvents);
	if(rc != 0)
	{
		// check if rc indicates no messages to get - that is ok
		if(rc == ACSERR_NOMESSAGE)
		{
			return 0;
		}
		else if(rc == ACSERR_UBUFSMALL)	// static buffer too small - allocate larger one
		{ 
			// space required is in the return parameter
		    m_EventBufPtr = (CSTAEvent_t*)GlobalAllocPtr(GHND, m_EventBufSize);
			if(!m_EventBufPtr)
			{
				m_TsapiController->PostMessage(WM_TSAPIFAILURE, rc, 0);
				return (LRESULT)rc;
			}

			// try to get the event out of the queue again, into the newly allocated memory                     
			rc = acsGetEventPoll(m_AcsHandle, m_EventBufPtr, &m_EventBufSize, 0, &numEvents);
			if(rc != 0)
			{
				// not you can do here...
				// free the allocated memory
				GlobalFreePtr(m_EventBufPtr);
				m_EventBufPtr = 0;   
				m_TsapiController->PostMessage(WM_TSAPIFAILURE, rc, 0);
				return (LRESULT)rc;
			}                                       
		}
		else 
		{
			// not much you can do here...
			m_TsapiController->PostMessage(WM_TSAPIFAILURE, rc, 0);
			return (LRESULT)rc;
		}
	}
	else
	{
		m_EventBufPtr = (CSTAEvent_t*)&m_EventBuf;
	}

	// handle each class of events slightly differently		
	switch(m_EventBufPtr->eventHeader.eventClass)
	{
	 case ACSUNSOLICITED:
		// ACS Unsolicited events are all handled by the TSAPI controller - the
		//  window that wants to be responsible for memory clean-up and stream failure
		//  handling. Forward all of these events to the controller.

		// this is a sendmessage(), not a postmessage() because the operation has to
		//  process to completion - or at least until the event buffer is not needed
		m_TsapiController->SendMessage(WM_TSAPIACSUNSOLICITED, 0, 0);
		break;
	 case ACSCONFIRMATION:
	 {
		// ACS Confirmation events are all handled by the window that is passed in via
		//  the invoke ID. Forward all of these events to that window.

		// get CWnd pointer out of invokeID, send message
		CWnd* pWnd = (CWnd*)m_EventBufPtr->event.acsConfirmation.invokeID;
		// make sure the window is still there
		if(::IsWindow(pWnd->m_hWnd))
		{
			// this is a sendmessage(), not a postmessage() because the operation has to
			//  process to completion - or at least until the event buffer is not needed
			pWnd->SendMessage(WM_TSAPIACSCONFIRMATION, 0, 0);
		}
		break;
	 }
	 case CSTACONFIRMATION:
	 {
		// CSTA Confirmation events are all handled by the window that is associated with
		//  the device whose device record is passed in via the invoke ID. Forward all of
		//  these events to that window.

		// get CTsapiDevice pointer and CWnd pointer out of invokeID, send message
		CTsapiDevice* pTsapi = (CTsapiDevice*)m_EventBufPtr->event.acsConfirmation.invokeID;
		// get the CWnd pointer out of CTsapiDevice and make sure the window is still there
		if(::IsWindow(pTsapi->GetWndPtr()->m_hWnd))
		{
			// this is a sendmessage(), not a postmessage() because the operation has to
			//  process to completion - or at least until the event buffer is not needed
			pTsapi->GetWndPtr()->SendMessage(WM_TSAPICSTACONFIRMATION, 0, (LPARAM)pTsapi);
		}
		break;
	 }
	 case CSTAUNSOLICITED:
	 {
		// CSTA Unsolicited events are all handled by the window that is associated with
		//  the device whose monitor cross reference ID matches the one received in this
		//  event. Forward all of these events to that window.

		// get CTsapiDevice pointer by looking for a matching monitor cross reference ID
		CTsapiDevice* pTsapi = GetDeviceRecord(m_EventBufPtr->event.cstaUnsolicited.monitorCrossRefId);
		// get the CWnd pointer out of CTsapiDevice and make sure the window is still there
		if(pTsapi && pTsapi->GetWndPtr() && ::IsWindow(pTsapi->GetWndPtr()->m_hWnd))
		{
			// this is a sendmessage(), not a postmessage() because the operation has to
			//  process to completion - or at least until the event buffer is not needed
			pTsapi->GetWndPtr()->SendMessage(WM_TSAPICSTAUNSOLICITED, 0, (LPARAM)pTsapi);
		}
		break;
	 }
	 default:
		break;
	}

	// If there are additional TSAPI events to process, post ourselves another message.
	if(numEvents > 0)
	{
		PostMessage(WM_TSAPIMSG, 0, 0);
	}                              

	return 0;
}

// this method creates a device record for the given device ID and returns a pointer
//  to that device record. It should return NULL if it couldn't create the device
//  record (can't happen here).
CTsapiDevice* CTsapiWnd::CreateDeviceRecord(DeviceID_t deviceId)
{
	// if more than 1 device were allowed, then dynamic allocation
	//  could happen here

	// now place the new device info into the device record
	m_MyOneDevice.SetDeviceID(deviceId);
	return &m_MyOneDevice;
}

// this method returns a pointer to the given device's device record or NULL if
//  a record is not found. 
CTsapiDevice* CTsapiWnd::GetDeviceRecord(DeviceID_t deviceID)
{
	// if more than 1 device were allowed, then all of the device structures
	//  would be searched for the deviceID specified
	DeviceID_t myDevID;
	m_MyOneDevice.GetDeviceID(myDevID);
	if(lstrcmp(myDevID, deviceID) == 0)
	{
		return &m_MyOneDevice;
	}

	return NULL;
}

// this method returns a pointer to the device record associated with the given
//  cross reference ID or NULL if a record is not found.
CTsapiDevice* CTsapiWnd::GetDeviceRecord(CSTAMonitorCrossRefID_t monitorCrossRefID)
{
	// if more than 1 device were allowed, then all of the device structures
	//  would be searched for the cross ref ID specified

	if(m_MyOneDevice.GetCrossRefID() == monitorCrossRefID)
	{
		return &m_MyOneDevice;
	}

	return NULL;
}

⌨️ 快捷键说明

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