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

📄 netclient.cpp

📁 VC游戏编程基础
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//-----------------------------------------------------------------------------
// File: NetClient.cpp
//
// Desc: This is a class that given a IDirectPlay8Client upon DoConnectWizard()
//       will enumerate hosts, and allows the user to join 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 "NetClient.h"
#include "NetClientRes.h"
#include "DXUtil.h"

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




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




//-----------------------------------------------------------------------------
// Name: CNetClientWizard
// Desc: Init the class
//-----------------------------------------------------------------------------
CNetClientWizard::CNetClientWizard( HINSTANCE hInst, LPCTSTR strAppName,
                                      GUID* pGuidApp )
{
    g_pNCW    = this;
    m_hInst   = hInst;
    m_guidApp = *pGuidApp;
    m_dwPort  = 0;
    
    if( NULL == strAppName )
        strAppName = TEXT("DirectPlay App");

    _tcsncpy( m_strAppName, strAppName, MAX_PATH-1 );
    m_strAppName[ MAX_PATH-1 ] = 0;
   
    m_dwEnumHostExpireInterval          = 0;
    m_hConnectCompleteEvent             = NULL;
    m_hrConnectComplete                 = 0;
    m_bConnecting                       = FALSE;
    m_bEnumListChanged                  = FALSE;
    m_bSearchingForSessions             = FALSE;
    m_hEnumAsyncOp                      = NULL;
    m_hConnectAsyncOp                   = NULL;
    m_pDPClient                         = NULL;
    m_pLobbiedApp                       = NULL;
    m_bHaveConnectionSettingsFromLobby  = FALSE;
    m_hLobbyClient                      = NULL;
    m_hDlg                              = NULL;

    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: ~CNetClientWizard
// Desc: Cleanup the class
//-----------------------------------------------------------------------------
CNetClientWizard::~CNetClientWizard()
{
    DeleteCriticalSection( &m_csHostEnum );
    CloseHandle( m_hConnectCompleteEvent );
    CloseHandle( m_hLobbyConnectionEvent );
}



//-----------------------------------------------------------------------------
// Name: Init
// Desc: Initialize member variables
//-----------------------------------------------------------------------------
HRESULT CNetClientWizard::Init( IDirectPlay8Client* pDPClient,
                                IDirectPlay8LobbiedApplication* pLobbiedApp )
{
    if( NULL == pDPClient || NULL == pLobbiedApp )
        return E_INVALIDARG;

    m_pDPClient         = pDPClient;
    m_pLobbiedApp       = pLobbiedApp;
    m_bHaveConnectionSettingsFromLobby = FALSE;
    m_hLobbyClient      = NULL;

    return S_OK;
}



//-----------------------------------------------------------------------------
// Name: DoConnectWizard
// Desc: Show the connection wizard UI
//-----------------------------------------------------------------------------
HRESULT CNetClientWizard::DoConnectWizard()
{
    m_hrDialog = S_OK;

    // Display the multiplayer games dialog box.
    DialogBox( m_hInst, MAKEINTRESOURCE(IDD_CLIENT_CONNECT), NULL, 
               (DLGPROC) StaticSessionsDlgProc );

    return m_hrDialog;
}




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

    return FALSE; // Message not handled
}




