📄 tapiphonedlg.cpp
字号:
{
//
// 如果没有 owner 权限,乎略这次拨入
//
pCall->Release();
//
// 注意:我们在 CTAPIEventNotification::Event() 中调用了 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 = "呼叫方号码: 无法获得";
else
m_valCallerNum = "呼叫方号码: " + 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 事件,有某种状态改变时触发此事件,比如只有状态为 CS_OFFERING
// 时才可以应答
/////////////////////////////////////////////////////////////////////////////////////
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;
}
//
// 检测是否是同一个 Call - 如果不是,不处理这个事件
//
if(false == m_Tapi.SameCall(pCallStateEvent))
{
pCallStateEvent->Release();
return hr;
}
//
// 通过 ITCallStateEvent 获得当前状态
//
hr = pCallStateEvent->get_State( &cs );
//
// 释放接口
//
pCallStateEvent->Release();
if ( FAILED(hr) )
{
return E_FAIL;
}
//
// 如果当前状态是 offering,则应答电话,同时更新 UI
//
if (CS_OFFERING == cs)
{
if (m_AutoAnswer) //如果选种自动应答
{
OnBnClickedBtnPickup();
}
else //选择手动应答
{
SetStatusMessage("请点击接听按钮接听电话");
}
}
else if (CS_DISCONNECTED == cs)
{
OnBnClickedBtnDisconnect();
m_Tapi.ReleaseTheCall();
}
else if (CS_CONNECTED == cs)
{
//
// 不作处理
//
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////////////
// DoCallMedia
//
// 功能:处理 TE_MEDIA 事件,TE_CALLMEDIA 触发 Media 事件,对应接口:ITCallMediaEvent
/////////////////////////////////////////////////////////////////////////////////////
HRESULT CtapiPhoneDlg::DoCallMedia(
IN IDispatch * pEvent)
{
CALL_MEDIA_EVENT cme = CME_STREAM_INACTIVE;
ITCallMediaEvent * pCallMediaEvent = NULL;
//
// 检测当前 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;
}
//
// 获得我们检测到的 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:
{
//
// 获得当前活动的终端
//
ITTerminal * pTerminal = NULL;
hr = m_Tapi.GetTerminalFromStreamEvent(pCallMediaEvent, &pTerminal);
if ( FAILED(hr) )
{
MessageBox("ITCallMediaEvent: GetTerminalFromStreamEvent failed");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
break;
}
//
// 根据终端的方向进行处理
//
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,开始发送媒体流
//
if(FAILED(hr))
{
MessageBox("ITCallMediaEvent: m_pPlayFileTerm QI for ITMediaControl failed");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
break;
}
//
// 开始发送
//
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)
{
//
// 检测当前 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))
{
//
// 致命错误 - 无法继续下去 - 切断此次通话
//
MessageBox("ITFileTerminalEvent, 获得接口失败!");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 获得状态 - ???????因为我们要确保声音文件未被其它程序使用
//
TERMINAL_MEDIA_STATE ftState = TMS_ACTIVE;
hr = pITFTEvent->get_State(&ftState);
if(FAILED(hr))
{
//
// 致命错误 - 无法继续下去 - 切断此次通话
//
pITFTEvent->Release();
MessageBox("ITFileTerminalEvent, but failed to get_State");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 我们对 TMS_IDLE 感兴趣,因为我们要停止播放
//
if(ftState != TMS_IDLE)
{
pITFTEvent->Release();
return hr;
}
//
// 获得终端
//
ITTerminal *pTerminal = NULL;
hr = pITFTEvent->get_Terminal(&pTerminal);
//
// 不再需要这个接口
//
pITFTEvent->Release();
if(FAILED(hr))
{
//
// 致命错误 - 无法继续下去 - 切断此次通话
//
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))
{
//
// 致命错误 - 无法继续下去 - 切断此次通话
//
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 - 因为播放已经完成
//
ITBasicCallControl2 *pITBCC2 = NULL;
hr = m_Tapi.m_pCall->QueryInterface(IID_ITBasicCallControl2, (void**)&pITBCC2);
if(FAILED(hr))
{
//
// 致命错误 - 无法继续下去 - 切断此次通话
//
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))
{
//
// 致命错误 - 无法继续下去 - 切断此次通话
//
MessageBox("ITFileTerminalEvent, but failed to ITBasicCallControl2::UnselectTerminalOnCall");
m_Tapi.m_pCall->Disconnect(DC_NORMAL);
return hr;
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////
// DigitEvent
//
// 处理 TE_DIGITEVENT 事件,TE_DIGITEVENT 时触发,对应接口 ITDigitDetectionEvent
/////////////////////////////////////////////////////////////////////////////////////
HRESULT CtapiPhoneDlg::DoDigitEvent(IN IDispatch* pEvent)
{
ITDigitDetectionEvent* pDigitEvent;
//
// 获得接口
//
pEvent->QueryInterface(IID_ITDigitDetectionEvent, (void**)&pDigitEvent);
unsigned char dig;
pDigitEvent->get_Digit(&dig);
//
// 跟据用户不同按键选择做出不同的回应
//
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -