The Multiplayer Connect Dialog Box

[Previous] [Next]

In the Multiplayer Connect dialog box (shown in Figure 15-1), the user enters his name and selects a connection type: Internet, modem, or serial. The user can also choose Wait For Lobby Connection and wait for a connection via a lobby.

Although it's not part of the connection initialization process, this dialog box allows the user to enter a player name. This name is stored in the g_strLocalPlayerName global variable. The actual enumeration of connection types happens in the DPConnect_ConnectionsDlgFillListBox routine, which has the following definition:

 //------------------------------------------------------------------- // Name: DPConnect_ConnectionsDlgFillListBox // Desc: Fills the DirectPlay connection list box and adds //       a Wait For Lobby Connection option //------------------------------------------------------------------- HRESULT DPConnect_ConnectionsDlgFillListBox( HWND hDlg ) {     HRESULT       hr;     HWND          hWndListBox = GetDlgItem( hDlg,                                             IDC_CONNECTION_LIST );     LPDIRECTPLAY4 pDP = NULL;     int           nIndex;     // Create an IDirectPlay object.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay, NULL,                                        CLSCTX_ALL,                                         IID_IDirectPlay4A,                                        (VOID**)&pDP)))     {         if( hr == E_NOINTERFACE )         {             MessageBox( NULL,               TEXT("This application requires DirectPlay 6 or later. "                    "The sample will now quit."),               TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR );         }         return hr;     }      // Enumerate all DirectPlay connections, and store them in the      // list box.     if( FAILED( hr = pDP->EnumConnections( &g_AppGUID,                              DPConnect_EnumConnectionsCallback,                             hWndListBox, 0 ) ) )     {         SAFE_RELEASE( pDP );         return hr;     }     SAFE_RELEASE( pDP );          // Add Wait For Lobby Connection selection to the list box.     SendMessage( hWndListBox, LB_ADDSTRING, 0,                   (LPARAM)"Wait for Lobby Connection" );     SetFocus( hWndListBox );     nIndex = SendMessage( hWndListBox, LB_FINDSTRINGEXACT,                           (WPARAM)-1,                            (LPARAM)g_strPreferredProvider );     if( nIndex != LB_ERR )          SendMessage( hWndListBox, LB_SETCURSEL, nIndex, 0 );     else         SendMessage( hWndListBox, LB_SETCURSEL, 0, 0 ); } 

This routine fills the DirectPlay connection list box with all the possible connection options. To do so, it calls CoCreateInstance to create a IDirectPlay object, requesting the IID_IDirectPlay4A interface (the newest DirectPlay interface). CoCreateInstance creates an instance of the class defined in the clsid parameter, requesting the interface specified in the iid parameter using the execution contents defined in the grfContext parameter.

Once it has created the interface, DPConnect_ConnectionsDlgFillListBox calls the IDirectPlay4::EnumConnections method with the DPConnect_EnumConnectionsCallback callback function. Here's the declaration for EnumConnections:

 HRESULT EnumConnections(     LPCGUID lpguidApplication,     LPDPENUMCONNECTIONSCALLBACK lpEnumCallback,     LPVOID lpContext,     DWORD dwFlags ); 

ParameterDescription
lpguidApplication Pointer to an application's globally unique identifier (GUID). Only service providers and lobby providers that this application can use will be returned. If this parameter is set to a NULL pointer, a list of all the connections is enumerated regardless of the application GUID.
lpEnumCallback Pointer to a user-supplied EnumConnectionsCallback function that will be called for each available connection.
lpContext Pointer to a user-defined context that is passed to the callback function.
dwFlags Flags that specify the type of connections to be enumerated. The default (0) will enumerate DirectPlay service providers only. Here are two possible values for this parameter:

DPCONNECTION_DIRECTPLAY Enumerates DirectPlay service providers to communicate in an application session

DPCONNECTION_DIRECTPLAYLOBBY Enumerates DirectPlay lobby providers to communicate with a lobby server

The routine then adds the Wait For Lobby Connection option to the list box using the SendMessage function. Then it tries to find an entry in the list box that exactly matches the value in the g_strPreferredProvider global variable. (This value is the preferred provider you've stored in this variable.) If this entry appears in the list box, the code selects it. Otherwise, it selects the first entry.

The DPConnect_EnumConnectionsCallback function used to enumerate the DirectPlay connections follows.

 //------------------------------------------------------------------- // Name: DPConnect_EnumConnectionsCallback // Desc: Enumerates through all DirectPlay connection types  //       and stores them in the list box //------------------------------------------------------------------- BOOL FAR PASCAL DPConnect_EnumConnectionsCallback( LPCGUID   pguidSP,                                             VOID*     pConnection,                                             DWORD  dwConnectionSize,                                             LPCDPNAME pName,                                             DWORD     dwFlags,                                             VOID*     pvContext ) {     HRESULT       hr;     LPDIRECTPLAY4 pDP = NULL;     VOID*         pConnectionBuffer = NULL;     HWND          hWndListBox = (HWND)pvContext;     LRESULT       iIndex;     // Create an IDirectPlay object.     if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay, NULL,                                        CLSCTX_ALL,                                         IID_IDirectPlay4A,                                        (VOID**)&pDP )))         return FALSE; // Error; stop enumerating          // Test whether the connection is available by attempting to      // initialize it.     if( FAILED( hr = pDP->InitializeConnection( pConnection, 0 ) ) )     {         SAFE_RELEASE( pDP );         return TRUE; // Unavailable connection; keep enumerating.     }     // Don't need the IDirectPlay interface anymore, so release it.     SAFE_RELEASE( pDP );           // Found a good connection, so put it in the list box.     iIndex = SendMessage( hWndListBox, LB_ADDSTRING, 0,                            (LPARAM)pName->lpszShortNameA );     if( iIndex == CB_ERR )         return FALSE; // Error; stop enumerating     pConnectionBuffer = new BYTE[ dwConnectionSize ];     if( pConnectionBuffer == NULL )         return FALSE; // Error; stop enumerating     // Store pointer to GUID in list box.     memcpy( pConnectionBuffer, pConnection, dwConnectionSize );     SendMessage( hWndListBox, LB_SETITEMDATA, iIndex,                   (LPARAM)pConnectionBuffer );     return TRUE; // Keep enumerating } 

This enumeration callback is similar to the other enumeration callbacks you've seen throughout this book. For each connection type, the function creates a temporary IDirectPlay4A interface and then calls IDirectPlay4::InitializeConnection using the connection data passed to the callback function. If this fails, the connection type might not be available for some reason, so it won't be added to the dialog box's list of connection types. Here's the declaration for the IDirectPlay4::InitializeConnection routine:

 HRESULT InitializeConnection (     LPVOID lpConnection     DWORD dwFlags ); 

ParameterDescription
lpConnection Pointer to a buffer that contains all the information about the connection to be initialized as a DirectPlay address
dwFlags Not used; must be 0

You're now done with the IDirectPlay4 interface, so you can release it using the SAFE_RELEASE macro, shown here:

 #define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } } 



Inside Direct3D
Inside Direct3D (Dv-Mps Inside)
ISBN: 0735606137
EAN: 2147483647
Year: 1999
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net