outgoing.cpp
来自「一个基于com的电话检测和回复程序。程序使用tapi3.0实现」· C++ 代码 · 共 1,059 行 · 第 1/2 页
CPP
1,059 行
TERMINAL_DIRECTION tdStreamDirection;
long lStreamMediaType;
if ( FAILED( pStream ->get_Direction(&tdStreamDirection) ) ) { return FALSE; }
if ( FAILED( pStream ->get_MediaType(&lStreamMediaType) ) ) { return FALSE; }
return (tdStreamDirection == TD_CAPTURE) &&
(lStreamMediaType == TAPIMEDIATYPE_VIDEO);
}
/////////////////////////////////////////////////////////////////
// EnablePreview
//
// Selects a video render terminal on a video capture stream,
// thereby enabling video preview.
/////////////////////////////////////////////////////////////////
HRESULT
EnablePreview(
ITStream * pStream
)
{
ITTerminal * pTerminal;
HRESULT hr = GetVideoRenderTerminal(&pTerminal);
if ( SUCCEEDED(hr) )
{
hr = pStream->SelectTerminal(pTerminal);
pTerminal->Release();
}
return hr;
}
/////////////////////////////////////////////////////////////////
// SelectTerminalsOnCall
//
// Creates and selects terminals for all streams on the given
// call.
/////////////////////////////////////////////////////////////////
HRESULT
SelectTerminalsOnCall(
ITBasicCallControl * pCall
)
{
HRESULT hr;
//
// get the ITStreamControl interface for this call
//
ITStreamControl * pStreamControl;
hr = pCall->QueryInterface(IID_ITStreamControl,
(void **) &pStreamControl);
if ( SUCCEEDED(hr) )
{
//
// enumerate the streams
//
IEnumStream * pEnumStreams;
hr = pStreamControl->EnumerateStreams(&pEnumStreams);
pStreamControl->Release();
if ( SUCCEEDED(hr) )
{
//
// for each stream
//
ITStream * pStream;
while ( S_OK == pEnumStreams->Next(1, &pStream, NULL) )
{
ITTerminal * pTerminal;
//
// Find out the media type and direction of this stream,
// and create the default terminal for this media type and
// direction.
//
hr = GetTerminal(pStream,
&pTerminal);
if ( SUCCEEDED(hr) )
{
//
// Select the terminal on the stream.
//
hr = pStream->SelectTerminal(pTerminal);
if ( SUCCEEDED(hr) )
{
//
// Also enable preview on the video capture stream.
//
if ( IsVideoCaptureStream( pStream ) )
{
EnablePreview( pStream );
}
}
pTerminal->Release();
}
pStream->Release();
}
pEnumStreams->Release();
}
}
return hr;
}
/////////////////////////////////////////////////////////////////
// MakeTheCall
//
// Sets up and makes a call
/////////////////////////////////////////////////////////////////
HRESULT
MakeTheCall(
DWORD dwAddressType,
PWCHAR szAddressToCall
)
{
HRESULT hr = S_OK;
BSTR bstrAddressToCall;
BSTR pAddressName;
// find an address object that
// we will use to make calls on
hr = FindAnAddress(dwAddressType, &pAddressName);
if ( FAILED(hr) )
{
DoMessage(L"Could not find a TAPI address for making calls.");
return hr;
}
WCHAR pText[200];
wsprintf(pText, L"Using address: %s", pAddressName);
SysFreeString(pAddressName);
DoMessage(pText);
//
// find out which media types this address supports
//
long lMediaTypes = 0;
if ( AddressSupportsMediaType(gpAddress, TAPIMEDIATYPE_AUDIO) )
{
lMediaTypes |= TAPIMEDIATYPE_AUDIO; // we will use audio
}
if ( AddressSupportsMediaType(gpAddress, TAPIMEDIATYPE_VIDEO) )
{
lMediaTypes |= TAPIMEDIATYPE_VIDEO; // we will use video
}
//
// Create the call.
//
bstrAddressToCall = SysAllocString( szAddressToCall );
hr = gpAddress->CreateCall( bstrAddressToCall,
dwAddressType,
lMediaTypes,
&gpCall);
SysFreeString ( bstrAddressToCall );
if ( FAILED(hr) )
{
DoMessage(L"Could not create a call.");
return hr;
}
//
// Select our terminals on the call; if any of the selections fail we
// proceed without that terminal.
//
hr = SelectTerminalsOnCall( gpCall );
//
// We're now ready to call connect.
//
// the VARIANT_TRUE parameter indicates that this
// call is sychronous - that is, it won't
// return until the call is in the connected
// state (or fails to connect)
// Since this is called in the UI thread,
// this means that the app will appear
// to hang until this function returns.
// Some TAPI service providers may take a long
// time for a call to reach the connected state.
//
hr = gpCall->Connect( VARIANT_TRUE );
if ( FAILED(hr) )
{
gpCall->Release();
gpCall = NULL;
DoMessage(L"Could not connect the call.");
return hr;
}
return S_OK;
}
/////////////////////////////////////////////////////////
// GetTerminal
//
// Creates the default terminal for the passed-in stream.
//
/////////////////////////////////////////////////////////
HRESULT
GetTerminal(
ITStream * pStream,
ITTerminal ** ppTerminal
)
{
//
// Determine the media type and direction of this stream.
//
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;
//
// Since video render is a dynamic terminal, the procedure for creating
// it is different.
//
if ( ( lMediaType == TAPIMEDIATYPE_VIDEO ) &&
( dir == TD_RENDER ) )
{
return GetVideoRenderTerminal(ppTerminal);
}
//
// For all other terminals we use GetDefaultStaticTerminal.
// First, get the terminal support interface.
//
ITTerminalSupport * pTerminalSupport;
hr = gpAddress->QueryInterface( IID_ITTerminalSupport,
(void **)&pTerminalSupport);
if ( SUCCEEDED(hr) )
{
//
// get the default terminal for this MediaType and direction
//
hr = pTerminalSupport->GetDefaultStaticTerminal(lMediaType,
dir,
ppTerminal);
pTerminalSupport->Release();
}
return hr;
}
/////////////////////////////////////////////////////////
// GetVideoRenderTerminal
//
// Creates a dynamic terminal for the Video Render mediatype / direction
//
/////////////////////////////////////////////////////////
HRESULT
GetVideoRenderTerminal(
ITTerminal ** ppTerminal
)
{
//
// Construct a BSTR for the correct IID.
//
LPOLESTR lpTerminalClass;
HRESULT hr;
hr = StringFromIID(CLSID_VideoWindowTerm,
&lpTerminalClass);
if ( SUCCEEDED(hr) )
{
BSTR bstrTerminalClass;
bstrTerminalClass = SysAllocString ( lpTerminalClass );
CoTaskMemFree( lpTerminalClass );
if ( bstrTerminalClass == NULL )
{
hr = E_OUTOFMEMORY;
}
else
{
//
// Get the terminal support interface
//
ITTerminalSupport * pTerminalSupport;
hr = gpAddress->QueryInterface(IID_ITTerminalSupport,
(void **)&pTerminalSupport);
if ( SUCCEEDED(hr) )
{
//
// Create the video render terminal.
//
hr = pTerminalSupport->CreateTerminal(bstrTerminalClass,
TAPIMEDIATYPE_VIDEO,
TD_RENDER,
ppTerminal);
pTerminalSupport->Release();
if ( SUCCEEDED(hr) )
{
// Get the video window interface for the terminal
IVideoWindow *pVideoWindow = NULL;
hr = (*ppTerminal)->QueryInterface(IID_IVideoWindow,
(void**)&pVideoWindow);
if ( SUCCEEDED(hr) )
{
//
// Set the AutoShow member to true
//
// Note that the AutoShow property is the only one
// we can use on this terminal's IVideoWindow and
// IBasicVideo interfaces before the CME_STREAM_ACTIVE
// event is received for the stream. All other methods
// will fail until CME_STREAM_ACTIVE has been sent.
// Applications that need to control more about a video
// window than just its visibility must listen for the
// CME_STREAM_ACTIVE event. See the "t3in.exe" sample
// for how to do this.
//
hr = pVideoWindow->put_AutoShow( VARIANT_TRUE );
pVideoWindow->Release();
}
}
}
SysFreeString( bstrTerminalClass );
}
}
return hr;
}
//////////////////////////////////////////////////////////////////////
// DisconnectTheCall
//
// Disconnects the call
//////////////////////////////////////////////////////////////////////
HRESULT
DisconnectTheCall()
{
HRESULT hr = S_OK;
if (NULL != gpCall)
{
hr = gpCall->Disconnect( DC_NORMAL );
gpCall->Release();
gpCall = NULL;
return hr;
}
return S_FALSE;
}
///////////////////////////////////////////////////////////////////
//
// HELPER FUNCTIONS
//
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////
// DoMessage
///////////////////////////////////////////////////////////////////
void
DoMessage(
LPWSTR pszMessage
)
{
MessageBox(
ghDlg,
pszMessage,
gszTapi30,
MB_OK
);
}
///////////////////////////////////////////////////////////////
// EnableButton
//
// Enable, make default, and setfocus to a button
///////////////////////////////////////////////////////////////
void
EnableButton(
HWND hDlg,
int ID
)
{
SendDlgItemMessage(
hDlg,
ID,
BM_SETSTYLE,
BS_DEFPUSHBUTTON,
0
);
EnableWindow(
GetDlgItem( hDlg, ID ),
TRUE
);
SetFocus(
GetDlgItem( hDlg, ID )
);
}
//////////////////////////////////////////////////////////////
// DisableButton
//
// Disable a button
//////////////////////////////////////////////////////////////
void
DisableButton(
HWND hDlg,
int ID
)
{
SendDlgItemMessage(
hDlg,
ID,
BM_SETSTYLE,
BS_PUSHBUTTON,
0
);
EnableWindow(
GetDlgItem( hDlg, ID ),
FALSE
);
}
//////////////////////////////////////////////////////////////
// AddressSupportsMediaType
//
// Finds out if the given address supports the given media
// type, and returns TRUE if it does.
//////////////////////////////////////////////////////////////
BOOL
AddressSupportsMediaType(
ITAddress * pAddress,
long lMediaType
)
{
VARIANT_BOOL bSupport = VARIANT_FALSE;
ITMediaSupport * pMediaSupport;
if ( SUCCEEDED( pAddress->QueryInterface( IID_ITMediaSupport,
(void **)&pMediaSupport ) ) )
{
// does it support this media type?
pMediaSupport->QueryMediaType(
lMediaType,
&bSupport
);
pMediaSupport->Release();
}
return (bSupport == VARIANT_TRUE);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?