⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netconnect.cpp

📁 VC游戏编程基础
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//-----------------------------------------------------------------------------
// File: NetConnect.cpp
//
// Desc: This is a class that given a IDirectPlay8Peer, then DoConnectWizard()
//       will enumerate service providers, enumerate hosts, and allow the
//       user to either join or host a session.  The class uses
//       dialog boxes and GDI for the interactive UI.  Most games will
//       want to change the graphics to use Direct3D or another graphics
//       layer, but this simplistic sample uses dialog boxes.  Feel 
//       free to use this class as a starting point for adding extra 
//       functionality.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#ifndef STRICT
#define STRICT
#endif // !STRICT
#include <windows.h>
#include <basetsd.h>
#include <stdio.h>
#include <mmsystem.h>
#include <dxerr9.h>
#include <dplay8.h>
#include <dpaddr.h>
#include <dplobby8.h>
#include "NetConnect.h"
#include "NetConnectRes.h"
#include "DXUtil.h"

#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
#include <aygshell.h>
#endif // PocketPC



//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
CNetConnectWizard* g_pNCW = NULL;           // Pointer to the net connect wizard




//-----------------------------------------------------------------------------
// Name: CNetConnectWizard
// Desc: Init the class
//-----------------------------------------------------------------------------
CNetConnectWizard::CNetConnectWizard( HINSTANCE hInst, HWND hWndParent, 
                                      LPCTSTR strAppName, GUID* pGuidApp )
{
    g_pNCW              = this;
    m_hInst             = hInst;
    m_hWndParent        = hWndParent;
    m_pDP               = NULL;
    m_pLobbiedApp       = NULL;
    m_bHaveConnectionSettingsFromLobby = FALSE;
    m_hLobbyClient      = NULL;
    m_guidApp           = *pGuidApp;
    m_hDlg              = NULL;
    m_bConnecting       = FALSE;
    m_hConnectAsyncOp   = NULL;
    m_hEnumAsyncOp      = NULL;
    m_bMigrateHost      = FALSE;
    m_bUseDPNSVR        = FALSE;
    m_dwPort            = 0;
    m_eSigningType      = SIGN_NONE;
    m_dwEnumHostExpireInterval = 0;

    ZeroMemory(&m_guidSP, sizeof(GUID));

    // Set the max players unlimited by default.  This can be changed by the app
    // by calling SetMaxPlayers()
    m_dwMaxPlayers   = 0;

    _tcsncpy( m_strAppName, strAppName, MAX_PATH-1 );
    m_strAppName[ MAX_PATH-1 ] = 0; 
    
    _tcsncpy( m_strPreferredProvider, TEXT("DirectPlay8 TCP/IP Service Provider"), MAX_PATH-1 );
    m_strPreferredProvider[ MAX_PATH-1 ] = 0; 

    _tcsncpy( m_strHostname, TEXT(""), MAX_PATH-1 );

    InitializeCriticalSection( &m_csHostEnum );
    m_hConnectCompleteEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    m_hLobbyConnectionEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

    // Setup the m_DPHostEnumHead circular linked list
    ZeroMemory( &m_DPHostEnumHead, sizeof( DPHostEnumInfo ) );
    m_DPHostEnumHead.pNext = &m_DPHostEnumHead;
}




//-----------------------------------------------------------------------------
// Name: ~CNetConnectWizard
// Desc: Cleanup the class
//-----------------------------------------------------------------------------
CNetConnectWizard::~CNetConnectWizard()
{
    DeleteCriticalSection( &m_csHostEnum );
    CloseHandle( m_hConnectCompleteEvent );
    CloseHandle( m_hLobbyConnectionEvent );
}



//-----------------------------------------------------------------------------
// Name: Init
// Desc:
//-----------------------------------------------------------------------------
HRESULT CNetConnectWizard::Init( IDirectPlay8Peer* pDP,
                                 IDirectPlay8LobbiedApplication* pLobbiedApp )
{
    if( NULL == pDP || NULL == pLobbiedApp )
        return E_INVALIDARG;

    m_pDP               = pDP;
    m_pLobbiedApp       = pLobbiedApp;
    m_bHaveConnectionSettingsFromLobby = FALSE;
    m_hLobbyClient      = NULL;

    return S_OK;
}



//-----------------------------------------------------------------------------
// Name: Shutdown
// Desc: Releases the DirectPlay interfaces
//-----------------------------------------------------------------------------
VOID CNetConnectWizard::Shutdown()
{
}




//-----------------------------------------------------------------------------
// Name: DoConnectWizard
// Desc: This is the main external function.  This will launch a series of
//       dialog boxes that enumerate service providers, enumerate hosts,
//       and allow the user to either join or host a session
//-----------------------------------------------------------------------------
HRESULT CNetConnectWizard::DoConnectWizard( BOOL bBackTrack )
{
    if( m_pDP == NULL )
        return E_INVALIDARG;

    int nStep;

    // If the back track flag is true, then the user has already been through
    // the connect process once, and has back tracked out of the main game
    // so start at the last dialog box
    if( bBackTrack )
        nStep = 1;
    else
        nStep = 0;

    // Show the dialog boxes to connect
    for( ;; )
    {
        m_hrDialog = S_OK;

        switch( nStep )
        {
            case 0:
                // Display the multiplayer connect dialog box.
                DialogBox( m_hInst, MAKEINTRESOURCE(IDD_MULTIPLAYER_CONNECT),
                           m_hWndParent, (DLGPROC) StaticConnectionsDlgProc );
                break;

            case 1:
                // Display the multiplayer games dialog box.
                DialogBox( m_hInst, MAKEINTRESOURCE(IDD_MULTIPLAYER_GAMES),
                           m_hWndParent, (DLGPROC) StaticSessionsDlgProc );
                break;
        }

        if( FAILED( m_hrDialog ) ||
            m_hrDialog == NCW_S_QUIT ||
            m_hrDialog == NCW_S_LOBBYCONNECT )
            break;

        if( m_hrDialog == NCW_S_BACKUP )
            nStep--;
        else
            nStep++;

        // If we go beyond the last step in the wizard, then stop
        // and return.
        if( nStep == 2 )
            break;
    }

    // Depending upon a successful m_hrDialog the user has
    // either successfully join or created a game, depending on m_bHostPlayer
    m_pDP = NULL;
    return m_hrDialog;
}




//-----------------------------------------------------------------------------
// Name: StaticConnectionsDlgProc()
// Desc: Static msg handler which passes messages
//-----------------------------------------------------------------------------
INT_PTR CALLBACK CNetConnectWizard::StaticConnectionsDlgProc( HWND hDlg, UINT uMsg,
                                                              WPARAM wParam, LPARAM lParam )
{
    if( g_pNCW )
        return g_pNCW->ConnectionsDlgProc( hDlg, uMsg, wParam, lParam );

    return FALSE; // Message not handled
}




//-----------------------------------------------------------------------------
// Name: ConnectionsDlgProc()
// Desc: Handles messages for the multiplayer connect dialog
//-----------------------------------------------------------------------------
INT_PTR CALLBACK CNetConnectWizard::ConnectionsDlgProc( HWND hDlg, UINT msg,
                                                        WPARAM wParam, LPARAM lParam )
{
    UNREFERENCED_PARAMETER( lParam );
    
    switch( msg )
    {
        case WM_INITDIALOG:
            {
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
                SHINITDLGINFO   shidi;
                memset(&shidi, 0, sizeof(SHINITDLGINFO));
                shidi.dwMask = SHIDIM_FLAGS;
                shidi.dwFlags = SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN;
                shidi.hDlg = hDlg;

                SetForegroundWindow(hDlg);
                SHInitDialog(&shidi);
#endif // WIN32_PLATFORM_PSPC

                SetDlgItemText( hDlg, IDC_PLAYER_NAME_EDIT, m_strLocalPlayerName );

                // Limit the player name size
                SendDlgItemMessage( hDlg, IDC_PLAYER_NAME_EDIT, EM_LIMITTEXT, MAX_PLAYER_NAME-1, 0 );

                // Load and set the icon
                HICON hIcon = LoadIcon( m_hInst, MAKEINTRESOURCE( IDI_MAIN ) );
                SendMessage( hDlg, WM_SETICON, ICON_BIG,   (LPARAM) hIcon );  // Set big icon
                SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon );  // Set small icon

                // Set the window title
                TCHAR strWindowTitle[256];
                wsprintf( strWindowTitle, TEXT("%s - Multiplayer Connect"), m_strAppName );
                SetWindowText( hDlg, strWindowTitle );

                // Fill the list box with the service providers
                if( FAILED( m_hrDialog = ConnectionsDlgFillListBox( hDlg ) ) )
                {
                    DXTRACE_ERR_MSGBOX( TEXT("ConnectionsDlgFillListBox"), m_hrDialog );
                    EndDialog( hDlg, 0 );
                }
            }
            break;

        case WM_COMMAND:
            switch( LOWORD(wParam) )
            {
                case IDC_CONNECTION_LIST:
                    if( HIWORD(wParam) != LBN_DBLCLK )
                        break;
                    // Fall through

                case IDOK:
                    if( FAILED( m_hrDialog = ConnectionsDlgOnOK( hDlg ) ) )
                    {
                        DXTRACE_ERR_MSGBOX( TEXT("ConnectionsDlgOnOK"), m_hrDialog );
                        EndDialog( hDlg, 0 );
                    }

                    if( m_hrDialog == NCW_S_LOBBYCONNECT )
                    {
                        EndDialog( hDlg, 0 );
                    }
                    break;

                case IDCANCEL:
                    m_hrDialog = NCW_S_QUIT;
                    EndDialog( hDlg, 0 );
                    break;

                default:
                    return FALSE; // Message not handled
            }
            break;

        case WM_DESTROY:
            ConnectionsDlgCleanup( hDlg );
            break;

        default:
            return FALSE; // Message not handled
    }

    // Message was handled
    return TRUE;
}




//-----------------------------------------------------------------------------
// Name: ConnectionsDlgFillListBox()
// Desc: Fills the DirectPlay connection listbox with service providers,
//       and also adds a "Wait for Lobby" connection option.
//-----------------------------------------------------------------------------
HRESULT CNetConnectWizard::ConnectionsDlgFillListBox( HWND hDlg )
{
    HRESULT                     hr;
    int                         iLBIndex;
    DWORD                       dwItems     = 0;
    DPN_SERVICE_PROVIDER_INFO*  pdnSPInfo   = NULL;
    DWORD                       dwSize      = 0;
    HWND                        hWndListBox = GetDlgItem( hDlg, IDC_CONNECTION_LIST );
    TCHAR                       strName[MAX_PATH];

    // Enumerate all DirectPlay service providers, and store them in the listbox

    // Get required space for all providers
    hr = m_pDP->EnumServiceProviders( NULL, NULL, pdnSPInfo, &dwSize,
                                      &dwItems, 0 );
    if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL )
    {
        DXTRACE_ERR_MSGBOX( TEXT("EnumServiceProviders"), hr );
        goto LCleanReturn;
    }

    // Allocate required space
    pdnSPInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
    if( NULL == pdnSPInfo )
    {
        hr = E_OUTOFMEMORY;
        DXTRACE_ERR_MSGBOX( TEXT("ConnectionsDlgFillListBox"), hr );
        goto LCleanReturn;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -