?? tapiphonedlg.cpp
字號(hào):
{
//
// 如果沒有 owner 權(quán)限,乎略這次撥入
//
pCall->Release();
//
// 注意:我們?cè)?CTAPIEventNotification::Event() 中調(diào)用了 AddRef()
//
pEvent->Release();
return S_OK;
}
//
//用來獲得乎叫方信息, 用于來電顯示
//
BSTR bstrCallerName, bstrCallerNum;
BSTR bstrCallidName, bstrCallidNum;
BSTR bstrConnectName, bstrConnectNum;
CString strCallerName, strCallerNum;
CString strCallidName, strCallidNum;
CString strConnectName, strConnectNum;
//The name of the caller.
pCall->get_CallInfoString(CIS_CALLERIDNAME, &bstrCallerName);
strCallerName = bstrCallerName;
//The number of the caller.
pCall->get_CallInfoString(CIS_CALLERIDNUMBER, &bstrCallerNum);
strCallerNum = bstrCallerNum;
//The name of the called location.
pCall->get_CallInfoString(CIS_CALLEDIDNAME, &bstrCallidName);
strCallidName = bstrCallidName;
//The number of the called location.
pCall->get_CallInfoString(CIS_CALLEDIDNUMBER, &bstrCallidNum);
strCallidNum = strCallidNum;
//The name of the connected location.
pCall->get_CallInfoString(CIS_CONNECTEDIDNAME, &bstrConnectName);
strConnectName = bstrConnectName;
//The number of the connected location.
pCall->get_CallInfoString(CIS_CONNECTEDIDNUMBER, &bstrConnectNum);
strConnectNum = bstrConnectNum;
if( strCallidNum.IsEmpty() )
m_valCallerNum = "呼叫方號(hào)碼: 無法獲得";
else
m_valCallerNum = "呼叫方號(hào)碼: " + strCallidNum;
UpdateData(FALSE);
//
// 獲得 ITBasicCallControl 接口并把它保存在成員變量 ppCall 中
//
ITBasicCallControl * ppCall;
hr = pCall->QueryInterface( IID_ITBasicCallControl,
(void**)&ppCall );
m_Tapi.m_pCall = ppCall;
pCall->Release();
if ( SUCCEEDED(hr) )
{
//
// 更新 UI
//
m_btPickup.EnableWindow();
m_btDisconnect.EnableWindow();
SetStatusMessage("有電話呼入...");
}//end if
}
}//end if
return S_OK;
}//end function
/////////////////////////////////////////////////////////////////////////////////////
// DoCallState
//
// 功能:處理 TE_STATE 事件,有某種狀態(tài)改變時(shí)觸發(fā)此事件,比如只有狀態(tài)為 CS_OFFERING
// 時(shí)才可以應(yīng)答
/////////////////////////////////////////////////////////////////////////////////////
HRESULT CtapiPhoneDlg::DoCallState(IDispatch* pEvent)
{
HRESULT hr;
CALL_STATE cs;
ITCallStateEvent * pCallStateEvent;
//
// 獲得接口
//
hr = pEvent->QueryInterface( IID_ITCallStateEvent, (void **)&pCallStateEvent );
if ( FAILED(hr) )
{
return E_FAIL;
}
//
// 檢測(cè)是否是同一個(gè) Call - 如果不是,不處理這個(gè)事件
//
if(false == m_Tapi.SameCall(pCallStateEvent))
{
pCallStateEvent->Release();
return hr;
}
//
// 通過 ITCallStateEvent 獲得當(dāng)前狀態(tài)
//
hr = pCallStateEvent->get_State( &cs );
//
// 釋放接口
//
pCallStateEvent->Release();
if ( FAILED(hr) )
{
return E_FAIL;
}
//
// 如果當(dāng)前狀態(tài)是 offering,則應(yīng)答電話,同時(shí)更新 UI
//
if (CS_OFFERING == cs)
{
if (m_AutoAnswer) //如果選種自動(dòng)應(yīng)答
{
OnBnClickedBtnPickup();
}
else //選擇手動(dòng)應(yīng)答
{
SetStatusMessage("請(qǐng)點(diǎn)擊接聽按鈕接聽電話");
}
}
else if (CS_DISCONNECTED == cs)
{
OnBnClickedBtnDisconnect();
m_Tapi.ReleaseTheCall();
}
else if (CS_CONNECTED == cs)
{
//
// 不作處理
//
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////
// DoCallMedia
//
// 功能:處理 TE_MEDIA 事件,TE_CALLMEDIA 觸發(fā) Media 事件,對(duì)應(yīng)接口:ITCallMediaEvent
/////////////////////////////////////////////////////////////////////////////////////
HRESULT CtapiPhoneDlg::DoCallMedia(
IN IDispatch * pEvent)
{
CALL_MEDIA_EVENT cme = CME_STREAM_INACTIVE;
ITCallMediaEvent * pCallMediaEvent = NULL;
//
// 檢測(cè)當(dāng)前 Call 是否有效
//
if(NULL == m_Tapi.m_pCall)
{
return E_UNEXPECTED;
}
//
// 獲得接口
//
HRESULT hr = pEvent->QueryInterface( IID_ITCallMediaEvent, (void **)&pCallMediaEvent );
if(FAILED(hr))
{
MessageBox("ITCallMediaEvent, 獲取接口失敗!");
return hr;
}
//
// 獲得我們檢測(cè)到的 MediaEvent 具體類型
//
hr = pCallMediaEvent->get_Event( &cme );
if(FAILED(hr))
{
pCallMediaEvent->Release();
MessageBox("ITCallMediaEvent, but failed to get_Event");
return hr;
}
switch ( cme )
{
//
// 這是我們需要處理的唯一的事件
//
case CME_STREAM_ACTIVE:
{
//
// 獲得當(dāng)前活動(dòng)的終端
//
ITTerminal * pTerminal = NULL;
hr = m_Tapi.GetTerminalFromStreamEvent(pCallMediaEvent, &pTerminal);
if ( FAILED(hr) )
{
MessageBox("ITCallMediaEvent: GetTerminalFromStreamEvent failed");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
break;
}
//
// 根據(jù)終端的方向進(jìn)行處理
//
TERMINAL_DIRECTION td;
hr = pTerminal->get_Direction( &td);
//
// 釋放接口
//
pTerminal->Release();
if ( FAILED(hr) )
{
MessageBox("ITCallMediaEvent: get_Direction failed");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
break;
}
//
// 方向是 TD_CAPTURE:播放聲音文件
//
if ( TD_CAPTURE == td && NULL != m_Tapi.m_pPlayFileTerm)
{
ITMediaControl* pITMC = NULL;
hr = m_Tapi.m_pPlayFileTerm->QueryInterface(IID_ITMediaControl, (void**)&pITMC);
//
// 獲得 ITMediaControl,開始發(fā)送媒體流
//
if(FAILED(hr))
{
MessageBox("ITCallMediaEvent: m_pPlayFileTerm QI for ITMediaControl failed");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
break;
}
//
// 開始發(fā)送
//
hr = pITMC->Start();
pITMC->Release();
if(SUCCEEDED(hr))
{
SetStatusMessage("正在播放音頻文件... ");
}
else
{
MessageBox("ITCallMediaEvent: ITMediaControl::Start() failed");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
}
}
break;
}
default:
break;
}
//
// 釋放接口
//
pCallMediaEvent->Release();
return hr;
}
///////////////////////////////////////////////////////////////////
// DoFileEvent
//
//
// TE_FILETERMINAL 文件終端事件. pEvent: ITFileTerminalEvent
// 說明:只有 WinXP 下才支持
///////////////////////////////////////////////////////////////////
HRESULT CtapiPhoneDlg::DoFileEvent(
IN IDispatch * pEvent)
{
//
// 檢測(cè)當(dāng)前 Call 是否有效
//
if(NULL == m_Tapi.m_pCall)
{
return E_UNEXPECTED;
}
ITFileTerminalEvent* pITFTEvent = NULL;
HRESULT hr = pEvent->QueryInterface( IID_ITFileTerminalEvent,
reinterpret_cast<void **>(&pITFTEvent) );
if (FAILED(hr))
{
//
// 致命錯(cuò)誤 - 無法繼續(xù)下去 - 切斷此次通話
//
MessageBox("ITFileTerminalEvent, 獲得接口失敗!");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 獲得狀態(tài) - ???????因?yàn)槲覀円_保聲音文件未被其它程序使用
//
TERMINAL_MEDIA_STATE ftState = TMS_ACTIVE;
hr = pITFTEvent->get_State(&ftState);
if(FAILED(hr))
{
//
// 致命錯(cuò)誤 - 無法繼續(xù)下去 - 切斷此次通話
//
pITFTEvent->Release();
MessageBox("ITFileTerminalEvent, but failed to get_State");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 我們對(duì) TMS_IDLE 感興趣,因?yàn)槲覀円V共シ? //
if(ftState != TMS_IDLE)
{
pITFTEvent->Release();
return hr;
}
//
// 獲得終端
//
ITTerminal *pTerminal = NULL;
hr = pITFTEvent->get_Terminal(&pTerminal);
//
// 不再需要這個(gè)接口
//
pITFTEvent->Release();
if(FAILED(hr))
{
//
// 致命錯(cuò)誤 - 無法繼續(xù)下去 - 切斷此次通話
//
MessageBox("ITFileTerminalEvent, but failed to get_Terminal");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
TERMINAL_DIRECTION td;
hr = pTerminal->get_Direction( &td);
pTerminal->Release();
if(FAILED(hr))
{
//
// 致命錯(cuò)誤 - 無法繼續(xù)下去 - 切斷此次通話
//
MessageBox("ITFileTerminalEvent, but failed to get_Direction");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
if((td == TD_CAPTURE) && (NULL != m_Tapi.m_pPlayFileTerm))
{
SetStatusMessage("通話中...");
//
// unselect playback - 因?yàn)椴シ乓呀?jīng)完成
//
ITBasicCallControl2 *pITBCC2 = NULL;
hr = m_Tapi.m_pCall->QueryInterface(IID_ITBasicCallControl2, (void**)&pITBCC2);
if(FAILED(hr))
{
//
// 致命錯(cuò)誤 - 無法繼續(xù)下去 - 切斷此次通話
//
MessageBox("ITFileTerminalEvent, but failed to QI for ITBasicCallControl2");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 使用 ITBasicCallControl2 方法 - 要比列舉媒體流、終端容易的多
//
hr = pITBCC2->UnselectTerminalOnCall( m_Tapi.m_pPlayFileTerm);
m_Tapi.m_pPlayFileTerm->Release();
m_Tapi.m_pPlayFileTerm = NULL;
pITBCC2->Release();
if(FAILED(hr))
{
//
// 致命錯(cuò)誤 - 無法繼續(xù)下去 - 切斷此次通話
//
MessageBox("ITFileTerminalEvent, but failed to ITBasicCallControl2::UnselectTerminalOnCall");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////
// DigitEvent
//
// 處理 TE_DIGITEVENT 事件,TE_DIGITEVENT 時(shí)觸發(fā),對(duì)應(yīng)接口 ITDigitDetectionEvent
/////////////////////////////////////////////////////////////////////////////////////
HRESULT CtapiPhoneDlg::DoDigitEvent(IN IDispatch* pEvent)
{
ITDigitDetectionEvent* pDigitEvent;
//
// 獲得接口
//
pEvent->QueryInterface(IID_ITDigitDetectionEvent, (void**)&pDigitEvent);
unsigned char dig;
pDigitEvent->get_Digit(&dig);
//
// 跟據(jù)用戶不同按鍵選擇做出不同的回應(yīng)
//
switch (dig)
{
case '1':
// 播放聲音1
m_Tapi.PreparePlay(strFileName1);
break;
case '2':
// 播放聲間2
m_Tapi.PreparePlay(strFileName2);
break;
case '3':
// 留言
m_Tapi.StartRecord();
default:
break;
}
return S_OK;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -