📄 tsapi.cpp
字号:
}
}
}
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 + -