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 + -
显示快捷键?