首页
>>
厂商
>>
CT中间件厂商
>>
朗深技术
使用C++Builder快速实现自己的专用IVR
2009/06/04
1.涉及的组件
CTIX控件。
2.应用环境
使用C++Builder开发固定流程的IVR。
3.目标功能
来话后放音,循环放音完成后挂机。
4.主要代码片段
////////////////////////////////////////////////////////////
Part 1: 主窗口类
class TFrmCTIX : public TForm
{
__published:
TCTI *CTI1; //CTIX实例
void __fastcall FormDestroy(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall CTI1CallIncome(TObject *Sender, int Tag,
CALL *ACall, BSTR Ano, BSTR Bno);
void __fastcall CTI1CallEnd(TObject *Sender, int Tag,
CALL *ACall);
private:
SCPMANAGER *m_pMainSCPManager; //主SCPMANAGER
};
//Form创建
void __fastcall TFrmCTIX::FormCreate(TObject *Sender)
{
//COM 环境初始化
CoInitialize(NULL);
//创建线程管理器
g_pThreadManager = new CThreadManager();
//连接到CTI引擎
CTI1->Start(WideString("192.168.1.131").c_bstr(), 10088);
//获得主SCPMANAGER,CTI1是CTIX的实例
m_pMainSCPManager = CTI1->GetSCPManager();
}
//Form销毁
void __fastcall TFrmCTIX::FormDestroy(TObject *Sender)
{
//释放获得的SCPMANAGER
m_pMainSCPManager->Free();
//从CTI引擎断开连接
CTI1->Stop();
//释放CTIX内存
CTI1->Finalize();
delete g_pThreadManager;
//COM环境释放
CoUninitialize();
}
//来话通知事件处理函数
void __fastcall TFrmCTIX::CTI1CallIncome(TObject *Sender, int Tag,
CALL *ACall, BSTR Ano, BSTR Bno)
{
TAnswerCallThread* pThd = NULL;
//以挂起方式创建应答线程,传入CallID
pThd = new TAnswerCallThread(true, ACall->CallID);
//线程开始运行
pThd->Resume();
}
//挂机通知事件处理函数
void __fastcall TFrmCTIX::CTI1CallEnd(TObject *Sender, int Tag,
CALL *ACall)
{
//Tag是CALL关联的线程ID
//(线程ID在AnswerCallThread中通过SetCurrentProcess方法设置)
//通过线程ID找到线程
TThread *pThd = g_pThreadManager->FindThreadByThreadID(Tag);
if (pThd != NULL)
{
//调用线程结束方法,结束线程
pThd->Terminate();
}
}
////////////////////////////////////////////////////////////////////////
Part 2:业务线程类
class TAnswerCallThread : public TThread
{
private:
SCPMANAGER *m_pThreadSCPManager; //线程用的SCPMANAGER
int OriginalCallID; //保存线程构造时传入的CallID
CALL *m_pOriginalCall; //保存线程对应的CALL
protected:
void __fastcall Execute();
public:
__fastcall TAnswerCallThread(bool CreateSuspended, int callid);
};
//线程构造函数
__fastcall TAnswerCallThread::TAnswerCallThread(
bool CreateSuspended, int callid) : TThread(CreateSuspended)
{
m_pThreadSCPManager = NULL;
//保存线程构造时传入的CallID
m_OriginalCallID = callid;
//结束后释放线程
FreeOnTerminate = true;
//将线程加入到线程管理器
g_pThreadManager->AddThread(this);
}
//线程主执行函数
void __fastcall TAnswerCallThread::Execute()
{
int ret;
BSTR errstr = NULL;
//准备线程COM环境
CoInitialize(NULL);
//-------------- 应答过程 ----------------------
try
{
//获得线程的SCPMANAGER
m_pThreadSCPManager = FrmCTIX->CTI1->GetSCPManager();
if (m_pThreadSCPManager == NULL)
{
throw Exception("GetSCPManager fail.");
}
//获得线程关联的呼叫
m_pOriginalCall = m_pThreadSCPManager->
FindCallByID(m_OriginalCallID);
if (m_pOriginalCall == NULL)
{
throw Exception("FindCallByID fail.");
}
//设置呼叫关联的线程ID
ret = m_pOriginalCall->AttachCurrentProcess(ThreadID);
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("设置关联线程错误:")
+ AnsiString(errstr));
}
//应答来话
ret = m_pOriginalCall->Answer();
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("应答来话错误:")
+ AnsiString(errstr));
}
}
catch(Exception& e)
{
if (errstr != NULL)
{
//COM返回的BSTR由用户释放
SysFreeString(errstr);
}
//输出错误消息e.Message
}
//-------------- 业务过程 ----------------------
errstr = NULL;
try
{
int taskid;
//异步循环放音,直到StopOP或挂机
ret = m_pOriginalCall->Play(true, true,
WideString("D:\\vox\\welcome.vox").c_bstr(), &taskid);
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("放音错误:")
+ AnsiString(errstr));
}
//等待30秒
Sleep(30000L);
//停止放音
ret = m_pOriginalCall->StopOP(taskid);
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("停止放音错误:")
+ AnsiString(errstr));
}
}
catch(Exception& e)
{
if (errstr != NULL)
{
//COM返回的BSTR由用户释放
SysFreeString(errstr);
}
//输出错误消息e.Message
}
//呼叫挂机
ret = m_pOriginalCall->OnHook();
//-------------- 等待挂机事件 ------------------
while (Terminated == false)
{
Sleep(100L);
}
//-------------- 清理获得的COM对象 --------------
if (m_pThreadSCPManager != NULL)
{
//释放线程的SCPMANAGER
m_pThreadSCPManager->Free();
}
if (m_pOriginalCall != NULL)
{
//释放线程关联的CALL对象
m_pOriginalCall->Free();
}
//将线程从线程管理器中删除
g_pThreadManager->RemoveThreadByThreadID(ThreadID);
//释放线程COM环境
CoUninitialize();
}
///////////////////////////////////////////////////////////////////////
Part 3 线程管理器类
class CThreadManager
{
private:
TBucketList *m_pThreadList; //线程列表哈希表
TCriticalSection *m_pListLocker; //线程锁
public:
CThreadManager();
~CThreadManager();
//将线程加入线程表
void AddThread(TThread *pThd);
//根据线程ID从线程中移除
void RemoveThreadByThreadID(int ThreadID);
//根据线程ID查找线程对象
TThread *FindThreadByThreadID(int ThreadID);
};
//线程管理器构造
CThreadManager::CThreadManager()
{
m_pThreadList = new TBucketList(bl16);
m_pListLocker = new TCriticalSection();
}
//线程管理器析构
CThreadManager::~CThreadManager()
{
delete m_pThreadList;
delete m_pListLocker;
}
//加入线程列表
void CThreadManager::AddThread(TThread *pThd)
{
//多线程访问列表,需要加锁
m_pListLocker->Acquire();
try
{
m_pThreadList->Add((void*)(pThd->ThreadID), pThd);
}
catch(...)
{
}
m_pListLocker->Release();
}
//从线程列表中删除
void CThreadManager::RemoveThreadByThreadID(int ThreadID)
{
//多线程访问列表,需要加锁
m_pListLocker->Acquire();
try
{
TThread *pThd = NULL;
if (m_pThreadList->Find((void*)ThreadID, (void*)pThd))
{
m_pThreadList->Remove((void*)ThreadID);
}
}
catch(...)
{
}
m_pListLocker->Release();
}
//根据线程ID查找线程
TThread * CThreadManager::FindThreadByThreadID(int ThreadID)
{
TThread *pRetThd = NULL;
//多线程访问列表,需要加锁
m_pListLocker->Acquire();
try
{
TThread *pThd = NULL;
if (m_pThreadList->Find((void*)ThreadID, (void*)pThd))
{
pRetThd = pThd;
}
}
catch(...)
{
}
m_pListLocker->Release();
return pRetThd;
}
CTI论坛报道
相关链接:
UniMedia Script++常用对象及使用
2009-06-03
UniMedia MSIX座席控件的使用
2009-06-02
UniMedia MSIX座席控件Delphi调用实例解析
2009-06-01
UniMedia IDE集成环境文件操作实例解析
2009-05-22
UniMedia IDE集成环境调用DLL动态库实例解析
2009-05-22