使用C++Builder快速實(shí)現(xiàn)自己的專用IVR
2009/06/04
1.涉及的組件
CTIX控件。
2.應(yīng)用環(huán)境
使用C++Builder開發(fā)固定流程的IVR。
3.目標(biāo)功能
來話后放音,循環(huán)放音完成后掛機(jī)。
4.主要代碼片段
////////////////////////////////////////////////////////////
Part 1: 主窗口類
class TFrmCTIX : public TForm
{
__published:
TCTI *CTI1; //CTIX實(shí)例
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創(chuàng)建
void __fastcall TFrmCTIX::FormCreate(TObject *Sender)
{
//COM 環(huán)境初始化
CoInitialize(NULL);
//創(chuàng)建線程管理器
g_pThreadManager = new CThreadManager();
//連接到CTI引擎
CTI1->Start(WideString("192.168.1.131").c_bstr(), 10088);
//獲得主SCPMANAGER,CTI1是CTIX的實(shí)例
m_pMainSCPManager = CTI1->GetSCPManager();
}
//Form銷毀
void __fastcall TFrmCTIX::FormDestroy(TObject *Sender)
{
//釋放獲得的SCPMANAGER
m_pMainSCPManager->Free();
//從CTI引擎斷開連接
CTI1->Stop();
//釋放CTIX內(nèi)存
CTI1->Finalize();
delete g_pThreadManager;
//COM環(huán)境釋放
CoUninitialize();
}
//來話通知事件處理函數(shù)
void __fastcall TFrmCTIX::CTI1CallIncome(TObject *Sender, int
Tag,
CALL *ACall, BSTR Ano, BSTR Bno)
{
TAnswerCallThread* pThd = NULL;
//以掛起方式創(chuàng)建應(yīng)答線程,傳入CallID
pThd = new TAnswerCallThread(true, ACall->CallID);
//線程開始運(yùn)行
pThd->Resume();
}
//掛機(jī)通知事件處理函數(shù)
void __fastcall TFrmCTIX::CTI1CallEnd(TObject *Sender, int Tag,
CALL *ACall)
{
//Tag是CALL關(guān)聯(lián)的線程ID
//(線程ID在AnswerCallThread中通過SetCurrentProcess方法設(shè)置)
//通過線程ID找到線程
TThread *pThd = g_pThreadManager->FindThreadByThreadID(Tag);
if (pThd != NULL)
{
//調(diào)用線程結(jié)束方法,結(jié)束線程
pThd->Terminate();
}
}
////////////////////////////////////////////////////////////////////////
Part 2:業(yè)務(wù)線程類
class TAnswerCallThread : public TThread
{
private:
SCPMANAGER *m_pThreadSCPManager; //線程用的SCPMANAGER
int OriginalCallID; //保存線程構(gòu)造時(shí)傳入的CallID
CALL *m_pOriginalCall; //保存線程對(duì)應(yīng)的CALL
protected:
void __fastcall Execute();
public:
__fastcall TAnswerCallThread(bool CreateSuspended, int callid);
};
//線程構(gòu)造函數(shù)
__fastcall TAnswerCallThread::TAnswerCallThread(
bool CreateSuspended, int callid) : TThread(CreateSuspended)
{
m_pThreadSCPManager = NULL;
//保存線程構(gòu)造時(shí)傳入的CallID
m_OriginalCallID = callid;
//結(jié)束后釋放線程
FreeOnTerminate = true;
//將線程加入到線程管理器
g_pThreadManager->AddThread(this);
}
//線程主執(zhí)行函數(shù)
void __fastcall TAnswerCallThread::Execute()
{
int ret;
BSTR errstr = NULL;
//準(zhǔn)備線程COM環(huán)境
CoInitialize(NULL);
//-------------- 應(yīng)答過程 ----------------------
try
{
//獲得線程的SCPMANAGER
m_pThreadSCPManager = FrmCTIX->CTI1->GetSCPManager();
if (m_pThreadSCPManager == NULL)
{
throw Exception("GetSCPManager fail.");
}
//獲得線程關(guān)聯(lián)的呼叫
m_pOriginalCall = m_pThreadSCPManager->
FindCallByID(m_OriginalCallID);
if (m_pOriginalCall == NULL)
{
throw Exception("FindCallByID fail.");
}
//設(shè)置呼叫關(guān)聯(lián)的線程ID
ret = m_pOriginalCall->AttachCurrentProcess(ThreadID);
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("設(shè)置關(guān)聯(lián)線程錯(cuò)誤:")
+ AnsiString(errstr));
}
//應(yīng)答來話
ret = m_pOriginalCall->Answer();
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("應(yīng)答來話錯(cuò)誤:")
+ AnsiString(errstr));
}
}
catch(Exception& e)
{
if (errstr != NULL)
{
//COM返回的BSTR由用戶釋放
SysFreeString(errstr);
}
//輸出錯(cuò)誤消息e.Message
}
//-------------- 業(yè)務(wù)過程 ----------------------
errstr = NULL;
try
{
int taskid;
//異步循環(huán)放音,直到StopOP或掛機(jī)
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("放音錯(cuò)誤:")
+ AnsiString(errstr));
}
//等待30秒
Sleep(30000L);
//停止放音
ret = m_pOriginalCall->StopOP(taskid);
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("停止放音錯(cuò)誤:")
+ AnsiString(errstr));
}
}
catch(Exception& e)
{
if (errstr != NULL)
{
//COM返回的BSTR由用戶釋放
SysFreeString(errstr);
}
//輸出錯(cuò)誤消息e.Message
}
//呼叫掛機(jī)
ret = m_pOriginalCall->OnHook();
//-------------- 等待掛機(jī)事件 ------------------
while (Terminated == false)
{
Sleep(100L);
}
//-------------- 清理獲得的COM對(duì)象 --------------
if (m_pThreadSCPManager != NULL)
{
//釋放線程的SCPMANAGER
m_pThreadSCPManager->Free();
}
if (m_pOriginalCall != NULL)
{
//釋放線程關(guān)聯(lián)的CALL對(duì)象
m_pOriginalCall->Free();
}
//將線程從線程管理器中刪除
g_pThreadManager->RemoveThreadByThreadID(ThreadID);
//釋放線程COM環(huán)境
CoUninitialize();
}
///////////////////////////////////////////////////////////////////////
Part 3 線程管理器類
class CThreadManager
{
private:
TBucketList *m_pThreadList; //線程列表哈希表
TCriticalSection *m_pListLocker; //線程鎖
public:
CThreadManager();
~CThreadManager();
//將線程加入線程表
void AddThread(TThread *pThd);
//根據(jù)線程ID從線程中移除
void RemoveThreadByThreadID(int ThreadID);
//根據(jù)線程ID查找線程對(duì)象
TThread *FindThreadByThreadID(int ThreadID);
};
//線程管理器構(gòu)造
CThreadManager::CThreadManager()
{
m_pThreadList = new TBucketList(bl16);
m_pListLocker = new TCriticalSection();
}
//線程管理器析構(gòu)
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();
}
//根據(jù)線程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論壇報(bào)道
相關(guān)鏈接: