home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / directx / override / override.c < prev    next >
C/C++ Source or Header  |  1997-07-14  |  28KB  |  960 lines

  1. /*==========================================================================
  2.  *
  3.  *  Copyright (C) 1996-1997 Microsoft Corporation.  All Rights Reserved.
  4.  *
  5.  *  File:       override.c
  6.  *  Content:    Implementation of a DirectPlay launching utility
  7.  *
  8.  ***************************************************************************/
  9.  
  10. #define INITGUID
  11.  
  12. #include <windows.h>
  13. #include <windowsx.h>
  14. #include <objbase.h>
  15. #include <cguid.h>
  16.  
  17. #include "dplay.h"
  18. #include "dplobby.h"
  19.  
  20. #include "resource.h"
  21.  
  22. #define NAMEMAX            200            // string size
  23. #define TIMERID            1            // timer ID to use
  24. #define TIMERINTERVAL    1000        // timer interval
  25.  
  26. typedef struct {
  27.     LPDIRECTPLAY3A        lpDPlay;
  28.     GUID                guidInstance;
  29. } STATUSCONTEXT, *LPSTATUSCONTEXT;
  30.  
  31. // guid for this application
  32. // {126E6180-D307-11d0-9C4F-00A0C905425E}
  33. DEFINE_GUID(OVERRIDE_GUID, 
  34. 0x126e6180, 0xd307, 0x11d0, 0x9c, 0x4f, 0x0, 0xa0, 0xc9, 0x5, 0x42, 0x5e);
  35.  
  36. // prototypes
  37. BOOL CALLBACK        OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  38. BOOL CALLBACK        SessionsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  39.  
  40. HRESULT                InitializeOverrideWindow(HWND hWnd, LPDIRECTPLAYLOBBY2A *lplpDPlayLobby);
  41. void                DestroyOverrideWindow(HWND hWnd, LPDIRECTPLAY3A lpDPlay, LPDIRECTPLAYLOBBY2A lpDPlayLobby);
  42. HRESULT                UpdateAddressInfo(HWND hWnd, LPDIRECTPLAYLOBBY2A lpDPlayLobby2A);
  43. HRESULT                DoHostOrJoin(HINSTANCE hInstance, HWND hWnd, LPDIRECTPLAYLOBBY2A lpDPlayLobby, BOOL bHost, LPDIRECTPLAY3A *lplpDPlay);
  44. BOOL FAR PASCAL        DirectPlayEnumerateCallback(LPGUID lpSPGuid, LPTSTR lpszSPName,
  45.                         DWORD dwMajorVersion, DWORD dwMinorVersion, LPVOID lpContext);
  46. HRESULT                GetServiceProviderGuid(HWND hWnd, LPGUID lpguidServiceProvider);
  47. void                DeleteServiceProviderCombo(HWND hWnd);
  48. HRESULT                FillModemComboBox(HWND hWnd, LPDIRECTPLAYLOBBY2A lpDPlayLobby);
  49. BOOL                DlgItemIsChecked(HWND hDlg, int nIDDlgItem);
  50. void                EnableDlgButton(HWND hDlg, int nIDDlgItem, BOOL bEnable);
  51.  
  52. // ---------------------------------------------------------------------------
  53. // WinMain
  54. // ---------------------------------------------------------------------------
  55. // Description:             Main windows entry point.
  56. // Arguments:
  57. //  HINSTANCE               [in] Standard windows stuff
  58. //  HINSTANCE               [in]
  59. //  LPSTR                   [in]
  60. //  int                     [in]
  61. // Returns:
  62. //  int                        
  63. int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  64.                     LPSTR lpCmdLine, int nCmdShow )
  65. {
  66.     HRESULT        hr;
  67.     int            iResult = 0;
  68.  
  69.     // initialize COM library
  70.     hr = CoInitialize(NULL);
  71.     if FAILED(hr)
  72.         goto FAILURE;
  73.  
  74.     iResult = DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_OVERRIDEDIALOG), NULL, OverrideWndProc, (LPARAM) hInstance);
  75.  
  76. FAILURE:
  77.     // Uninitialize the COM library
  78.     CoUninitialize();
  79.  
  80.     return (iResult);
  81. }
  82.  
  83.  
  84. // ---------------------------------------------------------------------------
  85. // OverrideWndProc
  86. // ---------------------------------------------------------------------------
  87. // Description:             Message callback function for Override dialog.
  88. // Arguments:
  89. //  HWND                    [in] Dialog window handle.
  90. //  UINT                    [in] Window message identifier.
  91. //  WPARAM                  [in] Depends on message.
  92. //  LPARAM                  [in] Depends on message.
  93. // Returns:
  94. //  BOOL                    TRUE if message was processed internally.
  95. BOOL CALLBACK OverrideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  96. {
  97.     static HINSTANCE            hInstance;
  98.     static LPDIRECTPLAY3A        lpDPlay;
  99.     static LPDIRECTPLAYLOBBY2A    lpDPlayLobby;
  100.     HRESULT                        hr;
  101.  
  102.     switch(uMsg)
  103.     {
  104.         case WM_INITDIALOG:
  105.             // Save the instance handle
  106.             hInstance = (HINSTANCE)lParam;
  107.                         
  108.             // Initialize dialog with launcher information
  109.             lpDPlay = NULL;
  110.             lpDPlayLobby = NULL;
  111.             hr = InitializeOverrideWindow(hWnd, &lpDPlayLobby);
  112.             if FAILED(hr)
  113.                     SetDlgItemText(hWnd, IDC_STATUSEDIT, "Could not initialize DirectPlay");
  114.             break;
  115.  
  116.         case WM_DESTROY:
  117.             // Destroy launcher information in dialog
  118.             DestroyOverrideWindow(hWnd, lpDPlay, lpDPlayLobby);
  119.             break;
  120.  
  121.         case WM_COMMAND:
  122.             switch(LOWORD(wParam))
  123.             {
  124.                 case IDC_SPCOMBO:
  125.  
  126.                     switch (HIWORD(wParam))
  127.                     {
  128.                     case CBN_SELCHANGE:
  129.                         UpdateAddressInfo(hWnd, lpDPlayLobby);
  130.                         break;
  131.                     }
  132.                     break;
  133.  
  134.                 case IDC_MODEMCOMBO:
  135.  
  136.                     switch (HIWORD(wParam))
  137.                     {
  138.                     case CBN_SELCHANGE:
  139.                         break;
  140.                     }
  141.                     break;
  142.  
  143.                 case IDC_HOSTBUTTON:
  144.  
  145.                     SetDlgItemText(hWnd, IDC_STATUSEDIT, "Hosting...");
  146.                     hr = DoHostOrJoin(hInstance, hWnd, lpDPlayLobby, TRUE, &lpDPlay);
  147.                     if FAILED(hr)
  148.                         SetDlgItemText(hWnd, IDC_STATUSEDIT, "Failed to host");
  149.                     else
  150.                         SetDlgItemText(hWnd, IDC_STATUSEDIT, "Host successfull");
  151.                     break;
  152.  
  153.                 case IDC_JOINBUTTON:
  154.  
  155.                     SetDlgItemText(hWnd, IDC_STATUSEDIT, "Joining...");
  156.                     hr = DoHostOrJoin(hInstance, hWnd, lpDPlayLobby, FALSE, &lpDPlay);
  157.                     if FAILED(hr)
  158.                         SetDlgItemText(hWnd, IDC_STATUSEDIT, "Failed to join");
  159.                     else
  160.                         SetDlgItemText(hWnd, IDC_STATUSEDIT, "Join successfull");
  161.                     break;
  162.  
  163.                 case IDCANCEL:
  164.                     // Return failure
  165.                     EndDialog(hWnd, TRUE);
  166.  
  167.                     break;
  168.             }
  169.  
  170.             break;
  171.     }
  172.  
  173.     // Allow for default processing
  174.     return FALSE;
  175. }
  176.  
  177. HRESULT InitializeOverrideWindow(HWND hWnd, LPDIRECTPLAYLOBBY2A *lplpDPlayLobby)
  178. {
  179.     LPDIRECTPLAYLOBBYA    lpDPlayLobbyA = NULL;
  180.     LPDIRECTPLAYLOBBY2A    lpDPlayLobby2A = NULL;
  181.     HRESULT                hr;
  182.         
  183.     // get ANSI DirectPlayLobby interface
  184.     hr = DirectPlayLobbyCreate(NULL, &lpDPlayLobbyA, NULL, NULL, 0);
  185.     if FAILED(hr)
  186.         goto FAILURE;
  187.  
  188.     // get ANSI DirectPlayLobby2 interface
  189.     hr = lpDPlayLobbyA->lpVtbl->QueryInterface(lpDPlayLobbyA,
  190.                             &IID_IDirectPlayLobby2A, (LPVOID *) &lpDPlayLobby2A);
  191.     if FAILED(hr)
  192.         goto FAILURE;
  193.  
  194.     // don't need DirectPlayLobby interface anymore
  195.     lpDPlayLobbyA->lpVtbl->Release(lpDPlayLobbyA);
  196.     lpDPlayLobbyA = NULL;
  197.  
  198.     // put all the service providers in combo box
  199.     DirectPlayEnumerate(DirectPlayEnumerateCallback, hWnd);
  200.     SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETCURSEL, (WPARAM) 0, (LPARAM) 0);
  201.  
  202.     // fill modem combo box with available modems
  203.     FillModemComboBox(hWnd, lpDPlayLobby2A);
  204.  
  205.     // update display first service provider
  206.     UpdateAddressInfo(hWnd, lpDPlayLobby2A);
  207.  
  208.     // return the ANSI lobby interface
  209.     *lplpDPlayLobby = lpDPlayLobby2A;
  210.  
  211.     return (DP_OK);
  212.  
  213. FAILURE:
  214.     if (lpDPlayLobbyA)
  215.         lpDPlayLobbyA->lpVtbl->Release(lpDPlayLobbyA);
  216.     if (lpDPlayLobby2A)
  217.         lpDPlayLobby2A->lpVtbl->Release(lpDPlayLobby2A);
  218.  
  219.     return (hr);
  220. }
  221.  
  222. void DestroyOverrideWindow(HWND hWnd, LPDIRECTPLAY3A lpDPlay, LPDIRECTPLAYLOBBY2A lpDPlayLobby)
  223. {
  224.     // delete combo box data items
  225.     DeleteServiceProviderCombo(hWnd);
  226.  
  227.     // release the dplay interface
  228.     if (lpDPlay)
  229.         lpDPlay->lpVtbl->Release(lpDPlay);
  230.  
  231.     // release the lobby interface
  232.     if (lpDPlayLobby)
  233.         lpDPlayLobby->lpVtbl->Release(lpDPlayLobby);
  234. }
  235.  
  236. // ---------------------------------------------------------------------------
  237. // DirectPlayEnumerateCallback
  238. // ---------------------------------------------------------------------------
  239. // Description:             Enumeration callback called by DirectPlay.
  240. //                            Enumerates service providers registered with DirectPlay.
  241. // Arguments:
  242. //  LPGUID                    [in] GUID of service provider
  243. //  LPTSTR                    [in] name of service provider
  244. //  DWORD                    [in] major version of DirectPlay
  245. //  DWORD                    [in] minor version of DirectPlay
  246. //  LPVOID                    [in] user-defined context
  247. // Returns:
  248. //  BOOL                    TRUE to continue enumerating
  249. BOOL FAR PASCAL DirectPlayEnumerateCallback(
  250.                         LPGUID        lpSPGuid,
  251.                         LPTSTR        lpszSPName,
  252.                         DWORD        dwMajorVersion,
  253.                         DWORD        dwMinorVersion,
  254.                         LPVOID        lpContext)
  255. {
  256.     HWND            hWnd = lpContext;
  257.     LRESULT            iIndex;
  258.     LPGUID            lpGuid;
  259.  
  260.     // store service provider name in combo box
  261.     iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_ADDSTRING, 0, (LPARAM) lpszSPName);
  262.     if (iIndex == CB_ERR)
  263.         goto FAILURE;
  264.  
  265.     // make space for application GUID
  266.     lpGuid = (LPGUID) GlobalAllocPtr(GHND, sizeof(GUID));
  267.     if (lpGuid == NULL)
  268.         goto FAILURE;
  269.  
  270.     // store pointer to GUID in combo box
  271.     *lpGuid = *lpSPGuid;
  272.     SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpGuid);
  273.  
  274. FAILURE:
  275.     return (TRUE);
  276. }
  277.  
  278. HRESULT GetServiceProviderGuid(HWND hWnd, LPGUID lpguidServiceProvider)
  279. {
  280.     LONG    iIndex;
  281.  
  282.     // get guid for service provider
  283.     iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETCURSEL,
  284.                                 (WPARAM) 0, (LPARAM) 0);
  285.     if (iIndex == CB_ERR)
  286.         return (DPERR_GENERIC);
  287.  
  288.     iIndex = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA,
  289.                                 (WPARAM) iIndex, (LPARAM) 0);
  290.     if ((iIndex == CB_ERR) || (iIndex == 0))
  291.         return (DPERR_GENERIC);
  292.  
  293.     *lpguidServiceProvider = *((LPGUID) iIndex);
  294.  
  295.     return (DP_OK);
  296. }
  297.  
  298. void DeleteServiceProviderCombo(HWND hWnd)
  299. {
  300.     WPARAM    i;
  301.     LONG    lpData;
  302.     
  303.     // destroy the data stored with each combo box item
  304.     i = 0;
  305.     while (TRUE)
  306.     {
  307.         // get data pointer stored with item
  308.         lpData = SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_GETITEMDATA,
  309.                                     (WPARAM) i, (LPARAM) 0);
  310.         if (lpData == CB_ERR)        // error getting data
  311.             break;
  312.  
  313.         if (lpData)                    // data to delete
  314.             GlobalFreePtr((LPVOID) lpData);
  315.  
  316.         i += 1;
  317.     }
  318.  
  319.     // delete all items in list
  320.     SendDlgItemMessage(hWnd, IDC_SPCOMBO, CB_RESETCONTENT,
  321.                                 (WPARAM) 0, (LPARAM) 0);
  322. }
  323.  
  324. void DeleteSessionInstanceList(HWND hWnd)
  325. {
  326.     WPARAM    i;
  327.     LONG    lpData;
  328.     
  329.     // destroy the GUID's stored with each session name
  330.     i = 0;
  331.     while (TRUE)
  332.     {
  333.         // get data pointer stored with item
  334.         lpData = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  335.                                     (WPARAM) i, (LPARAM) 0);
  336.         if (lpData == CB_ERR)        // error getting data
  337.             break;
  338.  
  339.         if (lpData)                    // data to delete
  340.             GlobalFreePtr((LPVOID) lpData);
  341.  
  342.         i += 1;
  343.     }
  344.  
  345.     // delete all items in list
  346.     SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_RESETCONTENT,
  347.                                 (WPARAM) 0, (LPARAM) 0);
  348. }
  349.  
  350. void SelectSessionInstance(HWND hWnd, LPGUID lpguidSessionInstance)
  351. {
  352.     WPARAM    i, iIndex;
  353.     LONG    lpData;
  354.     
  355.     // loop over the GUID's stored with each session name
  356.     // to find the one that matches what was passed in
  357.     i = 0;
  358.     iIndex = 0;
  359.     while (TRUE)
  360.     {
  361.         // get data pointer stored with item
  362.         lpData = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  363.                                     (WPARAM) i, (LPARAM) 0);
  364.         if (lpData == CB_ERR)        // error getting data
  365.             break;
  366.  
  367.         if (lpData == 0)            // no data to compare to
  368.             continue;
  369.  
  370.         // guid matches
  371.         if (IsEqualGUID(lpguidSessionInstance, (LPGUID) lpData))
  372.         {
  373.             iIndex = i;                // store index of this string
  374.             break;
  375.         }
  376.  
  377.         i += 1;
  378.     }
  379.  
  380.     // select this item
  381.     SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_SETCURSEL, (WPARAM) iIndex, (LPARAM) 0);
  382. }
  383.  
  384. HRESULT GetSessionInstanceGuid(HWND hWnd, LPGUID lpguidSessionInstance)
  385. {
  386.     LONG    iIndex;
  387.  
  388.     // get guid for session
  389.     iIndex = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETCURSEL,
  390.                                 (WPARAM) 0, (LPARAM) 0);
  391.     if (iIndex == LB_ERR)
  392.         return (DPERR_GENERIC);
  393.  
  394.     iIndex = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETITEMDATA,
  395.                                 (WPARAM) iIndex, (LPARAM) 0);
  396.     if ((iIndex == LB_ERR) || (iIndex == 0))
  397.         return (DPERR_GENERIC);
  398.  
  399.     *lpguidSessionInstance = *((LPGUID) iIndex);
  400.  
  401.     return (DP_OK);
  402. }
  403.  
  404. BOOL FAR PASCAL EnumSessionsCallback(
  405.                         LPCDPSESSIONDESC2    lpSessionDesc,
  406.                         LPDWORD                lpdwTimeOut,
  407.                         DWORD                dwFlags,
  408.                         LPVOID                lpContext)
  409. {
  410.     HWND            hWnd = (HWND) lpContext;
  411.     LPGUID            lpGuid;
  412.     LONG            iIndex;
  413.  
  414.     // see if last session has been enumerated
  415.     if (dwFlags & DPESC_TIMEDOUT)
  416.         return (FALSE);                        
  417.  
  418.     // store session name in list
  419.     iIndex = SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_ADDSTRING, 
  420.                                 (WPARAM) 0, (LPARAM) lpSessionDesc->lpszSessionNameA);
  421.  
  422.     if (iIndex == LB_ERR)
  423.         goto FAILURE;
  424.  
  425.  
  426.     // make space for session instance guid
  427.     lpGuid = (LPGUID) GlobalAllocPtr( GHND, sizeof(GUID) );
  428.     if (lpGuid == NULL)
  429.         goto FAILURE;
  430.  
  431.     // store pointer to guid in list
  432.     *lpGuid = lpSessionDesc->guidInstance;
  433.     SendDlgItemMessage( hWnd, IDC_SESSIONLIST, LB_SETITEMDATA, (WPARAM) iIndex, (LPARAM) lpGuid);
  434.  
  435. FAILURE:
  436.     return (TRUE);
  437. }
  438.  
  439. BOOL CALLBACK SessionsWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  440. {
  441.     static LPSTATUSCONTEXT    lpContext;
  442.     static LPDIRECTPLAY3A    lpDPlay;
  443.     static UINT                idTimer;
  444.     static BOOL                bInsideEnumSessions;
  445.     DPSESSIONDESC2            sessionDesc;
  446.     GUID                    guidSessionInstance;
  447.     LONG                    iIndex;
  448.     HRESULT                    hr;
  449.  
  450.     switch(uMsg)
  451.     {
  452.         case WM_INITDIALOG:
  453.             lpContext = (LPSTATUSCONTEXT) lParam;
  454.             lpDPlay = lpContext->lpDPlay;
  455.             bInsideEnumSessions = FALSE;
  456.  
  457.             // can't join until there is a session
  458.             EnableDlgButton(hWnd, IDC_JOINSESSIONBUTTON, FALSE);
  459.  
  460.             // set a timer to refresh the session list
  461.             idTimer = SetTimer(hWnd, TIMERID, TIMERINTERVAL, NULL);
  462.             break;
  463.  
  464.         case WM_DESTROY:
  465.             if (idTimer)
  466.             {
  467.                 KillTimer(hWnd, idTimer); 
  468.                 idTimer = 0;
  469.             }
  470.             DeleteSessionInstanceList(hWnd);
  471.             break;
  472.  
  473.         case WM_TIMER:
  474.             // make sure we don't re-enter EnumSessions
  475.             if (bInsideEnumSessions)
  476.                 break;
  477.  
  478.             // get guid of currently selected session
  479.             guidSessionInstance = GUID_NULL;
  480.             hr = GetSessionInstanceGuid(hWnd, &guidSessionInstance);
  481.  
  482.             // delete existing session list
  483.             DeleteSessionInstanceList(hWnd);
  484.  
  485.             // enum sessions
  486.             ZeroMemory(&sessionDesc, sizeof(DPSESSIONDESC2));
  487.             sessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  488.             sessionDesc.guidApplication = OVERRIDE_GUID;
  489.  
  490.             bInsideEnumSessions = TRUE;
  491.             hr = lpDPlay->lpVtbl->EnumSessions(lpDPlay, &sessionDesc, 0,
  492.                                     EnumSessionsCallback, hWnd,
  493.                                     DPENUMSESSIONS_AVAILABLE |
  494.                                     DPENUMSESSIONS_ASYNC |
  495.                                     DPENUMSESSIONS_RETURNSTATUS);
  496.             bInsideEnumSessions = FALSE;
  497.  
  498.             // select the session that was previously selected
  499.             SelectSessionInstance(hWnd, &guidSessionInstance);
  500.  
  501.             // hilite "Join" button only if there are sessions to join
  502.             iIndex = SendDlgItemMessage(hWnd, IDC_SESSIONLIST, LB_GETCOUNT,
  503.                                    (WPARAM) 0, (LPARAM) 0);
  504.  
  505.             EnableDlgButton(hWnd, IDC_JOINSESSIONBUTTON, (iIndex > 0) ? TRUE : FALSE);
  506.  
  507.             switch (hr)
  508.             {
  509.             case DP_OK:
  510.                 SetDlgItemText(hWnd, IDC_SESSIONSTATUSEDIT, "Searching for sessions...");
  511.                 break;
  512.  
  513.             case DPERR_CONNECTING:
  514.                 SetDlgItemText(hWnd, IDC_SESSIONSTATUSEDIT, "Making connection...");
  515.                 break;
  516.  
  517.             case DPERR_NOCONNECTION:
  518.                 SetDlgItemText(hWnd, IDC_SESSIONSTATUSEDIT, "Connection failed");
  519.                 KillTimer(hWnd, idTimer); 
  520.                 idTimer = 0;
  521.                 break;
  522.  
  523.             default:
  524.                 SetDlgItemText(hWnd, IDC_SESSIONSTATUSEDIT, "Error making connection");
  525.                 KillTimer(hWnd, idTimer); 
  526.                 idTimer = 0;
  527.                 break;
  528.             }
  529.             break;
  530.         
  531.         case WM_COMMAND:
  532.             switch(LOWORD(wParam))
  533.             {
  534.                 case IDC_JOINSESSIONBUTTON:
  535.                     // Return guid of session to join
  536.                     hr = GetSessionInstanceGuid(hWnd, &lpContext->guidInstance);
  537.                     if SUCCEEDED(hr)
  538.                         EndDialog(hWnd, TRUE);
  539.                     break;
  540.  
  541.                 case IDCANCEL:
  542.                     // Return failure
  543.                     EndDialog(hWnd, FALSE);
  544.                     break;
  545.             }
  546.  
  547.             break;
  548.     }
  549.  
  550.     // Allow for default processing
  551.     return FALSE;
  552. }
  553.  
  554. // ---------------------------------------------------------------------------
  555. // UpdateAddressInfo
  556. // ---------------------------------------------------------------------------
  557. // Description:             Updates address information elements in dialog.
  558. //                            Calls EnumAddressTypes() to determine what address
  559. //                            information should be displayed and arranges dialog
  560. //                            to display and collect the needed information.
  561. // Arguments:
  562. //  HWND                    [in] window handle
  563. //  LPDIRECTPLAYLOBBY2A        [in] DirectPlay Lobby interface to use
  564. // Returns:
  565. //  HRESULT                    DP_OK if it succeedes, otherwise the error
  566. HRESULT UpdateAddressInfo(HWND hWnd, LPDIRECTPLAYLOBBY2A lpDPlayLobby2A)
  567. {
  568.     GUID            guidServiceProvider;
  569.     HRESULT            hr;
  570.  
  571.     // clear and hide address dialog items
  572.     ShowWindow(GetDlgItem(hWnd, IDC_PHONEEDIT), SW_HIDE);
  573.     ShowWindow(GetDlgItem(hWnd, IDC_PHONEEDITLABEL), SW_HIDE);
  574.  
  575.     ShowWindow(GetDlgItem(hWnd, IDC_MODEMCOMBO), SW_HIDE);
  576.     ShowWindow(GetDlgItem(hWnd, IDC_MODEMCOMBOLABEL), SW_HIDE);
  577.  
  578.     ShowWindow(GetDlgItem(hWnd, IDC_TCPEDIT), SW_HIDE);
  579.     ShowWindow(GetDlgItem(hWnd, IDC_TCPEDITLABEL), SW_HIDE);
  580.  
  581.     ShowWindow(GetDlgItem(hWnd, IDC_IPXLABEL), SW_HIDE);
  582.  
  583.     ShowWindow(GetDlgItem(hWnd, IDC_SERVICEPROVIDERLABEL), SW_HIDE);
  584.  
  585.     // get currently selected service provider
  586.     hr = GetServiceProviderGuid(hWnd, &guidServiceProvider);
  587.     if FAILED(hr)
  588.         goto FAILURE;
  589.  
  590.     // modem service provider
  591.     if (IsEqualGUID(&guidServiceProvider, &DPSPGUID_MODEM))
  592.     {
  593.         // show edit control to collect phone number
  594.         ShowWindow(GetDlgItem(hWnd, IDC_PHONEEDIT), SW_SHOW);
  595.         ShowWindow(GetDlgItem(hWnd, IDC_PHONEEDITLABEL), SW_SHOW);
  596.  
  597.         // show combo box to collect modem
  598.         ShowWindow(GetDlgItem(hWnd, IDC_MODEMCOMBO), SW_SHOW);
  599.         ShowWindow(GetDlgItem(hWnd, IDC_MODEMCOMBOLABEL), SW_SHOW);
  600.     }
  601.  
  602.     // internet TCP/IP service provider
  603.     else if (IsEqualGUID(&guidServiceProvider, &DPSPGUID_TCPIP))
  604.     {
  605.         // show edit control to collect IP address
  606.         ShowWindow(GetDlgItem(hWnd, IDC_TCPEDIT), SW_SHOW);
  607.         ShowWindow(GetDlgItem(hWnd, IDC_TCPEDITLABEL), SW_SHOW);
  608.     }
  609.  
  610.     // IPX service provider
  611.     else if (IsEqualGUID(&guidServiceProvider, &DPSPGUID_IPX))
  612.     {
  613.         // no address info is needed, so just display a string
  614.         ShowWindow(GetDlgItem(hWnd, IDC_IPXLABEL), SW_SHOW);
  615.     }
  616.  
  617.     // anything else, let service provider collect settings, if any
  618.     else
  619.     {
  620.         ShowWindow(GetDlgItem(hWnd, IDC_SERVICEPROVIDERLABEL), SW_SHOW);
  621.     }
  622.  
  623. FAILURE:
  624.     return (hr);
  625. }
  626.  
  627. HRESULT    CreateServiceProviderAddress(HWND hWnd, LPDIRECTPLAYLOBBY2A lpDPlayLobby,
  628.                                      LPVOID *lplpAddress, LPDWORD lpdwAddressSize)
  629. {
  630.     DPCOMPOUNDADDRESSELEMENT    addressElements[3];
  631.     CHAR                        szIPAddressString[NAMEMAX];
  632.     CHAR                        szPhoneNumberString[NAMEMAX];
  633.     CHAR                        szModemString[NAMEMAX];
  634.     LPVOID                        lpAddress = NULL;
  635.     DWORD                        dwAddressSize = 0;
  636.     DWORD                        dwElementCount;
  637.     GUID                        guidServiceProvider;
  638.     HRESULT                        hr;
  639.  
  640.     // get currently selected service provider
  641.     hr = GetServiceProviderGuid(hWnd, &guidServiceProvider);
  642.     if FAILED(hr)
  643.         goto FAILURE;
  644.  
  645.     dwElementCount = 0;
  646.  
  647.     if (IsEqualGUID(&guidServiceProvider, &DPSPGUID_MODEM))
  648.     {
  649.         // Modem needs a service provider, a phone number string and a modem string
  650.  
  651.         // service provider
  652.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  653.         addressElements[dwElementCount].dwDataSize = sizeof(GUID);
  654.         addressElements[dwElementCount].lpData = (LPVOID) &DPSPGUID_MODEM;
  655.         dwElementCount++;
  656.  
  657.         // add a modem string if available
  658.         lstrcpy(szModemString, "");
  659.         if (GetDlgItemText(hWnd, IDC_MODEMCOMBO, szModemString, NAMEMAX))
  660.         {
  661.             addressElements[dwElementCount].guidDataType = DPAID_Modem;
  662.             addressElements[dwElementCount].dwDataSize = lstrlen(szModemString) + 1;
  663.             addressElements[dwElementCount].lpData = szModemString;
  664.             dwElementCount++;
  665.         }
  666.  
  667.         // add phone number string
  668.         lstrcpy(szPhoneNumberString, "");
  669.         GetDlgItemText(hWnd, IDC_PHONEEDIT, szPhoneNumberString, NAMEMAX);
  670.         addressElements[dwElementCount].guidDataType = DPAID_Phone;
  671.         addressElements[dwElementCount].dwDataSize = lstrlen(szPhoneNumberString) + 1;
  672.         addressElements[dwElementCount].lpData = szPhoneNumberString;
  673.         dwElementCount++;
  674.     }
  675.  
  676.     // internet TCP/IP service provider
  677.     else if (IsEqualGUID(&guidServiceProvider, &DPSPGUID_TCPIP))
  678.     {
  679.         // TCP/IP needs a service provider and an IP address
  680.  
  681.         // service provider
  682.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  683.         addressElements[dwElementCount].dwDataSize = sizeof(GUID);
  684.         addressElements[dwElementCount].lpData = (LPVOID) &DPSPGUID_TCPIP;
  685.         dwElementCount++;
  686.  
  687.         // IP address string
  688.         lstrcpy(szIPAddressString, "");
  689.         GetDlgItemText(hWnd, IDC_TCPEDIT, szIPAddressString, NAMEMAX);
  690.         addressElements[dwElementCount].guidDataType = DPAID_INet;
  691.         addressElements[dwElementCount].dwDataSize = lstrlen(szIPAddressString) + 1;
  692.         addressElements[dwElementCount].lpData = szIPAddressString;
  693.         dwElementCount++;
  694.     }
  695.  
  696.     // IPX service provider
  697.     else if (IsEqualGUID(&guidServiceProvider, &DPSPGUID_IPX))
  698.     {
  699.         // IPX just needs a service provider
  700.  
  701.         // service provider
  702.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  703.         addressElements[dwElementCount].dwDataSize = sizeof(GUID);
  704.         addressElements[dwElementCount].lpData = (LPVOID) &DPSPGUID_IPX;
  705.         dwElementCount++;
  706.     }
  707.  
  708.     // anything else, let service provider collect settings, if any
  709.     else
  710.     {
  711.         // service provider
  712.         addressElements[dwElementCount].guidDataType = DPAID_ServiceProvider;
  713.         addressElements[dwElementCount].dwDataSize = sizeof(GUID);
  714.         addressElements[dwElementCount].lpData = (LPVOID) &guidServiceProvider;
  715.         dwElementCount++;
  716.     }
  717.  
  718.     // see how much room is needed to store this address
  719.     hr = lpDPlayLobby->lpVtbl->CreateCompoundAddress(lpDPlayLobby,
  720.                         addressElements, dwElementCount,
  721.                         NULL, &dwAddressSize);
  722.     if (hr != DPERR_BUFFERTOOSMALL)
  723.         goto FAILURE;
  724.  
  725.     // allocate space
  726.     lpAddress = GlobalAllocPtr(GHND, dwAddressSize);
  727.     if (lpAddress == NULL)
  728.     {
  729.         hr = DPERR_NOMEMORY;
  730.         goto FAILURE;
  731.     }
  732.  
  733.     // create the address
  734.     hr = lpDPlayLobby->lpVtbl->CreateCompoundAddress(lpDPlayLobby,
  735.                         addressElements, dwElementCount,
  736.                         lpAddress, &dwAddressSize);
  737.     if FAILED(hr)
  738.         goto FAILURE;
  739.  
  740.     // return the address info
  741.     *lplpAddress = lpAddress;
  742.     *lpdwAddressSize = dwAddressSize;
  743.  
  744.     return (DP_OK);
  745.  
  746. FAILURE:
  747.     if (lpAddress)
  748.         GlobalFreePtr(lpAddress);
  749.  
  750.     return (hr);
  751. }
  752.  
  753. HRESULT    DoHostOrJoin(HINSTANCE hInstance, HWND hWnd, LPDIRECTPLAYLOBBY2A lpDPlayLobby, BOOL bHost, LPDIRECTPLAY3A *lplpDPlay)
  754. {
  755.     LPDIRECTPLAY3A    lpDPlay = NULL;
  756.     LPVOID            lpAddress = NULL;
  757.     DWORD            dwAddressSize = 0;
  758.     DPSESSIONDESC2    sessionDesc;
  759.     STATUSCONTEXT    statusContext;
  760.     HRESULT            hr;
  761.  
  762.     // bail if we don't have a lobby interface
  763.     if (lpDPlayLobby == NULL)
  764.         return (DPERR_INVALIDOBJECT);
  765.  
  766.     // get service provider address from information in dialog
  767.     hr = CreateServiceProviderAddress(hWnd, lpDPlayLobby, &lpAddress, &dwAddressSize);
  768.     if FAILED(hr)
  769.         goto FAILURE;
  770.  
  771.     // interface already exists, so release it
  772.     if (*lplpDPlay)
  773.     {
  774.         (*lplpDPlay)->lpVtbl->Release(*lplpDPlay);
  775.         *lplpDPlay = NULL;
  776.     }
  777.  
  778.     // create an ANSI DirectPlay3 interface
  779.     hr = CoCreateInstance(&CLSID_DirectPlay, NULL, CLSCTX_INPROC_SERVER, 
  780.                           &IID_IDirectPlay3A, (LPVOID*)&lpDPlay);
  781.     if FAILED(hr)
  782.         goto FAILURE;
  783.  
  784.     // initialize the connection using the address
  785.     hr = lpDPlay->lpVtbl->InitializeConnection(lpDPlay, lpAddress, 0);
  786.     if FAILED(hr)
  787.         goto FAILURE;
  788.  
  789.     if (bHost)
  790.     {
  791.         // host a new session
  792.         ZeroMemory(&sessionDesc, sizeof(DPSESSIONDESC2));
  793.         sessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  794.         sessionDesc.dwFlags = DPSESSION_MIGRATEHOST | DPSESSION_KEEPALIVE;
  795.         sessionDesc.guidApplication = OVERRIDE_GUID;
  796.         sessionDesc.dwMaxPlayers = 0;
  797.         sessionDesc.lpszSessionNameA = "Override";
  798.  
  799.         // open it
  800.         hr = lpDPlay->lpVtbl->Open(lpDPlay, &sessionDesc, DPOPEN_CREATE);
  801.     }
  802.  
  803.     // enumerate the sessions
  804.     else
  805.     {
  806.         // display status dialog and enumerate until we find a session
  807.         statusContext.lpDPlay = lpDPlay;
  808.         statusContext.guidInstance = GUID_NULL;
  809.  
  810.         if (!DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_SESSIONSDIALOG), hWnd, SessionsWndProc, (LPARAM) &statusContext))
  811.         {
  812.             hr = DPERR_USERCANCEL;
  813.             goto FAILURE;
  814.         }
  815.  
  816.         // open the session selected by the use
  817.         ZeroMemory(&sessionDesc, sizeof(DPSESSIONDESC2));
  818.         sessionDesc.dwSize = sizeof(DPSESSIONDESC2);
  819.         sessionDesc.guidApplication = OVERRIDE_GUID;
  820.         sessionDesc.guidInstance = statusContext.guidInstance;
  821.  
  822.         // open it
  823.         hr = lpDPlay->lpVtbl->Open(lpDPlay, &sessionDesc, DPOPEN_JOIN);
  824.     }
  825.  
  826.     if FAILED(hr)
  827.         goto FAILURE;
  828.  
  829.     // return the connected interface
  830.     *lplpDPlay = lpDPlay;
  831.  
  832.     // set to NULL so we don't release it below
  833.     lpDPlay = NULL;
  834.  
  835. FAILURE:
  836.     if (lpDPlay)
  837.     {
  838.         lpDPlay->lpVtbl->Close(lpDPlay);
  839.         lpDPlay->lpVtbl->Release(lpDPlay);
  840.     }
  841.  
  842.     if (lpAddress)
  843.         GlobalFreePtr(lpAddress);
  844.  
  845.     return (hr);
  846. }
  847.  
  848. // ---------------------------------------------------------------------------
  849. // EnumModemAddress
  850. // ---------------------------------------------------------------------------
  851. // Description:             Enumeration callback called by DirectPlayLobby.
  852. //                            Enumerates the DirectPlay address chunks. If the
  853. //                            chunk contains modem strings, add them to the control.
  854. // Arguments:
  855. //  REFGUID                 [in] GUID of the address type
  856. //  DWORD                    [in] size of chunk
  857. //  LPVOID                    [in] pointer to chunk
  858. //  LPVOID                    [in] user-defined context
  859. // Returns:
  860. //  BOOL                    FALSE to stop enumerating after the first callback
  861. BOOL FAR PASCAL EnumModemAddress(REFGUID lpguidDataType, DWORD dwDataSize,
  862.                             LPCVOID lpData, LPVOID lpContext)
  863. {
  864.     HWND    hWnd = (HWND) lpContext;
  865.     LPSTR    lpszStr = (LPSTR) lpData;
  866.  
  867.     // modem
  868.     if (IsEqualGUID(lpguidDataType, &DPAID_Modem))
  869.     {
  870.         // loop over all strings in list
  871.         while (lstrlen(lpszStr))
  872.         {
  873.             // store modem name in combo box
  874.             SendDlgItemMessage(hWnd, IDC_MODEMCOMBO, CB_ADDSTRING, 0, (LPARAM) lpszStr);
  875.  
  876.             // skip to next string
  877.             lpszStr += lstrlen(lpszStr) + 1;
  878.         }
  879.     }
  880.  
  881.     return (TRUE);
  882. }
  883.  
  884. // ---------------------------------------------------------------------------
  885. // FillModemComboBox
  886. // ---------------------------------------------------------------------------
  887. // Description:             Fills combo box with modem names
  888. // Arguments:
  889. //  HWND                    [in]  Window handle.
  890. //  LPDIRECTPLAYLOBBY2A     [in]  DirectPlay Lobby interface to use
  891. //  LPGUID                    [out] GUID of service provider to use
  892. // Returns:
  893. //  HRESULT                    any error
  894. HRESULT FillModemComboBox(HWND hWnd, LPDIRECTPLAYLOBBY2A lpDPlayLobby)
  895. {
  896.     LPDIRECTPLAY        lpDPlay1 = NULL;
  897.     LPDIRECTPLAY3A        lpDPlay3A = NULL;
  898.     LPVOID                lpAddress = NULL;
  899.     DWORD                dwAddressSize = 0;
  900.     GUID                guidServiceProvider = DPSPGUID_MODEM;
  901.     HRESULT                hr;
  902.  
  903.     // get a DirectPlay interface for this service provider
  904.     hr = DirectPlayCreate(&guidServiceProvider, &lpDPlay1, NULL);
  905.     if FAILED(hr)
  906.         goto FAILURE;
  907.  
  908.     // query for an ANSI DirectPlay3 interface
  909.     hr = lpDPlay1->lpVtbl->QueryInterface(lpDPlay1, &IID_IDirectPlay3A, (LPVOID *) &lpDPlay3A);
  910.     if FAILED(hr)
  911.         goto FAILURE;
  912.  
  913.     // get size of player address for player zero
  914.     hr = lpDPlay3A->lpVtbl->GetPlayerAddress(lpDPlay3A, DPID_ALLPLAYERS, NULL, &dwAddressSize);
  915.     if (hr != DPERR_BUFFERTOOSMALL)
  916.         goto FAILURE;
  917.  
  918.     // make room for it
  919.     lpAddress = GlobalAllocPtr(GHND, dwAddressSize);
  920.     if (lpAddress == NULL)
  921.     {
  922.         hr = DPERR_NOMEMORY;
  923.         goto FAILURE;
  924.     }
  925.  
  926.     // get the address
  927.     hr = lpDPlay3A->lpVtbl->GetPlayerAddress(lpDPlay3A, DPID_ALLPLAYERS, lpAddress, &dwAddressSize);
  928.     if FAILED(hr)
  929.         goto FAILURE;
  930.     
  931.     // get modem strings from address and put them in the combo box
  932.     hr = lpDPlayLobby->lpVtbl->EnumAddress(lpDPlayLobby, EnumModemAddress, 
  933.                              lpAddress, dwAddressSize, hWnd);
  934.     if FAILED(hr)
  935.         goto FAILURE;
  936.  
  937.     // select first item in list
  938.     SendDlgItemMessage(hWnd, IDC_MODEMCOMBO, CB_SETCURSEL, (WPARAM) 0, 0);
  939.  
  940. FAILURE:
  941.     if (lpDPlay1)
  942.         lpDPlay1->lpVtbl->Release(lpDPlay1);
  943.     if (lpDPlay3A)
  944.         lpDPlay3A->lpVtbl->Release(lpDPlay3A);
  945.     if (lpAddress)
  946.         GlobalFreePtr(lpAddress);
  947.  
  948.     return (hr);
  949. }
  950.  
  951. BOOL DlgItemIsChecked(HWND hDlg, int nIDDlgItem)
  952. {
  953.     return ((SendDlgItemMessage(hDlg, nIDDlgItem, BM_GETCHECK, (WPARAM) 0, (LPARAM) 0) == BST_CHECKED) ? TRUE : FALSE);
  954. }
  955.  
  956. void EnableDlgButton(HWND hDlg, int nIDDlgItem, BOOL bEnable)
  957. {
  958.     EnableWindow(GetDlgItem(hDlg, nIDDlgItem), bEnable);
  959. }
  960.