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

📄 opentsrv.cpp

📁 TSapi 软件电话源代码
💻 CPP
字号:
// opentsrv.cpp : implementation file
//
// This file handles the Open Tserver dialog
//

#include "stdafx.h"
#include "resource.h" // replace with theApp header if needed
#include "opentsrv.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COpenTsrv dialog


COpenTsrv::COpenTsrv(CWnd* pParent /*=NULL*/)
	: CDialog(COpenTsrv::IDD, pParent)
{
	//{{AFX_DATA_INIT(COpenTsrv)
	m_Login = _T("");
	m_Password = _T("");
	m_Tserver = _T("");
	m_DeviceID = _T("");
	//}}AFX_DATA_INIT
}

// For non-MFC folks, this is a helper routine for passing data back-and-forth
//  from this class to the Open Tserver dialog.
void COpenTsrv::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(COpenTsrv)
	DDX_Control(pDX, IDC_TSERVERLIST, m_TserverListControl);
	DDX_Control(pDX, IDOK, m_OKControl);
	DDX_Text(pDX, IDC_LOGIN, m_Login);
	DDV_MaxChars(pDX, m_Login, 48);
	DDX_Text(pDX, IDC_PASSWORD, m_Password);
	DDV_MaxChars(pDX, m_Password, 48);
	DDX_CBString(pDX, IDC_TSERVERLIST, m_Tserver);
	DDX_Text(pDX, IDC_DEVICEID, m_DeviceID);
	DDV_MaxChars(pDX, m_DeviceID, 64);
	//}}AFX_DATA_MAP
}

// For non-MFC folks, this map replaces the large "switch" statement found in
//  straight C Windows programs. The ON_MESSAGE() lines were added manually.
//  Read them as "when a message of type {first argument} is received, call
//   the method {second argument}"
BEGIN_MESSAGE_MAP(COpenTsrv, CDialog)
	ON_MESSAGE(WM_TSAPIACSCONFIRMATION, OnTsapiAcsConfirmation)
	ON_MESSAGE(WM_TSAPICSTACONFIRMATION, OnTsapiCstaConfirmation)
	//{{AFX_MSG_MAP(COpenTsrv)
	ON_CBN_SELCHANGE(IDC_TSERVERLIST, OnSelchangeTserverlist)
	ON_EN_CHANGE(IDC_LOGIN, OnChangeLogin)
	ON_EN_CHANGE(IDC_DEVICEID, OnChangeDeviceid)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// COpenTsrv message handlers

extern "C"
{

// this callback function is used by the csta dll (via acsEnumServerNames)
// lParam contains a pointer to the combo box on the Open Tserver dialog
// name contains 1 registered Tserver service - put it into the combo box.
Boolean AddToList(char* name, unsigned long lParam)
{
	CComboBox* lBox = (CComboBox*)lParam;
	return(lBox->AddString(name) >= 0);    
}

}

// dialog initialization
BOOL COpenTsrv::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	CenterWindow();

	// want CSTA-type services
	// AddToList() is the callback function
	// pass the address of the combo box to be returned in the AddToList() callback	
	acsEnumServerNames(ST_CSTA, AddToList, (unsigned long)(CComboBox*)&m_TserverListControl);

	UpdateData(FALSE);

	// must have a Tserver, login and device (password may also be needed, depending on
	//  the Tserver selected)
	m_OKControl.EnableWindow(!m_Tserver.IsEmpty() && !m_Login.IsEmpty() && !m_DeviceID.IsEmpty());	

	return TRUE;  // return TRUE unless you set the focus to a control
}

// for every change to the Login ID field, this method is called
void COpenTsrv::OnChangeLogin() 
{
	UpdateData(TRUE);
	
	// must have a Tserver, login and device (password may also be needed, depending on
	//  the Tserver selected)
	m_OKControl.EnableWindow(!m_Tserver.IsEmpty() && !m_Login.IsEmpty() && !m_DeviceID.IsEmpty());	
}

// as each Tserver in the Tserver combo box is selected, this method is called
void COpenTsrv::OnSelchangeTserverlist() 
{
	UpdateData(TRUE); // get server name out of the combo box control

	// get authorization information for the selected Tserver
	ACSAuthInfo_t authInfo;	
	if(acsQueryAuthInfo((ServerID_t*)(LPCTSTR)m_Tserver,  &authInfo) == ACSPOSITIVE_ACK)
	{ 
		switch(authInfo.authType)
		{
		 case AUTH_LOGIN_ID_ONLY:
		 case AUTH_LOGIN_ID_IS_DEFAULT:
		 case ANY_LOGIN_ID: 
	 		// no login or password needed 
	 		m_Login = authInfo.authLoginID;
			UpdateData(FALSE);
	 		break; 
		 default: // login (and maybe password) are needed
	 		break;
		}
	}

	// must have a Tserver, login and device (password may also be needed, depending on
	//  the Tserver selected)
	m_OKControl.EnableWindow(!m_Tserver.IsEmpty() && !m_Login.IsEmpty() && !m_DeviceID.IsEmpty());	
}

// for every change to the Device ID field, this method is called
void COpenTsrv::OnChangeDeviceid() 
{
	UpdateData(TRUE);
	
	// must have a Tserver, login and device (password may also be needed, depending on
	//  the Tserver selected)
	m_OKControl.EnableWindow(!m_Tserver.IsEmpty() && !m_Login.IsEmpty() && !m_DeviceID.IsEmpty());	
}

// If the OK button is pressed, this method is called
void COpenTsrv::OnOK() 
{
	if(!UpdateData(TRUE))
	{
		return;
	}

	// attempt to open a stream to the selected Tserver
	ServerID_t advertisingName;     
	lstrcpy(advertisingName, m_Tserver);
	LoginID_t loginID;
	lstrcpy(loginID, m_Login);
	Passwd_t passwd;
	lstrcpy(passwd, m_Password);
	AppName_t appname;
	lstrcpy(appname, "TSAPI Sample");
	Version_t version;
	lstrcpy(version, "TS1-2");

	// before opening the stream, create the hidden window which will process all
	//  of the TSAPI events.
	m_TsapiWndPtr = new CTsapiWnd;
	m_TsapiWndPtr->m_TsapiController = m_TsapiController;
	m_TsapiWndPtr->DoCreate();
	// The application will generate the invoke IDs.
	// Use a pointer to the window here (and for all ACS requests) for the invoke ID -
	//  this specifies which window applies to this request. The TSAPI window looks at
	//  the invoke ID of all ACS events and assumes they are window pointers. The event is
	//  then forwarded to that window.
	RetCode_t rc = acsOpenStream(&m_TsapiWndPtr->m_AcsHandle, APP_GEN_ID,
						(InvokeID_t)this, ST_CSTA, &advertisingName, &loginID, &passwd, &appname,
						ACS_LEVEL1, &version, 10, 5, 50, 5, 0);
	if(rc < 0)
	{
		// failure for some reason, specified in rc as a RetCode_t (defined in acs.h).
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("open stream failed");
		return; 
	}
	
	// no conf events are being processed yet, so don't wait for it yet...
	
	// set up event notification on this acs stream
	// all TSAPI events will be sent to the TSAPI window (m_TsapiWndPtr) via the
	//  WM_TSAPIMSG message.
	// The last parameter set to FALSE indicates that the application will handle draining
	//  the TSAPI event queue from the CSTA dll. TRUE would indicate the dll should send a
	//  WM_TSAPIMSG per TSAPI event. With FALSE, the dll sends a WM_TSAPIMSG only when the
	//  TSAPI event queue goes from empty to non-empty. This allows the application to drain
	//  the TSAPI event queue at its own pace, without overflowing the Windows message queue.
	rc = acsEventNotify(m_TsapiWndPtr->m_AcsHandle, m_TsapiWndPtr->GetSafeHwnd(), WM_TSAPIMSG, FALSE);
	if(rc < 0)
	{
		// failure for some reason, specified in rc as a RetCode_t (defined in acs.h).
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL);
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("event notify failed");
		return; 
	}
	
	// once the event notify is processed, conf events will come back from the
	//  TSAPI DLL                           
}