//-----------------------------------------------------------------------------
// Name: SessionsDlgProc()
// Desc: Handles messages for the multiplayer games dialog
//-----------------------------------------------------------------------------
INT_PTR CALLBACK CNetClientWizard::SessionsDlgProc( HWND hDlg, UINT msg,
                                                    WPARAM wParam, LPARAM lParam )
{
    HRESULT hr;

    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

				// 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

                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 );

                // Set the window title
                TCHAR strWindowTitle[256];

                _sntprintf( strWindowTitle, 255, TEXT("%s - Multiplayer Games"), m_strAppName );
                strWindowTitle[255] = 0;

                SetWindowText( hDlg, strWindowTitle );

                // Set the default port
                if( m_dwPort != 0 )
                {
                    TCHAR strPort[40];
                    _itot( m_dwPort, strPort, 10 );
                    SetDlgItemText( hDlg, IDC_REMOTE_PORT, strPort );
                }

                // Init the search portion of the dialog
                m_bSearchingForSessions = FALSE;
                SetDlgItemText( hDlg, IDC_SEARCH_CHECK, TEXT("Start Search") );
                SessionsDlgInitListbox( hDlg );
            }
            break;

        case WM_TIMER:
            // Upon this timer message, then refresh the list of hosts
            // by expiring old hosts, and displaying the list in the
            // dialog box
            if( wParam == TIMERID_DISPLAY_HOSTS )
            {
                // Don't refresh if we are not enumerating hosts
                if( !m_bSearchingForSessions )
                    break;

                // Expire all of the hosts that haven't
                // refreshed in a certain period of time
                SessionsDlgExpireOldHostEnums();

                // Display the list of hosts in the dialog
                if( FAILED( hr = SessionsDlgDisplayEnumList( hDlg ) ) )
                {
                    DXTRACE_ERR_MSGBOX( TEXT("SessionsDlgEnumHosts"), hr );
                    MessageBox( hDlg, TEXT("Error enumerating DirectPlay games."),
                                m_strAppName, MB_OK | MB_ICONERROR );

                    m_bSearchingForSessions = FALSE;
                    KillTimer( hDlg, TIMERID_DISPLAY_HOSTS );
                    CheckDlgButton( hDlg, IDC_SEARCH_CHECK, BST_UNCHECKED );
                    SetDlgItemText( hDlg, IDC_SEARCH_CHECK, TEXT("Start Search") );
                    SessionsDlgInitListbox( hDlg );
                }
            }
            else if( wParam == TIMERID_CONNECT_COMPLETE )
            {
                // Check to see if the MessageHandler has set an event to tell us the
                // DPN_MSGID_CONNECT_COMPLETE has been processed.  Now m_hrConnectComplete
                // is valid.
                if( WAIT_OBJECT_0 == WaitForSingleObject( m_hConnectCompleteEvent, 0 ) )
                {
                    m_bConnecting = FALSE;

                    if( FAILED( m_hrConnectComplete ) )
                    {
                        DXTRACE_ERR_MSGBOX( TEXT("DPN_MSGID_CONNECT_COMPLETE"), m_hrConnectComplete );
                        MessageBox( hDlg, TEXT("Unable to join game."),
                                    m_strAppName, MB_OK | MB_ICONERROR );
                    }
                    else
                    {
                        // DirectPlay connect successful, so end dialog
                        m_hrDialog = NCW_S_FORWARD;
                        EndDialog( hDlg, 0 );
                    }
                }
            }

            break;

        case WM_COMMAND:
            switch( LOWORD(wParam) )
            {
                case IDC_SEARCH_CHECK:
                    m_bSearchingForSessions = !m_bSearchingForSessions;

                    if( m_bSearchingForSessions )
                    {
                        SetDlgItemText( hDlg, IDC_SEARCH_CHECK, TEXT("Searching...") );

                        // Start the timer to display the host list every so often
                        SetTimer( hDlg, TIMERID_DISPLAY_HOSTS, DISPLAY_REFRESH_RATE, NULL );

                        // Start the async enumeration
                        if( FAILED( hr = SessionsDlgEnumHosts( hDlg ) ) )
                        {
                            if( hr == DPNERR_ADDRESSING )
                            {
                                // This will be returned if the ip address is invalid
                                // for example something like "asdf" 
                                MessageBox( hDlg, TEXT("IP address not valid. Stopping search"),
                                            m_strAppName, MB_OK );
                            }
                            else
                            {
                                DXTRACE_ERR_MSGBOX( TEXT("SessionsDlgEnumHosts"), hr );
                                MessageBox( hDlg, TEXT("Error enumerating DirectPlay games."),
                                            m_strAppName, MB_OK | MB_ICONERROR );
                            }

                            m_bSearchingForSessions = FALSE;
                            KillTimer( hDlg, TIMERID_DISPLAY_HOSTS );
                            CheckDlgButton( hDlg, IDC_SEARCH_CHECK, BST_UNCHECKED );
                            SetDlgItemText( hDlg, IDC_SEARCH_CHECK, TEXT("Start Search") );
                            SessionsDlgInitListbox( hDlg );
                        }
                    }
                    else
                    {
                        SetDlgItemText( hDlg, IDC_SEARCH_CHECK, TEXT("Start Search") );

                        // Stop the timer, and stop the async enumeration
                        KillTimer( hDlg, TIMERID_DISPLAY_HOSTS );

                        // Until the CancelAsyncOperation returns, it is possible
                        // to still receive host enumerations
                        if( m_hEnumAsyncOp )
                            m_pDPClient->CancelAsyncOperation( m_hEnumAsyncOp, 0 );

                        // Reset the search portion of the dialog
                        SessionsDlgInitListbox( hDlg );
                    }
                    break;

                case IDC_GAMES_LIST:
                    if( HIWORD(wParam) != LBN_DBLCLK )
                        break;
                    // Fall through

                case IDC_JOIN:
                    if( FAILED( hr = SessionsDlgJoinGame( hDlg ) ) )
                    {

⌨️ 快捷键说明

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