📄 netconnect.cpp
字号:
//-----------------------------------------------------------------------------
// 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 + -