?? tapieventprocess.cpp
字號:
VARIANT_TRUE,
VARIANT_TRUE,
lMediaTypes,
0,
&lRegister
);
return hr;
}
/////////////////////////////////////////////////////////////////
// MakeTheCall
//
// 功能:設置并呼叫號碼
/////////////////////////////////////////////////////////////////
HRESULT
CTapi::MakeTheCall(
IN DWORD dwAddressType,
IN PWCHAR szAddressToCall
)
{
HRESULT hr = S_OK;
BSTR bstrAddressToCall;
//
// 檢測當前地址是否有效
//
if( m_pAddress == NULL)
return E_FAIL;
//
// 這里我們只要求支持聲音即可
//
long lMediaTypes = TAPIMEDIATYPE_AUDIO;
//
// 因為我們在對線路偵聽時,已經確定 m_Address 至少支持聲音,
// 已經滿足我們要求,不用另做檢測
//
//
// 建立呼叫
//
bstrAddressToCall = SysAllocString( szAddressToCall );
hr = m_pAddress->CreateCall( bstrAddressToCall,
dwAddressType,
lMediaTypes,
&m_pCall);
SysFreeString ( bstrAddressToCall );
if ( FAILED(hr) )
{
AfxMessageBox("建立呼叫失敗!");
return hr;
}
//
// 為當前呼叫選擇終端
//
hr = SelectTerminalsOnCall(m_pAddress, m_pCall );
//
// 正式發出呼叫
//
hr = m_pCall->Connect( VARIANT_TRUE );
if ( FAILED(hr) )
{
m_pCall->Release();
m_pCall = NULL;
AfxMessageBox("無法連接!");
return hr;
}
return S_OK;
}
/////////////////////////////////////////////////////////
// GetTerminal
//
// 為輸入 stream 創建默認的 terminal,并通過 ppTerminal 返回
//
/////////////////////////////////////////////////////////
HRESULT CTapi::GetTerminal(
ITAddress * pAddress,
ITStream * pStream,
ITTerminal ** ppTerminal
)
{
//
// 確定當前傳入 stream 的 media type 和 direction
//
HRESULT hr;
long lMediaType;
TERMINAL_DIRECTION dir;
hr = pStream->get_MediaType( &lMediaType );
if ( FAILED(hr) ) return hr;
hr = pStream->get_Direction( &dir );
if ( FAILED(hr) ) return hr;
//
// 這里我們人處理 Audio 流,對于 Video 流,我們不令做處理
// 因此只調用 GetDefaultStaticTerminal.
// 首先,獲得 ITTerminalSupport 接口
//
ITTerminalSupport * pTerminalSupport;
hr = pAddress->QueryInterface( IID_ITTerminalSupport,
(void **)&pTerminalSupport);
if ( SUCCEEDED(hr) )
{
//
// 為這種 MediaType 和 Direction 獲得默認的 Terminal
//
hr = pTerminalSupport->GetDefaultStaticTerminal(lMediaType,
dir,
ppTerminal);
pTerminalSupport->Release();
}
return hr;
}
/////////////////////////////////////////////////////////////////
// SelectTerminalOnCall
//
// 在給定的 call 上中的 stream 中選擇一個適當的 terminal
/////////////////////////////////////////////////////////////////
HRESULT CTapi::SelectTerminalsOnCall(
ITAddress * pAddress,
ITBasicCallControl * pCall
)
{
HRESULT hr;
//
// 為當前 call 獲得 ITStreamControl 接口
//
ITStreamControl * pStreamControl;
hr = pCall->QueryInterface(IID_ITStreamControl,
(void **) &pStreamControl);
if ( SUCCEEDED(hr) )
{
//
// 列舉所有的 stream
//
IEnumStream * pEnumStreams;
hr = pStreamControl->EnumerateStreams(&pEnumStreams);
pStreamControl->Release();
if ( SUCCEEDED(hr) )
{
//
// 遍歷所有的 stream
//
ITStream * pStream;
while ( S_OK == pEnumStreams->Next(1, &pStream, NULL) )
{
ITTerminal * pTerminal;
//
// 找出當前 stream 的 media type 和 direction,
// 并且為這種 media type 和 direction 創建默認的 terminal
//
hr = GetTerminal(pAddress,
pStream,
&pTerminal);
if ( SUCCEEDED(hr) )
{
//
// 對當前的 Stream 選擇上面獲得的 Terminal
//
hr = pStream->SelectTerminal(pTerminal);
pTerminal->Release();
}
pStream->Release();
}
pEnumStreams->Release();
}
}
return hr;
}
/////////////////////////////////////////////////////////////////
// PreparePlay
//
// 功能:播放給定的聲音文件
/////////////////////////////////////////////////////////////////
HRESULT
CTapi::PreparePlay(CString strFileName)
{
//
// 檢測當前的 call object 是否有效
//
if (NULL == m_pCall)
{
AfxMessageBox("AnswerTheCall: Call object 無效");
return E_UNEXPECTED;
}
//
// 如果 m_pPlayFileTerm 不是NULL,先釋放之
//
if(NULL != m_pPlayFileTerm)
{
m_pPlayFileTerm->Release();
m_pPlayFileTerm = NULL;
}
//
// 為請求終端作準備 - 需要 ITBasicCallControl2 接口,只有在 TAPI3.1 中才支持
//
ITBasicCallControl2* pITBCC2 = NULL;
HRESULT hr = m_pCall->QueryInterface( IID_ITBasicCallControl2, (void**)&pITBCC2 );
if(FAILED(hr))
{
AfxMessageBox("AnswerTheCall: QI ITBasicCallControl2 failed");
m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 為請求終端作準備 - need CLSID BSTR
//
BSTR bstrCLSID = NULL;
hr = StringFromCLSID(CLSID_FilePlaybackTerminal, &bstrCLSID);
if(FAILED(hr))
{
pITBCC2->Release();
AfxMessageBox("AnswerTheCall: StringFromCLSID failed");
m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
//正式請求終端,需要媒體流類型和媒體流方向
//
hr = pITBCC2->RequestTerminal(bstrCLSID,
TAPIMEDIATYPE_AUDIO,
TD_CAPTURE,
&m_pPlayFileTerm);
//
//釋放內存
//
::CoTaskMemFree(bstrCLSID);
if(FAILED(hr))
{
pITBCC2->Release();
AfxMessageBox("AnswerTheCall: RequestTerminal failed");
m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 為設置文件名作準備
//
BSTR bstrFileName = strFileName.AllocSysString();
if(NULL == bstrFileName)
{
m_pPlayFileTerm->Release();
m_pPlayFileTerm = NULL;
pITBCC2->Release();
AfxMessageBox("AnswerTheCall: SysAllocString for play list failed");
m_pCall->Disconnect(DC_NORMAL);
return E_OUTOFMEMORY;
}
//
// 為 m_pPlayFileTerm 設置文件名
//
hr = PutPlayList(m_pPlayFileTerm, bstrFileName);
//
// 釋放內存
//
::SysFreeString(bstrFileName);
if(FAILED(hr))
{
m_pPlayFileTerm->Release();
m_pPlayFileTerm = NULL;
pITBCC2->Release();
AfxMessageBox("AnswerTheCall: PutPlayList failed");
m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 用 ITBasicCallControl2 選擇終端
//
hr = pITBCC2->SelectTerminalOnCall(m_pPlayFileTerm);
if(FAILED(hr))
{
m_pPlayFileTerm->Release();
m_pPlayFileTerm = NULL;
pITBCC2->Release();
AfxMessageBox("AnswerTheCall: SelectTerminalOnCall failed");
m_pCall->Disconnect(DC_NORMAL);
return hr;
}
pITBCC2->Release();
return S_OK;
}
/////////////////////////////////////////////////////////////////////
// Answers the call
//
// 功能:應答電話,創建并選擇播放的終端
/////////////////////////////////////////////////////////////////////
HRESULT
CTapi::AnswerTheCall()
{
HRESULT hr;
hr = PreparePlay(m_WelcomeFileName);
if( FAILED(hr) )
{
AfxMessageBox("無法找到" + m_WelcomeFileName + "文件或該文件不是合法的語音文件!");
return E_FAIL;
}
//
// 現在可以正式應答電話了
//
hr = m_pCall->Answer();
if(FAILED(hr))
{
m_pPlayFileTerm->Release();
m_pPlayFileTerm = NULL;
AfxMessageBox("AnswerTheCall: Answer failed");
m_pCall->Disconnect(DC_NORMAL);
return hr;
}
//
// 到此正常結束
//
// pITBCC2->Release();
return S_OK;
}
//////////////////////////////////////////////////////////////////////
// DisconnectTheCall
//
// 功能:掛斷電話
//////////////////////////////////////////////////////////////////////
HRESULT CTapi::DisconnectTheCall()
{
HRESULT hr = S_OK;
if (NULL != m_pCall)
{
hr = m_pCall->Disconnect( DC_NORMAL );
//
// 暫時不要釋放 m_pCall,因為這樣做的話我們無法得到 Disconnected 消息
//
return hr;
}
return S_FALSE;
}
//////////////////////////////////////////////////////////////////////
// ReleaseTheCall
//
// 釋放通話過程中所用到的 object
//
//////////////////////////////////////////////////////////////////////
void
CTapi::ReleaseTheCall()
{
// KillTimer(m_hWnd, TIMER_ID);
//
// 釋放終端
//
if(NULL != m_pPlayFileTerm)
{
m_pPlayFileTerm->Release();
m_pPlayFileTerm = NULL;
}
if(NULL != m_pRecordFileTerm)
{
m_pRecordFileTerm->Release();
m_pRecordFileTerm = NULL;
}
//
// 釋放 call object - 這樣會同時釋放所有的被選擇過得終端
//
if (NULL != m_pCall)
{
m_pCall->Release();
m_pCall = NULL;
}
}
//////////////////////////////////////////////////////////////////
// PutPlayList
//
// 功能:將要播放的聲音文件放入播放列表。調用了 put_PlayList
//////////////////////////////////////////////////////////////////
HRESULT CTapi::PutPlayList(
IN ITTerminal *pITTerminal,
IN BSTR bstrFileName)
{
//
// 檢測輸入的終端是否有效
//
if(NULL == pITTerminal)
{
AfxMessageBox("PutPlayList: playback terminal NULL");
return E_UNEXPECTED;
}
//
// 獲得 ITMediaPlayback 接口
//
ITMediaPlayback* pMediaPlayback = NULL;
HRESULT hr = pITTerminal->QueryInterface(
IID_ITMediaPlayback,
(void**)&pMediaPlayback);
if(FAILED(hr))
{
AfxMessageBox("PutPlayList: QI ITMediaPlayback failed");
return hr;
}
//
// put_PlayList 函數需要用到的 VARIANT 變量
//
VARIANT varPlaylist;
VariantInit(&varPlaylist);
//
// 設置 SAFEARRAYBOUND
//
SAFEARRAYBOUND DimensionBounds;
DimensionBounds.lLbound = 1;
//
// 設置 playlist 中的文件數
//
DimensionBounds.cElements = 1;
//
// 把文件名置于 playlist 中的 index = 1處
//
long lArrayPos = 1;
//
// 用于存放文件名 - 用于把文件名加入到 SafeArray
//
VARIANT* pvarArrayEntry = new VARIANT;
if( pvarArrayEntry == NULL)
{
AfxMessageBox("PutPlayList: new VARIANT failed");
return E_OUTOFMEMORY;
}
VariantInit(pvarArrayEntry);
//
// 創建 SAFEARRAY
//
SAFEARRAY *pPlayListArray = NULL;
pPlayListArray = SafeArrayCreate( VT_VARIANT, 1, &DimensionBounds);
if( pPlayListArray == NULL)
{
AfxMessageBox("PutPlayList: SafeArrayCreate failed");
delete pvarArrayEntry;
return E_OUTOFMEMORY;
}
//
// 正式把存儲在 pvarArrayEntry 中的文件名加入到 SafeArray 中
// 當我們需要加入多個元素到 SafeArray 中時,只需讓 lArrayPos 加 1 即可
//
pvarArrayEntry->vt = VT_BSTR;
pvarArrayEntry->bstrVal = ::SysAllocString(bstrFileName);
SafeArrayPutElement( pPlayListArray, &lArrayPos, pvarArrayEntry);
VariantClear(pvarArrayEntry);
//
// 準備varPlaylist, 為調用 put_PlayList 作準備
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -