使用C++Builder快速實(shí)現自己的專(zhuān)用IVR
2009/06/04
1.涉及的組件
CTIX控件。
2.應用環(huán)境
使用C++Builder開(kāi)發(fā)固定流程的IVR。
3.目標功能
來(lái)話(huà)后放音,循環(huán)放音完成后掛機。
4.主要代碼片段
////////////////////////////////////////////////////////////
Part 1: 主窗口類(lèi)
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 )建線(xiàn)程管理器
g_pThreadManager = new CThreadManager();
//連接到CTI引擎
CTI1->Start(WideString("192.168.1.131").c_bstr(), 10088);
//獲得主SCPMANAGER,CTI1是CTIX的實(shí)例
m_pMainSCPManager = CTI1->GetSCPManager();
}
//Form銷(xiāo)毀
void __fastcall TFrmCTIX::FormDestroy(TObject *Sender)
{
//釋放獲得的SCPMANAGER
m_pMainSCPManager->Free();
//從CTI引擎斷開(kāi)連接
CTI1->Stop();
//釋放CTIX內存
CTI1->Finalize();
delete g_pThreadManager;
//COM環(huán)境釋放
CoUninitialize();
}
//來(lái)話(huà)通知事件處理函數
void __fastcall TFrmCTIX::CTI1CallIncome(TObject *Sender, int
Tag,
CALL *ACall, BSTR Ano, BSTR Bno)
{
TAnswerCallThread* pThd = NULL;
//以?huà)炱鸱绞絼?chuàng )建應答線(xiàn)程,傳入CallID
pThd = new TAnswerCallThread(true, ACall->CallID);
//線(xiàn)程開(kāi)始運行
pThd->Resume();
}
//掛機通知事件處理函數
void __fastcall TFrmCTIX::CTI1CallEnd(TObject *Sender, int Tag,
CALL *ACall)
{
//Tag是CALL關(guān)聯(lián)的線(xiàn)程ID
//(線(xiàn)程ID在A(yíng)nswerCallThread中通過(guò)SetCurrentProcess方法設置)
//通過(guò)線(xiàn)程ID找到線(xiàn)程
TThread *pThd = g_pThreadManager->FindThreadByThreadID(Tag);
if (pThd != NULL)
{
//調用線(xiàn)程結束方法,結束線(xiàn)程
pThd->Terminate();
}
}
////////////////////////////////////////////////////////////////////////
Part 2:業(yè)務(wù)線(xiàn)程類(lèi)
class TAnswerCallThread : public TThread
{
private:
SCPMANAGER *m_pThreadSCPManager; //線(xiàn)程用的SCPMANAGER
int OriginalCallID; //保存線(xiàn)程構造時(shí)傳入的CallID
CALL *m_pOriginalCall; //保存線(xiàn)程對應的CALL
protected:
void __fastcall Execute();
public:
__fastcall TAnswerCallThread(bool CreateSuspended, int callid);
};
//線(xiàn)程構造函數
__fastcall TAnswerCallThread::TAnswerCallThread(
bool CreateSuspended, int callid) : TThread(CreateSuspended)
{
m_pThreadSCPManager = NULL;
//保存線(xiàn)程構造時(shí)傳入的CallID
m_OriginalCallID = callid;
//結束后釋放線(xiàn)程
FreeOnTerminate = true;
//將線(xiàn)程加入到線(xiàn)程管理器
g_pThreadManager->AddThread(this);
}
//線(xiàn)程主執行函數
void __fastcall TAnswerCallThread::Execute()
{
int ret;
BSTR errstr = NULL;
//準備線(xiàn)程COM環(huán)境
CoInitialize(NULL);
//-------------- 應答過(guò)程 ----------------------
try
{
//獲得線(xiàn)程的SCPMANAGER
m_pThreadSCPManager = FrmCTIX->CTI1->GetSCPManager();
if (m_pThreadSCPManager == NULL)
{
throw Exception("GetSCPManager fail.");
}
//獲得線(xiàn)程關(guān)聯(lián)的呼叫
m_pOriginalCall = m_pThreadSCPManager->
FindCallByID(m_OriginalCallID);
if (m_pOriginalCall == NULL)
{
throw Exception("FindCallByID fail.");
}
//設置呼叫關(guān)聯(lián)的線(xiàn)程ID
ret = m_pOriginalCall->AttachCurrentProcess(ThreadID);
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("設置關(guān)聯(lián)線(xiàn)程錯誤:")
+ AnsiString(errstr));
}
//應答來(lái)話(huà)
ret = m_pOriginalCall->Answer();
if (ret != rtSUCC)
{
BSTR errstr = m_pOriginalCall->LastErrStr;
throw Exception(AnsiString("應答來(lái)話(huà)錯誤:")
+ AnsiString(errstr));
}
}
catch(Exception& e)
{
if (errstr != NULL)
{
//COM返回的BSTR由用戶(hù)釋放
SysFreeString(errstr);
}
//輸出錯誤消息e.Message
}
//-------------- 業(yè)務(wù)過(guò)程 ----------------------
errstr = NULL;
try
{
int taskid;
//異步循環(huán)放音,直到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由用戶(hù)釋放
SysFreeString(errstr);
}
//輸出錯誤消息e.Message
}
//呼叫掛機
ret = m_pOriginalCall->OnHook();
//-------------- 等待掛機事件 ------------------
while (Terminated == false)
{
Sleep(100L);
}
//-------------- 清理獲得的COM對象 --------------
if (m_pThreadSCPManager != NULL)
{
//釋放線(xiàn)程的SCPMANAGER
m_pThreadSCPManager->Free();
}
if (m_pOriginalCall != NULL)
{
//釋放線(xiàn)程關(guān)聯(lián)的CALL對象
m_pOriginalCall->Free();
}
//將線(xiàn)程從線(xiàn)程管理器中刪除
g_pThreadManager->RemoveThreadByThreadID(ThreadID);
//釋放線(xiàn)程COM環(huán)境
CoUninitialize();
}
///////////////////////////////////////////////////////////////////////
Part 3 線(xiàn)程管理器類(lèi)
class CThreadManager
{
private:
TBucketList *m_pThreadList; //線(xiàn)程列表哈希表
TCriticalSection *m_pListLocker; //線(xiàn)程鎖
public:
CThreadManager();
~CThreadManager();
//將線(xiàn)程加入線(xiàn)程表
void AddThread(TThread *pThd);
//根據線(xiàn)程ID從線(xiàn)程中移除
void RemoveThreadByThreadID(int ThreadID);
//根據線(xiàn)程ID查找線(xiàn)程對象
TThread *FindThreadByThreadID(int ThreadID);
};
//線(xiàn)程管理器構造
CThreadManager::CThreadManager()
{
m_pThreadList = new TBucketList(bl16);
m_pListLocker = new TCriticalSection();
}
//線(xiàn)程管理器析構
CThreadManager::~CThreadManager()
{
delete m_pThreadList;
delete m_pListLocker;
}
//加入線(xiàn)程列表
void CThreadManager::AddThread(TThread *pThd)
{
//多線(xiàn)程訪(fǎng)問(wèn)列表,需要加鎖
m_pListLocker->Acquire();
try
{
m_pThreadList->Add((void*)(pThd->ThreadID), pThd);
}
catch(...)
{
}
m_pListLocker->Release();
}
//從線(xiàn)程列表中刪除
void CThreadManager::RemoveThreadByThreadID(int ThreadID)
{
//多線(xiàn)程訪(fǎng)問(wèn)列表,需要加鎖
m_pListLocker->Acquire();
try
{
TThread *pThd = NULL;
if (m_pThreadList->Find((void*)ThreadID, (void*)pThd))
{
m_pThreadList->Remove((void*)ThreadID);
}
}
catch(...)
{
}
m_pListLocker->Release();
}
//根據線(xiàn)程ID查找線(xiàn)程
TThread * CThreadManager::FindThreadByThreadID(int ThreadID)
{
TThread *pRetThd = NULL;
//多線(xiàn)程訪(fǎng)問(wèn)列表,需要加鎖
m_pListLocker->Acquire();
try
{
TThread *pThd = NULL;
if (m_pThreadList->Find((void*)ThreadID, (void*)pThd))
{
pRetThd = pThd;
}
}
catch(...)
{
}
m_pListLocker->Release();
return pRetThd;
}
CTI論壇報道
相關(guān)鏈接:
亚洲精品网站在线观看不卡无广告,国产a不卡片精品免费观看,欧美亚洲一区二区三区在线,国产一区二区三区日韩
玉林市|
南岸区|
谷城县|
武城县|
耿马|
河北省|
岳池县|
苗栗市|
通辽市|
松滋市|
兴义市|
潞西市|
胶州市|
鹰潭市|
黎城县|
卓资县|
留坝县|
南投县|
吴川市|
银川市|
荔浦县|
寻乌县|
千阳县|
如东县|
黄大仙区|
峨边|
获嘉县|
景宁|
石台县|
临安市|
勐海县|
连江县|
合川市|
仙游县|
石阡县|
施甸县|
东宁县|
鸡西市|
汉寿县|
翁源县|
固始县|
http://444
http://444
http://444
http://444
http://444
http://444