// This method is called when an ACS Confirmation Event is received that is forwarded to
//  this dialog.
LRESULT COpenTsrv::OnTsapiAcsConfirmation(WPARAM wParam, LPARAM lParam)
{
	// this dialog should either get an open stream conf event or
	//  a universal failure event
	switch(m_TsapiWndPtr->m_EventBufPtr->eventHeader.eventType)
	{
	 case ACS_OPEN_STREAM_CONF:
		// this is what we want...
		break;
	 case ACS_UNIVERSAL_FAILURE_CONF:
		// failure for some reason. This could be invalid login/password, no permissions,
		//  or several other failure codes (listed in acsdefs.h).
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL);
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("open stream failed");
		return 0; 
	 default:
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL);
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("unexpected response to acsOpenStream");
		return 0; 
	}

	// now, attempt to put a device monitor on the specified device. No filtering is requested,
	//  but the PBX may place filtering on the monitor. You will be notified of the filtering
	//  placed on the monitor in the monitor confirmation event.
	CSTAMonitorFilter_t noFilter;
	noFilter.call = 0;
	noFilter.feature = 0;
	noFilter.agent = 0;
	noFilter.maintenance = 0;
	noFilter.privateFilter = 0;

	// create a device record in the TSAPI window for this device. This device record will be
	//  used to track all calls for this device and is also used to determine which window should
	//  handle the TSAPI events that are received for each device.
	DeviceID_t deviceID;
	lstrcpy(deviceID, m_DeviceID);
	CTsapiDevice* pTsapi = m_TsapiWndPtr->CreateDeviceRecord(deviceID);
	if(!pTsapi)
	{
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL);
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("no memory for device");
		return 0;
	}

	// For now, process events for this device in this window
	pTsapi->SetWndPtr(this);

	// Use a pointer to the device record here (and for all CSTA requests) for the invoke ID -
	//  this specifies which device record applies to this request. The TSAPI window looks at
	//  the invoke ID of all CSTA CONFIRMATION events and assumes they are device record pointers.
	//  That record is then used to determine which window should handle events for that device.
	//  The event is then forwarded to that window.
	RetCode_t rc = cstaMonitorDevice(m_TsapiWndPtr->m_AcsHandle,
						(InvokeID_t)pTsapi, &deviceID, &noFilter, NULL);
	if(rc < 0)
	{
		// failure for some reason, specified in rc as a RetCode_t (defined in acs.h).
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL);
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("monitor device failed");
		return 0;
	}

 	return 0;
}

// This method is called when an CSTA Confirmation Event is received that is forwarded to
//  this dialog. 
LRESULT COpenTsrv::OnTsapiCstaConfirmation(WPARAM wParam, LPARAM lParam)
{
	// this dialog should either get a monitor conf event or
	//  a universal failure event
	switch(m_TsapiWndPtr->m_EventBufPtr->eventHeader.eventType)
	{
	 case CSTA_MONITOR_CONF:
		// this is what we want...
		break;
	 case CSTA_UNIVERSAL_FAILURE_CONF:
		// failure for some reason. failure codes are listed in cstadefs.h.
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL);
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("monitor device failed");
		return 0; 
	 default:
		acsAbortStream(m_TsapiWndPtr->m_AcsHandle, NULL);
		delete m_TsapiWndPtr;
		m_TsapiWndPtr = 0;
		AfxMessageBox("unexpected response to cstaMonitorDevice");
		return 0; 
	}

	// The lParam is a device record pointer. Set the monitor cross reference ID for that
	//  device to the cross reference ID recieved here. The TSAPI window looks at the cross
	//  reference ID of all CSTA UNSOLICITED events and retrieves the associated device record.
	//  That record is then used to determine which window should handle events for that device.
	//  The event is then forwarded to that window.
	((CTsapiDevice*)lParam)->SetCrossRefID(m_TsapiWndPtr->m_EventBufPtr->event.cstaConfirmation.u.monitorStart.monitorCrossRefID);

	// now the open tserver dialog can be dismissed.
	// The calling class is now responsible for the CTsapiWnd memory clean-up
	EndDialog(IDOK);
	return 0;
}


⌨️ 快捷键说明

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