使用C++Builder快速實現(xiàn)自己的專用IVR 
                  
                   2009/06/04
                  1.涉及的組件 
                    CTIX控件。
                  
                  2.應(yīng)用環(huán)境
                    使用C++Builder開發(fā)固定流程的IVR。
                  
                  3.目標(biāo)功能
                    來話后放音,循環(huán)放音完成后掛機。
                  
                  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創(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的實例
                  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);
                  //線程開始運行
                  pThd->Resume();
                  }
                  
                  //掛機通知事件處理函數(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)造時傳入的CallID
                  CALL *m_pOriginalCall; //保存線程對應(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)造時傳入的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)線程錯誤:")
                  + AnsiString(errstr));
                  }
                  
                  //應(yīng)答來話
                  ret = m_pOriginalCall->Answer();
                  if (ret != rtSUCC)
                  {
                  BSTR errstr = m_pOriginalCall->LastErrStr;
                  throw Exception(AnsiString("應(yīng)答來話錯誤:")
                  + AnsiString(errstr));
                  }
                  }
                  catch(Exception& e)
                  {
                  if (errstr != NULL)
                  {
                  //COM返回的BSTR由用戶釋放
                  SysFreeString(errstr);
                  }
                  //輸出錯誤消息e.Message
                  }
                  
                  
                  //-------------- 業(yè)務(wù)過程 ----------------------
                  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由用戶釋放
                  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)
                  {
                  //釋放線程關(guān)聯(lián)的CALL對象
                  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查找線程對象
                  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論壇報道
                  
 相關(guān)鏈接:
漳平市|
祁东县|
乳山市|
隆尧县|
郸城县|
呼伦贝尔市|
雅江县|
年辖:市辖区|
讷河市|
徐汇区|
夏河县|
永吉县|
肇州县|
习水县|
阿瓦提县|
枝江市|
广元市|
海丰县|
黑山县|
元朗区|
丽江市|
浠水县|
资阳市|
河曲县|
平安县|
睢宁县|
南召县|
邢台县|
齐齐哈尔市|
页游|
江达县|
垦利县|
岫岩|
金秀|
饶阳县|
金川县|
安福县|
安徽省|
土默特右旗|
沙坪坝区|
凤庆县|