📄 michellecti.cpp
字号:
// MichelleCTI.cpp : Implementation of CMichelleCTI
#include "stdafx.h"
#include "ctcv4.h"
#include "KVPair.h"
#include "KVList.h"
#include "CTIEvent.h"
#include "MichelleCTI.h"
#include "DirectoryNumber.h"
DECLARE_CASTER(CCTIEvent, ICTIEvent)
DECLARE_CREATOR(CCTIEvent, ICTIEvent)
DECLARE_CASTER(CDirectoryNumber, IDirectoryNumber)
DECLARE_CREATOR(CDirectoryNumber, IDirectoryNumber)
//THE NETWORK TYPE
#define NT_NetBIOS_NetBEUI 0
#define NT_TCPIP NT_NetBIOS_NetBEUI+1
#define NT_DECnet NT_NetBIOS_NetBEUI+2
#define NT_NetBIOS_TCPIP NT_NetBIOS_NetBEUI+3
#define NT_NAMED_PIPE NT_NetBIOS_NetBEUI+4
#define NT_SPX NT_NetBIOS_NetBEUI+5
HWND h_gPumpWnd=NULL; // the main window handle that process all message from cti and dn
HINSTANCE h_gInstance=NULL; // The dll instance handle
BSTR C2B(char* pStr,int nBufLen)
{
BSTR ret=NULL;
int nLen=MultiByteToWideChar(CP_ACP,0,pStr,-1,NULL,0);
if (nLen>0)
{
OLECHAR* pBstr=new OLECHAR[nLen];
if (pBstr)
{
nLen=MultiByteToWideChar(CP_ACP,0,pStr,-1,pBstr,nLen);
if (nLen>0)
{
ret=SysAllocString(pBstr);
}
delete pBstr;
}
}
return ret;
}
BOOL B2C(BSTR bStr,char* pStr,int nBufLen)
{
BOOL bRet=FALSE;
memset(pStr,0,nBufLen);
int nLen=WideCharToMultiByte(CP_ACP,0,bStr,-1,pStr,nBufLen,NULL,NULL);
if (nLen>0)
bRet=TRUE;
return bRet;
}
// The main message process function for the pump window,
// it process all messages from cti and dns, the fire some of them to VB
static LRESULT CALLBACK PumpWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
//redo, to fire event and
//msg: the message type
//wParam: the class pointer
//lParam: the data buffer pointer
CCTIEvent *pCEvent;
ICTIEvent *pIEvent;
CMichelleCTI *pCTI;
CDirectoryNumber *pDN;
switch (msg)
{
case UM_FATALERROR: // Never process this routin
pCTI = (CMichelleCTI *)wParam;
if (pCTI)
{
pCTI->FatalError();
//fire this evnet out
if(SUCCEEDED(CreateClass(&pCEvent, &pIEvent)))
{
pCEvent->FillEvent(NULL); //NULL means that this is EventServerDisconnected
pCTI->Fire_Event(pIEvent);
pIEvent->Release();
} else
{
pCTI->Fire_Event(NULL);
}
}
//Release data buffer
if (lParam)
{
delete (ctcEventData*)lParam;
}
break;
case UM_CTIEVENT: //process the cti message
pCTI = (CMichelleCTI *)wParam;
if (pCTI)
{
if(!pCTI->DefaultHandler())
{
//fire this evnet out
if(SUCCEEDED(CreateClass(&pCEvent, &pIEvent)))
{
pCEvent->FillEvent((ctcEventData*)lParam); //NULL means that this is EventServerDisconnected
pCTI->Fire_Event(pIEvent);
pIEvent->Release();
} else
{
pCTI->Fire_Event(NULL);
}
}
}
//Release data buffer
if (lParam)
{
delete (ctcEventData*)lParam;
}
break;
case UM_DNEVENT://process the dn message
pDN = (CDirectoryNumber *)wParam;
if (pDN)
{
// if(!pDN->DefaultHandler((ctcEventData*)lParam))
{
if(SUCCEEDED(CreateClass(&pCEvent, &pIEvent)))
{
pCEvent->FillEvent((ctcEventData*)lParam); //NULL means that this is EventServerDisconnected
pDN->Fire_Event(pIEvent);
pIEvent->Release();
} else
{
pDN->Fire_Event(NULL);
}
}
}
//Release data buffer
if (lParam)
{
delete (ctcEventData*)lParam;
}
break;
default:// the windows message
return (DefWindowProc(hwnd, msg, wParam, lParam));
}
return 0L;
}
BOOL GlobalStartup(HINSTANCE hInstance)
{
h_gInstance=hInstance;
//Create the main message process window
BOOL bRet=FALSE;
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = PumpWndProc;
wc.cbClsExtra = wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = _T("Michelle_CTI_MsgProcess_Window");
if(RegisterClass(&wc))
{
h_gPumpWnd = CreateWindow(wc.lpszClassName, NULL,
WS_DISABLED, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
bRet=TRUE;
}
return bRet;
}
void GlobalCleanup()
{
if (h_gPumpWnd)
DestroyWindow(h_gPumpWnd);
return;
}
void CMichelleCTI::ClearAPIInfo()
{
m_lErrCode=0;
m_ErrType=ET_USER;
m_ErrMsg="";
}
void CMichelleCTI::CleanDNList()
{
EnterCriticalSection(&m_csList);
DNLIST::iterator p;
for (p=m_dnlist.begin();p!=m_dnlist.end();++p)
{
UnregisterDN(*p);
}
m_dnlist.clear();
LeaveCriticalSection(&m_csList);
}
void CMichelleCTI::FatalError()
{
return;
}
LPDN CMichelleCTI::SearchRegisterdDN(char* dn)
{
return NULL;
}
BOOL CMichelleCTI::DefaultHandler()
{
// must fire the ctilink message
// if error, fire ctidislink
// else not fire
return TRUE;
}
STDMETHODIMP CMichelleCTI::get_Initialized(BOOL *pVal)
{
*pVal=(strlen(m_strServerName)>0);
return S_OK;
}
STDMETHODIMP CMichelleCTI::get_ErrType(ERRORTYPES *pVal)
{
*pVal=m_ErrType;
return S_OK;
}
STDMETHODIMP CMichelleCTI::get_ErrCode(long *pVal)
{
*pVal=m_lErrCode;
return S_OK;
}
STDMETHODIMP CMichelleCTI::get_ErrMsg(BSTR *pVal)
{
// TODO: Add your implementation code here
*pVal=C2B(m_ErrMsg.c_str());
return S_OK;
}
//initialize the cti server for dns' login
STDMETHODIMP_(BOOL) CMichelleCTI::Initialize(PBXTYPES pbxtype, BSTR server, int port, BSTR name, BSTR pass)
{
//PARAMETERS:
// pbxtype:
// server: the server name
// port: the network type
// name: logicalIdentifier
memset(&m_strServerName,0,sizeof(m_strServerName));
memset(&m_strLogicalIdentifier,0,sizeof(m_strLogicalIdentifier));
memset(&m_strNetType,0,sizeof(m_strNetType));
m_dnlist.clear();
ClearAPIInfo();
BOOL bRet=FALSE;
try
{
if (B2C(server,m_strServerName,sizeof(m_strServerName))&&
B2C(name,m_strLogicalIdentifier,sizeof(m_strLogicalIdentifier)))
{
switch (port)
{
case NT_NetBIOS_NetBEUI:
strcpy(m_strNetType,"ncacn_nb_nb");
break;
case NT_TCPIP:
strcpy(m_strNetType,"ncacn_ip_tcp");
break;
case NT_DECnet:
strcpy(m_strNetType,"ncacn_dnet_nsp");
break;
case NT_NetBIOS_TCPIP:
strcpy(m_strNetType,"ncacn_nb_tcp");
break;
case NT_NAMED_PIPE:
strcpy(m_strNetType,"ncacn_np");
break;
case NT_SPX:
strcpy(m_strNetType,"ncacn_spx");
break;
default:
strcpy(m_strNetType,"ncacn_ip_tcp");
}
bRet=TRUE;
}else
{
m_ErrType=ET_USER;
m_ErrMsg="Cti initialize failed.";
m_lErrCode=-1;
}
}catch(...)
{
m_ErrType=ET_USER;
m_ErrMsg="Cti initialize failed.";
m_lErrCode=-1;
}
return bRet;
}
STDMETHODIMP_(void) CMichelleCTI::Uninitialize()
{
ClearAPIInfo();
CleanDNList();
memset(&m_strServerName,0,sizeof(m_strServerName));
memset(&m_strLogicalIdentifier,0,sizeof(m_strLogicalIdentifier));
memset(&m_strNetType,0,sizeof(m_strNetType));
return;
}
STDMETHODIMP_(LPDN) CMichelleCTI::RegisterDN(BSTR dn, ADDRTYPES type, BSTR acdpos)
{
//parameters:
//dn: the directory number
//type: the ctcAssignData.DeviceType
ClearAPIInfo();
CDirectoryNumber *pExDN = NULL, *pPosDN = NULL;
IDirectoryNumber *iExDN = NULL, *iPosDN = NULL;
char dnBuf[ctcMaxDnLen]={0};
char acdposBuf[ctcMaxDnLen]={0};
if (B2C(dn,dnBuf,ctcMaxDnLen))
{
if (SearchRegisterdDN(dnBuf)==NULL)
{// This dn can be registered
if(SUCCEEDED(CreateClass(&pExDN, &iExDN)))
{
ctcChanId chanelID;
struct ctcAssignData assignData={0};
assignData.APIversion=ctcK_CurrentVersion;
strcpy((char*)assignData.deviceDN,dnBuf);
switch(type)
{
case AT_DN:
case AT_Position:
assignData.deviceType=ctcK_Dn;
break;
default:
assignData.deviceType=-1;
break;
}
DWORD dwStatus=ctcAssign(&chanelID,
&assignData,
m_strServerName,
m_strLogicalIdentifier,
m_strNetType);
if (ctcSuccess==dwStatus)
{
dwStatus=ctcSetMonitor(chanelID, ctcK_On);
if (ctcSuccess==dwStatus)
{
if (pExDN->Initialize(dnBuf,chanelID,type,this))
{
iExDN->AddRef();
EnterCriticalSection(&m_csList);
m_dnlist.push_back(pExDN);
LeaveCriticalSection(&m_csList);
if(acdpos)
{
iPosDN = RegisterDN(acdpos, AT_Position, NULL);
if(iPosDN)
{
pPosDN = I2C(iPosDN);
ATLASSERT(pPosDN);
pExDN->m_posDN = pPosDN;
pPosDN->m_extDN = pExDN;
}
else
{
EnterCriticalSection(&m_csList);
m_dnlist.remove(pExDN);
LeaveCriticalSection(&m_csList);
UnregisterDN(iExDN);
iExDN->Release();
iExDN = NULL;
}
}
}else
{
m_lErrCode=CTC_DN_INITIALIZE_FAIL;
m_ErrType=ET_USER;
m_ErrMsg="DN initialize failed.";
iExDN->Release();
iExDN = NULL;
}
}else
{
m_lErrCode=dwStatus;
m_ErrMsg="set monitor on failed";
m_ErrType=ET_USER;
}
}else
{
m_lErrCode=dwStatus;
m_ErrMsg="ctcAssign failed.";
m_ErrType=ET_USER;
}
}
}else
{//This dn has been registerd
m_lErrCode=CTC_DN_REGISTERED;
m_ErrType=ET_USER;
m_ErrMsg="This DN can't be registered twince.";
}
}
return iExDN;
}
STDMETHODIMP_(void) CMichelleCTI::UnregisterDN(LPDN dn)
{
ClearAPIInfo();
CDirectoryNumber *pDN = I2C(dn);
if (!dn || !pDN) return;
if(pDN->m_posDN)
{
UnregisterDN(pDN->m_posDN);
pDN->m_posDN=NULL;
}
EnterCriticalSection(&m_csList);
m_dnlist.remove(pDN);
LeaveCriticalSection(&m_csList);
ctcChanId chanelID=pDN->m_channelId;
ctcSetMonitor(chanelID, ctcK_Off);
ctcDeassign(chanelID);
pDN->Uninitialize();
pDN->Release();
return ;
}
STDMETHODIMP_(BOOL) CMichelleCTI::Init(BSTR server, int port)
{
BOOL bRet=FALSE;
return bRet;
}
STDMETHODIMP_(void) CMichelleCTI::Uninit()
{
return ;
}
STDMETHODIMP_(void) CMichelleCTI::Login(BSTR AgentID)
{
return ;
}
STDMETHODIMP_(void) CMichelleCTI::ReportStatus(BSTR AgentID, AGENTSTATES AgentState)
{
return ;
}
STDMETHODIMP_(void) CMichelleCTI::ReportConfirm(BOOL confirm)
{
return ;
}
STDMETHODIMP_(void) CMichelleCTI::ReportResult(BSTR ReqID, BOOL result, BSTR reason)
{
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -