home *** CD-ROM | disk | FTP | other *** search
- #define UNICODE
- #include <windows.h>
- #include <tapi3.h>
- #include "resource.h"
-
- //////////////////////////////////////////////////////////
- // T3OUT.EXE
- //
- // Example of making an outgoing call with TAPI 3.0
- //
- // This application will allow a user to make a call
- // by using TAPI 3.0. The application will simply look
- // for the first TAPI line that support Audio, and can
- // dial a phone number. It will then use that line to
- // make calls.
- //
- // This application does not handle incoming calls, and
- // does not process incoming messages.
- //
- //////////////////////////////////////////////////////////
-
- //////////////////////////////////////////////////////////
- // Constants
- //////////////////////////////////////////////////////////
-
- const DWORD ADDRESSLENGTH = 128;
- const DWORD MAXTERMINALS = 5;
-
- const WCHAR * const gszTapi30 = L"TAPI 3.0 Outgoing Call Sample";
-
- const WCHAR * const gszConferenceName = L"Conference Name";
- const WCHAR * const gszEmailName = L"Email Name";
- const WCHAR * const gszMachineName = L"Machine Name";
- const WCHAR * const gszPhoneNumber = L"Phone Number";
- const WCHAR * const gszIPAddress = L"IP Address";
-
- //////////////////////////////////////////////////////////
- // GLOBALS
- //////////////////////////////////////////////////////////
- HINSTANCE ghInst;
- HWND ghDlg = NULL;
- ITTAPI * gpTapi;
- ITAddress * gpAddress;
- ITBasicCallControl * gpCall;
-
- BSTR gbstrAudioIn;
- BSTR gbstrAudioOut;
- BSTR gbstrVideoIn;
- BSTR gbstrVideoOut;
-
-
- //////////////////////////////////////////////////////////
- // PROTOTYPES
- //////////////////////////////////////////////////////////
- BOOL
- CALLBACK
- MainDialogProc(
- HWND hDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam
- );
-
- HRESULT
- FindAnAddress(
- DWORD dwAddressType
- );
-
- HRESULT
- GetMediaTerminal(
- BSTR bstrMedia,
- ITMediaTerminal ** ppMediaTerminal
- );
-
- HRESULT
- GetVideoInMediaTerminal(
- ITMediaTerminal ** ppMediaTerminal
- );
-
- HRESULT
- MakeTheCall(
- DWORD dwAddressType,
- PWCHAR szAddressToCall
- );
-
- HRESULT
- DisconnectTheCall();
-
- void
- DoMessage(
- LPWSTR pszMessage
- );
-
- HRESULT
- InitializeTapi();
-
- void
- ShutdownTapi();
-
- void
- EnableButton(
- HWND hDlg,
- int ID
- );
- void
- DisableButton(
- HWND hDlg,
- int ID
- );
-
- //////////////////////////////////////////////////////////
- // WinMain
- //////////////////////////////////////////////////////////
- int
- WINAPI
- WinMain(
- HINSTANCE hInst,
- HINSTANCE hPrevInst,
- LPSTR lpCmdLine,
- int nCmdShow
- )
- {
- ghInst = hInst;
-
-
- // need to coinit
- if (!SUCCEEDED(CoInitialize(NULL)))
- {
- return 0;
- }
-
- if (S_OK != InitializeTapi())
- {
- return 0;
- }
-
- // everything is initialized, so
- // start the main dialog box
- DialogBox(
- ghInst,
- MAKEINTRESOURCE(IDD_MAINDLG),
- NULL,
- MainDialogProc
- );
-
-
- ShutdownTapi();
-
- CoUninitialize();
-
- return 1;
- }
-
-
- //////////////////////////////////////////////////////////////
- // InitializeTapi
- //
- // Various initializations
- ///////////////////////////////////////////////////////////////
- HRESULT
- InitializeTapi()
- {
- HRESULT hr;
- LPWSTR psz;
-
-
- // cocreate the TAPI object
- hr = CoCreateInstance(
- CLSID_TAPI,
- NULL,
- CLSCTX_INPROC_SERVER,
- IID_ITTAPI,
- (LPVOID *)&gpTapi
- );
-
- if (hr != S_OK)
- {
- DoMessage(L"CoCreateInstance on TAPI failed");
- return hr;
- }
-
- // call initialize. this must be called before
- // any other tapi functions are called.
- hr = gpTapi->Initialize();
-
- if (S_OK != hr)
- {
- DoMessage(L"TAPI failed to initialize");
-
- gpTapi->Release();
- gpTapi = NULL;
-
- return hr;
- }
-
-
- // convert the TAPIMEDIATYPEs to BSTRs for
- // convenience throughout the program
- StringFromIID(
- TAPIMEDIATYPE_AudioIn,
- &psz
- );
-
- gbstrAudioIn = SysAllocString( psz );
-
- CoTaskMemFree( psz );
-
- StringFromIID(
- TAPIMEDIATYPE_AudioOut,
- &psz
- );
-
- gbstrAudioOut = SysAllocString( psz );
-
- CoTaskMemFree( psz );
-
- StringFromIID(
- TAPIMEDIATYPE_VideoIn,
- &psz
- );
-
- gbstrVideoIn = SysAllocString( psz );
-
- CoTaskMemFree( psz );
-
- StringFromIID(
- TAPIMEDIATYPE_VideoOut,
- &psz
- );
-
- gbstrVideoOut = SysAllocString( psz );
-
- CoTaskMemFree( psz );
-
- return S_OK;
- }
-
-
- ///////////////////////////////////////////////////////////////
- // ShutdownTapi
- ///////////////////////////////////////////////////////////////
- void
- ShutdownTapi()
- {
- // if there is still a call,
- // release it
- if (NULL != gpCall)
- {
- gpCall->Release();
- gpCall = NULL;
- }
-
- // if we have an address object
- // release it
- if (NULL != gpAddress)
- {
- gpAddress->Release();
- }
-
- // release main object.
- if (NULL != gpTapi)
- {
- gpTapi->Shutdown();
- gpTapi->Release();
- }
-
- SysFreeString( gbstrAudioIn );
- SysFreeString( gbstrAudioOut );
- SysFreeString( gbstrVideoIn );
- SysFreeString( gbstrVideoOut );
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // InitAddressTypeComboBox
- //
- // Put address type string in the combo box
- // and save the addresstype with the string
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- InitAddressTypeComboBox(
- HWND hComboBox
- )
- {
- int i;
-
- i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszConferenceName );
-
- SendMessage(
- hComboBox,
- CB_SETITEMDATA ,
- i,
- (long)T3_ADDRESSTYPE_CONFERENCENAME
- );
-
-
- i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszEmailName );
-
- SendMessage(
- hComboBox,
- CB_SETITEMDATA ,
- i,
- (long)T3_ADDRESSTYPE_EMAILNAME
- );
-
-
- i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszMachineName );
-
- SendMessage(
- hComboBox,
- CB_SETITEMDATA ,
- i,
- (long)T3_ADDRESSTYPE_DOMAINNAME
- );
-
-
- i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszPhoneNumber );
-
- SendMessage(
- hComboBox,
- CB_SETITEMDATA ,
- i,
- (long)T3_ADDRESSTYPE_PHONENUMBER
- );
-
-
- SendMessage( hComboBox, CB_SETCURSEL, i, 0 );
-
- i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszIPAddress );
-
- SendMessage(
- hComboBox,
- CB_SETITEMDATA ,
- i,
- (long)T3_ADDRESSTYPE_IPADDRESS
- );
-
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // MainDlgProc
- ///////////////////////////////////////////////////////////////////////////
- BOOL
- CALLBACK
- MainDialogProc(
- HWND hDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam
- )
- {
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- HWND hComboBox;
-
-
- // set up dialog
- ghDlg = hDlg;
-
- EnableButton( hDlg, IDOK );
- DisableButton( hDlg, IDC_DISCONNECT );
-
- hComboBox = GetDlgItem( hDlg, IDC_ADDRESSTYPE );
-
- InitAddressTypeComboBox(hComboBox);
-
- SetFocus( hComboBox );
-
- return 0;
- }
-
- case WM_COMMAND:
- {
- if ( LOWORD(wParam) == IDCANCEL )
- {
- // quit
- EndDialog( hDlg, 0 );
-
- return 1;
- }
-
- // dial request
- if ( LOWORD(wParam) == IDOK )
- {
- HWND hComboBox;
- DWORD dwIndex;
- DWORD dwAddressType;
- WCHAR szAddressToCall[ADDRESSLENGTH];
-
-
- // get the address type the user selected.
- hComboBox = GetDlgItem( hDlg, IDC_ADDRESSTYPE );
- dwIndex = SendMessage( hComboBox, CB_GETCURSEL, 0, 0 );
-
- dwAddressType = SendMessage(
- hComboBox,
- CB_GETITEMDATA,
- dwIndex,
- 0
- );
-
- // get the address the user wants to call
- GetDlgItemText(
- hDlg,
- IDC_ADDRESS,
- szAddressToCall,
- ADDRESSLENGTH
- );
-
- // make the call
- if ( S_OK == MakeTheCall(dwAddressType, szAddressToCall) )
- {
- EnableButton( hDlg, IDC_DISCONNECT );
- DisableButton( hDlg, IDOK );
- }
- else
- {
- DoMessage(L"The call failed to connect");
- }
-
- return 1;
- }
-
- // disconnect requestion
- if ( LOWORD( wParam ) == IDC_DISCONNECT )
- {
- // disconnect
- if (S_OK == DisconnectTheCall())
- {
- EnableButton( hDlg, IDOK );
- DisableButton( hDlg, IDC_DISCONNECT );
- }
- else
- {
- DoMessage(L"The call failed to disconnect");
- }
-
- return 1;
- }
-
- return 0;
- }
- default:
-
- return 0;
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- // FindAnAddress
- //
- // Finds an address object that this application will use to make calls on.
- //
- // This function finds an address that supports the addresstype passed
- // in, as well as the audioin and audioout media types.
- //
- // Return Value
- // S_OK if it finds an address
- // S_FALSE if it does not find an address
- ////////////////////////////////////////////////////////////////////////
- HRESULT
- FindAnAddress(
- DWORD dwAddressType
- )
- {
- HRESULT hr = S_OK;
- BOOL bFoundAddress = FALSE;
- IEnumAddress * pEnumAddress;
- ITAddress * pAddress;
- IEnumAddressType * pEnumAddressTypes;
- DWORD dwType;
-
- // if we have an address object
- // release it
- if (NULL != gpAddress)
- {
- gpAddress->Release();
- gpAddress = NULL;
- }
-
- // enumerate the addresses
- hr = gpTapi->_EnumerateAddresses( &pEnumAddress );
-
- if (S_OK != hr)
- {
- return hr;
- }
-
- while ( !bFoundAddress )
- {
- // get the next address
- hr = pEnumAddress->Next( 1, &pAddress, NULL );
-
- if (S_OK != hr)
- {
- break;
- }
-
- // enumerate the address types that
- // this address supports
- hr = pAddress->_EnumerateAddressType( &pEnumAddressTypes );
-
- if (S_OK != hr)
- {
- pAddress->Release();
-
- continue;
- }
-
- while (TRUE)
- {
- ITMediaSupport * pMediaSupport;
- VARIANT_BOOL bSupport;
-
- // get the next address type
- hr = pEnumAddressTypes->Next( 1, &dwType, NULL );
-
- if (S_OK != hr)
- {
- break;
- }
-
- // is the type we are looking for?
- if ( dwAddressType == dwType )
- {
- // yes
- pAddress->QueryInterface( IID_ITMediaSupport, (void **)&pMediaSupport );
-
- // does it support AudioIn?
- pMediaSupport->QueryMediaType(
- gbstrAudioIn,
- &bSupport
- );
-
- if (bSupport)
- {
- // does it also support AudioOut?
- pMediaSupport->QueryMediaType(
- gbstrAudioOut,
- &bSupport
- );
-
- if (bSupport)
- {
- // save
- pMediaSupport->Release();
-
- gpAddress = pAddress;
- gpAddress->AddRef();
-
- bFoundAddress = TRUE;
- break;
- }
- }
-
- pMediaSupport->Release();
- }
- }
-
- pAddress->Release();
- pEnumAddressTypes->Release();
- }
-
- pEnumAddress->Release();
-
- if (!bFoundAddress)
- {
- return S_FALSE;
- }
-
- return S_OK;
- }
-
-
- /////////////////////////////////////////////////////////////////
- // CreateMediaTerminals
- //
- // Create audioin and audioout terminals.
- //
- // If the address also supports video, create
- // Videoin and videoout terminals, too.
- //
- // This function assumes that ppMediaTerminals has a size no less than four.
- /////////////////////////////////////////////////////////////////
- HRESULT
- CreateMediaTerminals(
- ITMediaTerminal ** ppMediaTerminals,
- PLONG pNumMediaTerminals
- )
- {
- int count = 0;
- HRESULT hr;
-
- // get the mediaterminal for audioin
- hr = GetMediaTerminal(
- gbstrAudioIn,
- &ppMediaTerminals[count]
- );
-
- if (S_OK != hr)
- {
- return hr;
- }
-
- count ++;
-
- // get the mediaterminal for audioout
- hr = GetMediaTerminal(
- gbstrAudioOut,
- &ppMediaTerminals[count]
- );
-
- if (S_OK != hr)
- {
- ppMediaTerminals[0]->Release();
- return hr;
- }
-
- count ++;
-
- // Find out if the address supports video.
- ITMediaSupport * pMediaSupport;
- VARIANT_BOOL bSupport;
-
- gpAddress->QueryInterface( IID_ITMediaSupport, (void **)&pMediaSupport );
-
- // does it support VideoIn?
- pMediaSupport->QueryMediaType(
- gbstrVideoIn,
- &bSupport
- );
-
- if (bSupport)
- {
- // get the mediaterminal for VideoIn
- hr = GetVideoInMediaTerminal(
- &ppMediaTerminals[count]
- );
-
- if (S_OK == hr)
- {
- count ++;
- }
-
- // does it also support VideoOut?
- pMediaSupport->QueryMediaType(
- gbstrVideoOut,
- &bSupport
- );
-
- if (bSupport)
- {
- // get the mediaterminal for Videoout
- hr = GetMediaTerminal(
- gbstrVideoOut,
- &ppMediaTerminals[count]
- );
-
- if (S_OK == hr)
- {
- count ++;
- }
- }
- }
-
- pMediaSupport->Release();
-
- *pNumMediaTerminals = count;
-
- return S_OK;
- }
-
- /////////////////////////////////////////////////////////////////
- // CreateMediaTerminalSafeArray
- //
- /////////////////////////////////////////////////////////////////
- SAFEARRAY *
- CreateMediaTerminalSafeArray(
- ITMediaTerminal ** ppMediaTerminals,
- LONG nNumMediaTerminals
- )
- {
- SAFEARRAY * psa;
- SAFEARRAYBOUND sabound[1];
-
- // create a safearray with two elements
- // to pass the mediaterminals to tapi
- sabound[0].lLbound = 0;
- sabound[0].cElements = nNumMediaTerminals;
-
- psa = SafeArrayCreate(
- VT_UNKNOWN,
- 1,
- sabound
- );
-
- if (NULL != psa)
- {
- // save them in the safearray
- for (long i = 0; i < nNumMediaTerminals; i ++)
- {
- SafeArrayPutElement(
- psa,
- &i,
- ppMediaTerminals[i]
- );
- }
- }
- return psa;
- }
-
- /////////////////////////////////////////////////////////////////
- // ReleaseMediaTerminals
- //
- /////////////////////////////////////////////////////////////////
- void
- ReleaseMediaTerminals(
- ITMediaTerminal ** ppMediaTerminals,
- LONG nNumMediaTerminals
- )
- {
- for (long i = 0; i < nNumMediaTerminals; i ++)
- {
- if (ppMediaTerminals[i])
- {
- ppMediaTerminals[i]->Release();
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////
- // MakeTheCall
- //
- // Sets up and makes a call
- /////////////////////////////////////////////////////////////////
- HRESULT
- MakeTheCall(
- DWORD dwAddressType,
- PWCHAR szAddressToCall
- )
- {
- HRESULT hr = S_OK;
- ITMediaTerminal * ppMediaTerminals[MAXTERMINALS];
- long nNumMediaTerminals = MAXTERMINALS;
- SAFEARRAY * psa;
- VARIANT var;
- BSTR bstrAddressToCall;
-
- // find an address object that
- // we will use to make calls on
- hr = FindAnAddress(dwAddressType);
-
- if (S_OK != hr)
- {
- DoMessage(L"Could not find an address to make a phone call on");
-
- return hr;
- }
-
- bstrAddressToCall = SysAllocString( szAddressToCall );
-
- hr = gpAddress->CreateCall( bstrAddressToCall, &gpCall );
-
- SysFreeString ( bstrAddressToCall );
-
- if (S_OK != hr)
- {
- return hr;
- }
-
- hr = CreateMediaTerminals(ppMediaTerminals, &nNumMediaTerminals);
-
- if (S_OK != hr)
- {
- gpCall->Release();
- gpCall = NULL;
- return hr;
- }
-
- psa = CreateMediaTerminalSafeArray(ppMediaTerminals, nNumMediaTerminals);
-
- if (S_OK != hr)
- {
- gpCall->Release();
- gpCall = NULL;
- ReleaseMediaTerminals(ppMediaTerminals, nNumMediaTerminals);
- return hr;
- }
-
-
- // put the safearray in a variant
- VariantInit(&var);
- var.vt = VT_ARRAY;
- var.parray = psa;
-
- // call SelectMediaTerminals
- hr = gpCall->SelectMediaTerminals( var );
-
- ReleaseMediaTerminals(ppMediaTerminals, nNumMediaTerminals);
-
- SafeArrayDestroy( psa );
-
- if (S_OK != hr)
- {
- return hr;
- }
-
- // We're now ready to call connect.
- //
- // the 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( TRUE );
-
- if (S_OK != hr)
- {
- gpCall->Release();
- gpCall = NULL;
- return hr;
- }
-
- return hr;
- }
-
-
- /////////////////////////////////////////////////////////
- // GetMediaTerminal
- //
- // Creates a MediaTerminal for the bstrMediaType passed
- // in, using the default terminal for the bstrMediaType
- //
- /////////////////////////////////////////////////////////
- HRESULT
- GetMediaTerminal(
- BSTR bstrMediaType,
- ITMediaTerminal ** ppMediaTerminal
- )
- {
- HRESULT hr = S_OK;
- ITTerminalSupport * pTerminalSupport;
- ITTerminal * pTerminal;
-
- // get the terminal support interface
- gpAddress->QueryInterface( IID_ITTerminalSupport, (void **)&pTerminalSupport );
-
- // get the default terminal for MediaType
- hr = pTerminalSupport->GetDefaultTerminal(
- bstrMediaType,
- &pTerminal
- );
-
-
- pTerminalSupport->Release();
-
- if (S_OK != hr)
- {
- return hr;
- }
-
- // Create a media terminal for MediaType
- // Use the default terminal we just got
- hr = gpTapi->CreateMediaTerminal(
- bstrMediaType,
- pTerminal,
- ppMediaTerminal
- );
-
- pTerminal->Release();
-
- if (S_OK != hr)
- {
- return hr;
- }
-
- return S_OK;
-
- }
-
- /////////////////////////////////////////////////////////
- // GetVideoInMediaTerminal
- //
- // Creates a MediaTerminal for the VideoIn mediatype
- // This is a dynamic terminal type.
- //
- /////////////////////////////////////////////////////////
- HRESULT
- GetVideoInMediaTerminal(
- ITMediaTerminal ** ppMediaTerminal
- )
- {
- HRESULT hr = S_OK;
- ITTerminalSupport * pTerminalSupport;
- ITTerminal * pTerminal;
-
- // get the terminal support interface
- gpAddress->QueryInterface( IID_ITTerminalSupport, (void **)&pTerminalSupport );
-
- BSTR bstrTerminalClass;
- LPOLESTR lpTerminalClass;
-
- StringFromIID(
- CLSID_VideoWindowTerm,
- &lpTerminalClass
- );
-
- bstrTerminalClass = SysAllocString ( lpTerminalClass );
-
- CoTaskMemFree( lpTerminalClass );
-
- hr = pTerminalSupport->CreateTerminal(
- bstrTerminalClass,
- &pTerminal
- );
-
- SysFreeString( bstrTerminalClass );
- pTerminalSupport->Release();
-
- if (FAILED(hr))
- {
- return hr;
- }
-
- // Create a media terminal for MediaType
- // Use the default terminal we just got
- hr = gpTapi->CreateMediaTerminal(
- gbstrVideoIn,
- pTerminal,
- ppMediaTerminal
- );
-
- pTerminal->Release();
-
- if (S_OK != hr)
- {
- return hr;
- }
-
- return S_OK;
-
- }
-
-
- //////////////////////////////////////////////////////////////////////
- // 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
- );
- }
-
-
-
-