home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 10 / ioProg_10.iso / soft / platsdk / inetwork.exe / TAPI-S.cab / 71OUTGOING.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  25.5 KB  |  1,053 lines

  1. #define UNICODE
  2. #include <windows.h>
  3. #include <tapi3.h>
  4. #include "resource.h"
  5.  
  6. //////////////////////////////////////////////////////////
  7. // T3OUT.EXE
  8. //
  9. // Example of making an outgoing call with TAPI 3.0
  10. //
  11. // This application will allow a user to make a call
  12. // by using TAPI 3.0.  The application will simply look
  13. // for the first TAPI line that support Audio, and can
  14. // dial a phone number.  It will then use that line to
  15. // make calls.
  16. //
  17. // This application does not handle incoming calls, and
  18. // does not process incoming messages.
  19. //
  20. //////////////////////////////////////////////////////////
  21.  
  22. //////////////////////////////////////////////////////////
  23. // Constants
  24. //////////////////////////////////////////////////////////
  25.  
  26. const DWORD ADDRESSLENGTH   = 128;
  27. const DWORD MAXTERMINALS    = 5;
  28.  
  29. const WCHAR * const gszTapi30           = L"TAPI 3.0 Outgoing Call Sample";
  30.  
  31. const WCHAR * const gszConferenceName   = L"Conference Name";
  32. const WCHAR * const gszEmailName        = L"Email Name";
  33. const WCHAR * const gszMachineName      = L"Machine Name";
  34. const WCHAR * const gszPhoneNumber      = L"Phone Number";
  35. const WCHAR * const gszIPAddress        = L"IP Address";
  36.  
  37. //////////////////////////////////////////////////////////
  38. // GLOBALS
  39. //////////////////////////////////////////////////////////
  40. HINSTANCE               ghInst;
  41. HWND                    ghDlg = NULL;
  42. ITTAPI *                gpTapi;
  43. ITAddress *             gpAddress;
  44. ITBasicCallControl *    gpCall;
  45.  
  46. BSTR                    gbstrAudioIn;
  47. BSTR                    gbstrAudioOut;
  48. BSTR                    gbstrVideoIn;
  49. BSTR                    gbstrVideoOut;
  50.  
  51.  
  52. //////////////////////////////////////////////////////////
  53. // PROTOTYPES
  54. //////////////////////////////////////////////////////////
  55. BOOL
  56. CALLBACK
  57. MainDialogProc(
  58.                HWND hDlg,
  59.                UINT uMsg,
  60.                WPARAM wParam,
  61.                LPARAM lParam
  62.               );
  63.  
  64. HRESULT
  65. FindAnAddress(
  66.               DWORD dwAddressType
  67.              );
  68.  
  69. HRESULT
  70. GetMediaTerminal(
  71.                  BSTR bstrMedia,
  72.                  ITMediaTerminal ** ppMediaTerminal
  73.                 );
  74.  
  75. HRESULT
  76. GetVideoInMediaTerminal(
  77.                  ITMediaTerminal ** ppMediaTerminal
  78.                 );
  79.  
  80. HRESULT
  81. MakeTheCall(
  82.             DWORD dwAddressType,
  83.             PWCHAR szAddressToCall
  84.            );
  85.  
  86. HRESULT
  87. DisconnectTheCall();
  88.  
  89. void
  90. DoMessage(
  91.           LPWSTR pszMessage
  92.          );
  93.  
  94. HRESULT
  95. InitializeTapi();
  96.  
  97. void
  98. ShutdownTapi();
  99.  
  100. void
  101. EnableButton(
  102.              HWND hDlg,
  103.              int ID
  104.             );
  105. void
  106. DisableButton(
  107.               HWND hDlg,
  108.               int ID
  109.              );
  110.  
  111. //////////////////////////////////////////////////////////
  112. // WinMain
  113. //////////////////////////////////////////////////////////
  114. int
  115. WINAPI
  116. WinMain(
  117.         HINSTANCE hInst,
  118.         HINSTANCE hPrevInst,
  119.         LPSTR lpCmdLine,
  120.         int nCmdShow
  121.        )
  122. {
  123.     ghInst = hInst;
  124.  
  125.     
  126.     // need to coinit
  127.     if (!SUCCEEDED(CoInitialize(NULL)))
  128.     {
  129.         return 0;
  130.     }
  131.  
  132.     if (S_OK != InitializeTapi())
  133.     {
  134.         return 0;
  135.     }
  136.     
  137.     // everything is initialized, so
  138.     // start the main dialog box
  139.     DialogBox(
  140.               ghInst,
  141.               MAKEINTRESOURCE(IDD_MAINDLG),
  142.               NULL,
  143.               MainDialogProc
  144.              );
  145.  
  146.  
  147.     ShutdownTapi();
  148.     
  149.     CoUninitialize();
  150.  
  151.     return 1;
  152. }
  153.  
  154.  
  155. //////////////////////////////////////////////////////////////
  156. // InitializeTapi
  157. //
  158. // Various initializations
  159. ///////////////////////////////////////////////////////////////
  160. HRESULT
  161. InitializeTapi()
  162. {
  163.     HRESULT         hr;
  164.     LPWSTR          psz;
  165.  
  166.     
  167.     // cocreate the TAPI object
  168.     hr = CoCreateInstance(
  169.                           CLSID_TAPI,
  170.                           NULL,
  171.                           CLSCTX_INPROC_SERVER,
  172.                           IID_ITTAPI,
  173.                           (LPVOID *)&gpTapi
  174.                          );
  175.  
  176.     if (hr != S_OK)
  177.     {
  178.         DoMessage(L"CoCreateInstance on TAPI failed");
  179.         return hr;
  180.     }
  181.  
  182.     // call initialize.  this must be called before
  183.     // any other tapi functions are called.
  184.     hr = gpTapi->Initialize();
  185.  
  186.     if (S_OK != hr)
  187.     {
  188.         DoMessage(L"TAPI failed to initialize");
  189.  
  190.         gpTapi->Release();
  191.         gpTapi = NULL;
  192.         
  193.         return hr;
  194.     }
  195.  
  196.  
  197.     // convert the TAPIMEDIATYPEs to BSTRs for
  198.     // convenience throughout the program
  199.     StringFromIID(
  200.                   TAPIMEDIATYPE_AudioIn,
  201.                   &psz
  202.                  );
  203.  
  204.     gbstrAudioIn = SysAllocString( psz );
  205.  
  206.     CoTaskMemFree( psz );
  207.  
  208.     StringFromIID(
  209.                   TAPIMEDIATYPE_AudioOut,
  210.                   &psz
  211.                  );
  212.  
  213.     gbstrAudioOut = SysAllocString( psz );
  214.  
  215.     CoTaskMemFree( psz );
  216.  
  217.     StringFromIID(
  218.                   TAPIMEDIATYPE_VideoIn,
  219.                   &psz
  220.                  );
  221.  
  222.     gbstrVideoIn = SysAllocString( psz );
  223.  
  224.     CoTaskMemFree( psz );
  225.  
  226.     StringFromIID(
  227.                   TAPIMEDIATYPE_VideoOut,
  228.                   &psz
  229.                  );
  230.  
  231.     gbstrVideoOut = SysAllocString( psz );
  232.  
  233.     CoTaskMemFree( psz );
  234.  
  235.     return S_OK;
  236. }
  237.  
  238.  
  239. ///////////////////////////////////////////////////////////////
  240. // ShutdownTapi
  241. ///////////////////////////////////////////////////////////////
  242. void
  243. ShutdownTapi()
  244. {
  245.     // if there is still a call,
  246.     // release it
  247.     if (NULL != gpCall)
  248.     {
  249.         gpCall->Release();
  250.         gpCall = NULL;
  251.     }
  252.  
  253.     // if we have an address object
  254.     // release it
  255.     if (NULL != gpAddress)
  256.     {
  257.         gpAddress->Release();
  258.     }
  259.     
  260.     // release main object.
  261.     if (NULL != gpTapi)
  262.     {
  263.         gpTapi->Shutdown();
  264.         gpTapi->Release();
  265.     }
  266.  
  267.     SysFreeString( gbstrAudioIn );
  268.     SysFreeString( gbstrAudioOut );
  269.     SysFreeString( gbstrVideoIn );
  270.     SysFreeString( gbstrVideoOut );
  271. }
  272.  
  273. ///////////////////////////////////////////////////////////////////////////
  274. // InitAddressTypeComboBox
  275. //
  276. // Put address type string in the combo box
  277. // and save the addresstype with the string
  278. //
  279. ///////////////////////////////////////////////////////////////////////////
  280. void
  281. InitAddressTypeComboBox(
  282.     HWND hComboBox
  283.     )
  284. {
  285.     int i;
  286.  
  287.     i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszConferenceName );
  288.     
  289.     SendMessage(
  290.                 hComboBox,
  291.                 CB_SETITEMDATA , 
  292.                 i,
  293.                 (long)T3_ADDRESSTYPE_CONFERENCENAME
  294.                );
  295.  
  296.     
  297.     i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszEmailName );
  298.     
  299.     SendMessage(
  300.                 hComboBox,
  301.                 CB_SETITEMDATA , 
  302.                 i,
  303.                 (long)T3_ADDRESSTYPE_EMAILNAME
  304.                );
  305.  
  306.     
  307.     i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszMachineName );
  308.     
  309.     SendMessage(
  310.                 hComboBox,
  311.                 CB_SETITEMDATA , 
  312.                 i,
  313.                 (long)T3_ADDRESSTYPE_DOMAINNAME
  314.                );
  315.  
  316.     
  317.     i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszPhoneNumber );
  318.     
  319.     SendMessage(
  320.                 hComboBox,
  321.                 CB_SETITEMDATA , 
  322.                 i,
  323.                 (long)T3_ADDRESSTYPE_PHONENUMBER
  324.                );
  325.  
  326.     
  327.     SendMessage( hComboBox, CB_SETCURSEL, i, 0 );
  328.  
  329.     i = SendMessage( hComboBox, CB_ADDSTRING, 0, (long)gszIPAddress );
  330.     
  331.     SendMessage(
  332.                 hComboBox,
  333.                 CB_SETITEMDATA , 
  334.                 i,
  335.                 (long)T3_ADDRESSTYPE_IPADDRESS
  336.                );
  337.  
  338. }
  339.  
  340. ///////////////////////////////////////////////////////////////////////////
  341. // MainDlgProc
  342. ///////////////////////////////////////////////////////////////////////////
  343. BOOL
  344. CALLBACK
  345. MainDialogProc(
  346.                HWND hDlg,
  347.                UINT uMsg,
  348.                WPARAM wParam,
  349.                LPARAM lParam
  350.               )
  351. {
  352.     switch (uMsg)
  353.     {
  354.         case WM_INITDIALOG:
  355.         {
  356.             HWND hComboBox;
  357.  
  358.             
  359.             // set up dialog
  360.             ghDlg = hDlg;
  361.             
  362.             EnableButton( hDlg, IDOK );
  363.             DisableButton( hDlg, IDC_DISCONNECT );
  364.  
  365.             hComboBox = GetDlgItem( hDlg, IDC_ADDRESSTYPE );
  366.  
  367.             InitAddressTypeComboBox(hComboBox);
  368.  
  369.             SetFocus( hComboBox );
  370.  
  371.             return 0;
  372.         }
  373.  
  374.         case WM_COMMAND:
  375.         {
  376.             if ( LOWORD(wParam) == IDCANCEL )
  377.             {
  378.                 // quit
  379.                 EndDialog( hDlg, 0 );
  380.  
  381.                 return 1;
  382.             }
  383.  
  384.             // dial request
  385.             if ( LOWORD(wParam) == IDOK )
  386.             {
  387.                 HWND hComboBox;
  388.                 DWORD dwIndex;
  389.                 DWORD dwAddressType;
  390.                 WCHAR szAddressToCall[ADDRESSLENGTH];
  391.  
  392.                 
  393.                 // get the address type the user selected.
  394.                 hComboBox = GetDlgItem( hDlg, IDC_ADDRESSTYPE );
  395.                 dwIndex = SendMessage( hComboBox, CB_GETCURSEL, 0, 0 );
  396.  
  397.                 dwAddressType = SendMessage( 
  398.                                              hComboBox,
  399.                                              CB_GETITEMDATA,
  400.                                              dwIndex,
  401.                                              0
  402.                                            );
  403.  
  404.                 // get the address the user wants to call
  405.                 GetDlgItemText(
  406.                                hDlg,
  407.                                IDC_ADDRESS,
  408.                                szAddressToCall,
  409.                                ADDRESSLENGTH
  410.                               );
  411.  
  412.                 // make the call
  413.                 if ( S_OK == MakeTheCall(dwAddressType, szAddressToCall) )
  414.                 {
  415.                     EnableButton( hDlg, IDC_DISCONNECT );
  416.                     DisableButton( hDlg, IDOK );
  417.                 }
  418.                 else
  419.                 {
  420.                     DoMessage(L"The call failed to connect");
  421.                 }
  422.  
  423.                 return 1;
  424.             }
  425.  
  426.             // disconnect requestion
  427.             if ( LOWORD( wParam ) == IDC_DISCONNECT )
  428.             {
  429.                 // disconnect
  430.                 if (S_OK == DisconnectTheCall())
  431.                 {
  432.                     EnableButton( hDlg, IDOK );
  433.                     DisableButton( hDlg, IDC_DISCONNECT );
  434.                 }
  435.                 else
  436.                 {
  437.                     DoMessage(L"The call failed to disconnect");
  438.                 }
  439.  
  440.                 return 1;
  441.             }
  442.  
  443.             return 0;
  444.         }
  445.         default:
  446.  
  447.             return 0;
  448.     }
  449. }
  450.  
  451.  
  452. ////////////////////////////////////////////////////////////////////////
  453. // FindAnAddress
  454. //
  455. // Finds an address object that this application will use to make calls on.
  456. //
  457. // This function finds an address that supports the addresstype passed
  458. // in, as well as the audioin and audioout media types.
  459. //
  460. // Return Value
  461. //          S_OK if it finds an address
  462. //          S_FALSE if it does not find an address
  463. ////////////////////////////////////////////////////////////////////////
  464. HRESULT
  465. FindAnAddress(
  466.               DWORD dwAddressType
  467.              )
  468. {
  469.     HRESULT             hr = S_OK;
  470.     BOOL                bFoundAddress = FALSE;
  471.     IEnumAddress *      pEnumAddress;
  472.     ITAddress *         pAddress;
  473.     IEnumAddressType *  pEnumAddressTypes;
  474.     DWORD               dwType;
  475.  
  476.     // if we have an address object
  477.     // release it
  478.     if (NULL != gpAddress)
  479.     {
  480.         gpAddress->Release();
  481.         gpAddress = NULL;
  482.     }
  483.  
  484.     // enumerate the addresses
  485.     hr = gpTapi->_EnumerateAddresses( &pEnumAddress );
  486.  
  487.     if (S_OK != hr)
  488.     {
  489.         return hr;
  490.     }
  491.  
  492.     while ( !bFoundAddress )
  493.     {
  494.         // get the next address
  495.         hr = pEnumAddress->Next( 1, &pAddress, NULL );
  496.  
  497.         if (S_OK != hr)
  498.         {
  499.             break;
  500.         }
  501.  
  502.         // enumerate the address types that
  503.         // this address supports
  504.         hr = pAddress->_EnumerateAddressType( &pEnumAddressTypes );
  505.  
  506.         if (S_OK != hr)
  507.         {
  508.             pAddress->Release();
  509.         
  510.             continue;
  511.         }
  512.  
  513.         while (TRUE)
  514.         {
  515.             ITMediaSupport * pMediaSupport;
  516.             VARIANT_BOOL     bSupport;
  517.             
  518.             // get the next address type
  519.             hr = pEnumAddressTypes->Next( 1, &dwType, NULL );
  520.  
  521.             if (S_OK != hr)
  522.             {
  523.                 break;
  524.             }
  525.  
  526.             // is the type we are looking for?
  527.             if ( dwAddressType == dwType )
  528.             {
  529.                 // yes
  530.                 pAddress->QueryInterface( IID_ITMediaSupport, (void **)&pMediaSupport );
  531.  
  532.                 // does it support AudioIn?
  533.                 pMediaSupport->QueryMediaType(
  534.                                               gbstrAudioIn,
  535.                                               &bSupport
  536.                                              );
  537.  
  538.                 if (bSupport)
  539.                 {
  540.                     // does it also support AudioOut?
  541.                     pMediaSupport->QueryMediaType(
  542.                         gbstrAudioOut,
  543.                         &bSupport
  544.                         );
  545.  
  546.                     if (bSupport)
  547.                     {
  548.                         // save
  549.                         pMediaSupport->Release();
  550.                         
  551.                         gpAddress = pAddress;
  552.                         gpAddress->AddRef();
  553.  
  554.                         bFoundAddress = TRUE;
  555.                         break;
  556.                     }
  557.                 }
  558.  
  559.                 pMediaSupport->Release();
  560.             }
  561.         }
  562.  
  563.         pAddress->Release();
  564.         pEnumAddressTypes->Release();
  565.     }
  566.  
  567.     pEnumAddress->Release();
  568.     
  569.     if (!bFoundAddress)
  570.     {
  571.         return S_FALSE;
  572.     }
  573.  
  574.     return S_OK;
  575. }
  576.  
  577.  
  578. /////////////////////////////////////////////////////////////////
  579. // CreateMediaTerminals
  580. //
  581. // Create audioin and audioout terminals.
  582. //
  583. // If the address also supports video, create
  584. // Videoin and videoout terminals, too.
  585. //
  586. // This function assumes that ppMediaTerminals has a size no less than four.
  587. /////////////////////////////////////////////////////////////////
  588. HRESULT
  589. CreateMediaTerminals(
  590.                      ITMediaTerminal ** ppMediaTerminals,
  591.                      PLONG pNumMediaTerminals
  592.                     )
  593. {
  594.     int count = 0;
  595.     HRESULT hr;
  596.  
  597.     // get the mediaterminal for audioin
  598.     hr = GetMediaTerminal(
  599.                           gbstrAudioIn,
  600.                           &ppMediaTerminals[count]
  601.                          );
  602.  
  603.     if (S_OK != hr)
  604.     {
  605.         return hr;
  606.     }
  607.     
  608.     count ++;
  609.  
  610.     // get the mediaterminal for audioout
  611.     hr = GetMediaTerminal(
  612.                           gbstrAudioOut,
  613.                           &ppMediaTerminals[count]
  614.                          );
  615.  
  616.     if (S_OK != hr)
  617.     {
  618.         ppMediaTerminals[0]->Release();
  619.         return hr;
  620.     }
  621.  
  622.     count ++;
  623.     
  624.     // Find out if the address supports video.
  625.     ITMediaSupport * pMediaSupport;
  626.     VARIANT_BOOL     bSupport;
  627.             
  628.     gpAddress->QueryInterface( IID_ITMediaSupport, (void **)&pMediaSupport );
  629.  
  630.     // does it support VideoIn?
  631.     pMediaSupport->QueryMediaType(
  632.                                   gbstrVideoIn,
  633.                                   &bSupport
  634.                                  );
  635.  
  636.     if (bSupport)
  637.     {
  638.         // get the mediaterminal for VideoIn
  639.         hr = GetVideoInMediaTerminal(
  640.                                   &ppMediaTerminals[count]
  641.                                  );
  642.  
  643.         if (S_OK == hr)
  644.         {
  645.             count ++;
  646.         }
  647.  
  648.         // does it also support VideoOut?
  649.         pMediaSupport->QueryMediaType(
  650.             gbstrVideoOut,
  651.             &bSupport
  652.             );
  653.  
  654.         if (bSupport)
  655.         {
  656.             // get the mediaterminal for Videoout
  657.             hr = GetMediaTerminal(
  658.                                   gbstrVideoOut,
  659.                                   &ppMediaTerminals[count]
  660.                                  );
  661.     
  662.             if (S_OK == hr)
  663.             {
  664.                 count ++;
  665.             }
  666.         }
  667.     }
  668.  
  669.     pMediaSupport->Release();
  670.     
  671.     *pNumMediaTerminals = count;
  672.  
  673.     return S_OK;
  674. }
  675.  
  676. /////////////////////////////////////////////////////////////////
  677. // CreateMediaTerminalSafeArray
  678. //
  679. /////////////////////////////////////////////////////////////////
  680. SAFEARRAY *
  681. CreateMediaTerminalSafeArray(
  682.                              ITMediaTerminal ** ppMediaTerminals,
  683.                              LONG nNumMediaTerminals
  684.                             )
  685. {
  686.     SAFEARRAY *             psa;
  687.     SAFEARRAYBOUND          sabound[1];
  688.  
  689.     // create a safearray with two elements
  690.     // to pass the mediaterminals to tapi
  691.     sabound[0].lLbound = 0;
  692.     sabound[0].cElements = nNumMediaTerminals;
  693.  
  694.     psa = SafeArrayCreate(
  695.                           VT_UNKNOWN,
  696.                           1,
  697.                           sabound
  698.                          );
  699.  
  700.     if (NULL != psa)
  701.     {
  702.         // save them in the safearray
  703.         for (long i = 0; i < nNumMediaTerminals; i ++)
  704.         {
  705.             SafeArrayPutElement(
  706.                             psa,
  707.                             &i,
  708.                             ppMediaTerminals[i]
  709.                            );
  710.         }
  711.     }
  712.     return psa;
  713. }
  714.  
  715. /////////////////////////////////////////////////////////////////
  716. // ReleaseMediaTerminals
  717. //
  718. /////////////////////////////////////////////////////////////////
  719. void
  720. ReleaseMediaTerminals(
  721.                       ITMediaTerminal ** ppMediaTerminals,
  722.                       LONG nNumMediaTerminals
  723.                      )
  724. {
  725.     for (long i = 0; i < nNumMediaTerminals; i ++)
  726.     {
  727.         if (ppMediaTerminals[i])
  728.         {
  729.             ppMediaTerminals[i]->Release();
  730.         }
  731.     }
  732. }
  733.  
  734. /////////////////////////////////////////////////////////////////
  735. // MakeTheCall
  736. //
  737. // Sets up and makes a call
  738. /////////////////////////////////////////////////////////////////
  739. HRESULT
  740. MakeTheCall(
  741.             DWORD dwAddressType,
  742.             PWCHAR szAddressToCall
  743.            )
  744. {
  745.     HRESULT                 hr = S_OK;
  746.     ITMediaTerminal *       ppMediaTerminals[MAXTERMINALS];
  747.     long                    nNumMediaTerminals = MAXTERMINALS;
  748.     SAFEARRAY *             psa;
  749.     VARIANT                 var;
  750.     BSTR                    bstrAddressToCall;
  751.  
  752.     // find an address object that
  753.     // we will use to make calls on
  754.     hr = FindAnAddress(dwAddressType);
  755.  
  756.     if (S_OK != hr)
  757.     {
  758.         DoMessage(L"Could not find an address to make a phone call on");
  759.  
  760.         return hr;
  761.     }
  762.  
  763.     bstrAddressToCall = SysAllocString( szAddressToCall );
  764.  
  765.     hr = gpAddress->CreateCall( bstrAddressToCall, &gpCall );
  766.  
  767.     SysFreeString ( bstrAddressToCall );
  768.     
  769.     if (S_OK != hr)
  770.     {
  771.         return hr;
  772.     }
  773.                                
  774.     hr = CreateMediaTerminals(ppMediaTerminals, &nNumMediaTerminals);
  775.  
  776.     if (S_OK != hr)
  777.     {
  778.         gpCall->Release();
  779.         gpCall = NULL;
  780.         return hr;
  781.     }
  782.  
  783.     psa = CreateMediaTerminalSafeArray(ppMediaTerminals, nNumMediaTerminals);
  784.  
  785.     if (S_OK != hr)
  786.     {
  787.         gpCall->Release();
  788.         gpCall = NULL;
  789.         ReleaseMediaTerminals(ppMediaTerminals, nNumMediaTerminals);
  790.         return hr;
  791.     }
  792.  
  793.  
  794.     // put the safearray in a variant
  795.     VariantInit(&var);
  796.     var.vt = VT_ARRAY;
  797.     var.parray = psa;
  798.  
  799.     // call SelectMediaTerminals
  800.     hr = gpCall->SelectMediaTerminals( var );
  801.  
  802.     ReleaseMediaTerminals(ppMediaTerminals, nNumMediaTerminals);
  803.  
  804.     SafeArrayDestroy( psa );
  805.  
  806.     if (S_OK != hr)
  807.     {
  808.         return hr;
  809.     }
  810.  
  811.     // We're now ready to call connect.
  812.     //
  813.     // the TRUE parameter indicates that this
  814.     // call is sychronous - that is, it won't
  815.     // return until the call is in the connected
  816.     // state (or fails to connect)
  817.     // Since this is called in the UI thread,
  818.     // this means that the app will appear
  819.     // to hang until this function returns.
  820.     // Some TAPI service providers may take a long
  821.     // time for a call to reach the connected state.
  822.     hr = gpCall->Connect( TRUE );
  823.  
  824.     if (S_OK != hr)
  825.     {
  826.         gpCall->Release();
  827.         gpCall = NULL;
  828.         return hr;
  829.     }
  830.     
  831.     return hr;
  832. }
  833.  
  834.  
  835. /////////////////////////////////////////////////////////
  836. // GetMediaTerminal
  837. //
  838. // Creates a MediaTerminal for the bstrMediaType passed
  839. // in, using the default terminal for the bstrMediaType
  840. //
  841. /////////////////////////////////////////////////////////
  842. HRESULT
  843. GetMediaTerminal(
  844.                  BSTR bstrMediaType,
  845.                  ITMediaTerminal ** ppMediaTerminal
  846.                 )
  847. {
  848.     HRESULT             hr = S_OK;
  849.     ITTerminalSupport * pTerminalSupport;
  850.     ITTerminal *        pTerminal;
  851.  
  852.     // get the terminal support interface
  853.     gpAddress->QueryInterface( IID_ITTerminalSupport, (void **)&pTerminalSupport );
  854.     
  855.     // get the default terminal for MediaType
  856.     hr = pTerminalSupport->GetDefaultTerminal(
  857.                                               bstrMediaType,
  858.                                               &pTerminal
  859.                                              );
  860.  
  861.  
  862.     pTerminalSupport->Release();
  863.  
  864.     if (S_OK != hr)
  865.     {
  866.         return hr;
  867.     }
  868.  
  869.     // Create a media terminal for MediaType
  870.     // Use the default terminal we just got
  871.     hr = gpTapi->CreateMediaTerminal(
  872.                                      bstrMediaType,
  873.                                      pTerminal,
  874.                                      ppMediaTerminal
  875.                                     );
  876.  
  877.     pTerminal->Release();
  878.  
  879.     if (S_OK != hr)
  880.     {
  881.         return hr;
  882.     }
  883.  
  884.     return S_OK;
  885.  
  886. }
  887.  
  888. /////////////////////////////////////////////////////////
  889. // GetVideoInMediaTerminal
  890. //
  891. // Creates a MediaTerminal for the VideoIn mediatype 
  892. // This is a dynamic terminal type.
  893. //
  894. /////////////////////////////////////////////////////////
  895. HRESULT
  896. GetVideoInMediaTerminal(
  897.                  ITMediaTerminal ** ppMediaTerminal
  898.                 )
  899. {
  900.     HRESULT             hr = S_OK;
  901.     ITTerminalSupport * pTerminalSupport;
  902.     ITTerminal *        pTerminal;
  903.  
  904.     // get the terminal support interface
  905.     gpAddress->QueryInterface( IID_ITTerminalSupport, (void **)&pTerminalSupport );
  906.     
  907.     BSTR bstrTerminalClass;
  908.     LPOLESTR lpTerminalClass;
  909.  
  910.     StringFromIID(
  911.                 CLSID_VideoWindowTerm,
  912.                 &lpTerminalClass
  913.                 );
  914.  
  915.     bstrTerminalClass = SysAllocString ( lpTerminalClass );
  916.  
  917.     CoTaskMemFree( lpTerminalClass );
  918.  
  919.     hr = pTerminalSupport->CreateTerminal(
  920.         bstrTerminalClass,
  921.         &pTerminal
  922.         );
  923.  
  924.     SysFreeString( bstrTerminalClass );
  925.     pTerminalSupport->Release();
  926.  
  927.     if (FAILED(hr))
  928.     {
  929.         return hr;
  930.     }
  931.  
  932.     // Create a media terminal for MediaType
  933.     // Use the default terminal we just got
  934.     hr = gpTapi->CreateMediaTerminal(
  935.                                      gbstrVideoIn,
  936.                                      pTerminal,
  937.                                      ppMediaTerminal
  938.                                     );
  939.  
  940.     pTerminal->Release();
  941.  
  942.     if (S_OK != hr)
  943.     {
  944.         return hr;
  945.     }
  946.  
  947.     return S_OK;
  948.  
  949. }
  950.  
  951.  
  952. //////////////////////////////////////////////////////////////////////
  953. // DisconnectTheCall
  954. //
  955. // Disconnects the call
  956. //////////////////////////////////////////////////////////////////////
  957. HRESULT
  958. DisconnectTheCall()
  959. {
  960.     HRESULT         hr = S_OK;
  961.  
  962.     if (NULL != gpCall)
  963.     {
  964.         hr = gpCall->Disconnect( DC_NORMAL );
  965.  
  966.         gpCall->Release();
  967.         gpCall = NULL;
  968.     
  969.         return hr;
  970.     }
  971.  
  972.     return S_FALSE;
  973. }
  974.  
  975.  
  976.  
  977. ///////////////////////////////////////////////////////////////////
  978. //
  979. // HELPER FUNCTIONS
  980. //
  981. ///////////////////////////////////////////////////////////////////
  982.  
  983.  
  984. ///////////////////////////////////////////////////////////////////
  985. // DoMessage
  986. ///////////////////////////////////////////////////////////////////
  987. void
  988. DoMessage(
  989.           LPWSTR pszMessage
  990.          )
  991. {
  992.     MessageBox(
  993.                ghDlg,
  994.                pszMessage,
  995.                gszTapi30,
  996.                MB_OK
  997.               );
  998. }
  999.  
  1000. ///////////////////////////////////////////////////////////////
  1001. // EnableButton
  1002. //
  1003. // Enable, make default, and setfocus to a button
  1004. ///////////////////////////////////////////////////////////////
  1005. void
  1006. EnableButton(
  1007.              HWND hDlg,
  1008.              int ID
  1009.             )
  1010. {
  1011.     SendDlgItemMessage(
  1012.                        hDlg,
  1013.                        ID,
  1014.                        BM_SETSTYLE,
  1015.                        BS_DEFPUSHBUTTON,
  1016.                        0
  1017.                       );
  1018.     EnableWindow(
  1019.                  GetDlgItem( hDlg, ID ),
  1020.                  TRUE
  1021.                 );
  1022.     SetFocus(
  1023.              GetDlgItem( hDlg, ID )
  1024.             );
  1025. }
  1026.  
  1027. //////////////////////////////////////////////////////////////
  1028. // DisableButton
  1029. //
  1030. // Disable a button
  1031. //////////////////////////////////////////////////////////////
  1032. void
  1033. DisableButton(
  1034.               HWND hDlg,
  1035.               int ID
  1036.              )
  1037. {
  1038.     SendDlgItemMessage(
  1039.                        hDlg,
  1040.                        ID,
  1041.                        BM_SETSTYLE,
  1042.                        BS_PUSHBUTTON,
  1043.                        0
  1044.                       );
  1045.     EnableWindow(
  1046.                  GetDlgItem( hDlg, ID ),
  1047.                  FALSE
  1048.                 );
  1049. }
  1050.  
  1051.  
  1052.  
  1053.