📄 sessioninfo.cpp
字号:
//-----------------------------------------------------------------------------
// File: SessionInfo.cpp
//
// Desc: Implemenation for the CSessionInfo utility class. This utility stores
// player, group, and message information gathered from the application's
// DirectPlay message handler, and provides a dialog UI to display the
// data.
//
// In order to use this class, simply create an instance using a
// pointer to the DirectPlay Peer, Client, or Server interface your
// application uses. Add a call to the MessageHandler member function at
// the beginning of your application's message handler, and call
// ShowDialog to launch the UI.
//
// This class supports multiple concurrent modeless dialogs to help with
// debugging an application during runtime.
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#include "sessioninfo.h"
// Global variables
CSessionInfo* g_pSI = NULL; // Global instance pointer
// Custom fonts
#ifdef UNDER_CE
LOGFONT g_lfName = { 20, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT("MS Sans Serif") };
LOGFONT g_lfConnection = { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, TEXT("Courier New") };
#else
LOGFONT g_lfName = { 24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT("MS Sans Serif") };
LOGFONT g_lfConnection = { 14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_MODERN, TEXT("Courier New") };
#endif
//-----------------------------------------------------------------------------
// Name: CSIGroup()
// Desc: Constructor
//-----------------------------------------------------------------------------
CSIGroup::CSIGroup( DPNID dpnid )
{
id = dpnid;
lstrcpy( strName, TEXT("") );
pMembers = new CArrayList( AL_VALUE, sizeof(DPNID) );
}
//-----------------------------------------------------------------------------
// Name: ~CSIGroup()
// Desc: Destructor
//-----------------------------------------------------------------------------
CSIGroup::~CSIGroup()
{
SAFE_DELETE( pMembers );
}
//-----------------------------------------------------------------------------
// Name: CSIPlayer()
// Desc: Constructor
//-----------------------------------------------------------------------------
CSIPlayer::CSIPlayer( DPNID dpnid )
{
id = dpnid;
bIsHost = FALSE;
lstrcpy( strName, TEXT("") );
lstrcpy( strURL, TEXT("") );
}
//-----------------------------------------------------------------------------
// Name: AddMember()
// Desc: Adds the given player ID to the list of member players in this group
//-----------------------------------------------------------------------------
HRESULT CSIGroup::AddMember( DPNID id )
{
// Check to see if this Member is already present
if( IsMember( id ) )
return S_OK;
// Add the new player id
return pMembers->Add( &id );
}
//-----------------------------------------------------------------------------
// Name: RemoveMember
// Desc: Removes the given player ID from the list of member players in this
// group
//-----------------------------------------------------------------------------
HRESULT CSIGroup::RemoveMember( DPNID id )
{
// Find the Member
for( UINT i=0; i < pMembers->Count(); i++ )
{
DPNID* pID = (DPNID*) pMembers->GetPtr( i );
// Member found
if( id == *pID )
{
// Remove the id and return
pMembers->Remove( i );
return S_OK;
}
}
// Not found
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: CSessionInfo()
// Desc: Constructor
//-----------------------------------------------------------------------------
CSessionInfo::CSessionInfo( IDirectPlay8Peer* pPeer )
{
Initialize();
m_eType = PEER;
m_pPeer = pPeer;
m_pPeer->AddRef();
}
//-----------------------------------------------------------------------------
// Name: CSessionInfo()
// Desc: Constructor
//-----------------------------------------------------------------------------
CSessionInfo::CSessionInfo( IDirectPlay8Client* pClient )
{
Initialize();
m_eType = CLIENT;
m_pClient = pClient;
m_pClient->AddRef();
}
//-----------------------------------------------------------------------------
// Name: CSessionInfo()
// Desc: Constructor
//-----------------------------------------------------------------------------
CSessionInfo::CSessionInfo( IDirectPlay8Server* pServer )
{
Initialize();
m_eType = SERVER;
m_pServer = pServer;
m_pServer->AddRef();
}
//-----------------------------------------------------------------------------
// Name: Initialize()
// Desc: Performs common initialization for all connection types
//-----------------------------------------------------------------------------
VOID CSessionInfo::Initialize()
{
g_pSI = this;
m_pPlayers = new CArrayList( AL_REFERENCE );
m_pGroups = new CArrayList( AL_REFERENCE );
m_eType = INVALID;
m_pPeer = NULL;
m_pClient = NULL;
m_pServer = NULL;
m_dpnidLocal = 0;
m_hDlg = NULL;
m_hDlgParent = NULL;
m_hDlgPlayers = NULL;
m_hDlgMessages = NULL;
m_hDlgThread = NULL;
// Load custom fonts and resources
#ifndef UNDER_CE
HMODULE hShellLib = LoadLibraryEx( TEXT("Shell32.dll"), NULL, LOAD_LIBRARY_AS_DATAFILE );
if( hShellLib )
{
m_hPlayerIcon = (HICON) LoadImage( hShellLib, MAKEINTRESOURCE(18),
IMAGE_ICON, 24, 24, LR_LOADTRANSPARENT);
m_hGroupIcon = (HICON) LoadImage( hShellLib, MAKEINTRESOURCE(273),
IMAGE_ICON, 24, 24, LR_LOADTRANSPARENT);
FreeLibrary( hShellLib );
}
#endif // !UNDER_CE
// Create display fonts
m_hNameFont = CreateFontIndirect( &g_lfName );
m_hConnectionFont = CreateFontIndirect( &g_lfConnection );
InitializeCriticalSection( &m_csLock );
}
//-----------------------------------------------------------------------------
// Name: ~CSessionInfo()
// Desc: Destructor
//-----------------------------------------------------------------------------
CSessionInfo::~CSessionInfo()
{
// Cleanup dialog
if( m_hDlg )
SendMessage( m_hDlg, WM_CLOSE, 0, 0 );
SafeDestroyThread( &m_hDlgThread );
// Cleanup interfaces
SAFE_RELEASE( m_pPeer );
SAFE_RELEASE( m_pClient );
SAFE_RELEASE( m_pServer );
for( UINT i=0; i < m_pPlayers->Count(); i++ )
{
CSIPlayer* pPlayer = (CSIPlayer*) m_pPlayers->GetPtr( i );
SAFE_DELETE( pPlayer );
}
for( i=0; i < m_pGroups->Count(); i++ )
{
CSIGroup* pGroup = (CSIGroup*) m_pGroups->GetPtr( i );
SAFE_DELETE( pGroup );
}
SAFE_DELETE( m_pPlayers );
SAFE_DELETE( m_pGroups );
DeleteObject( m_hNameFont );
DeleteObject( m_hConnectionFont );
DeleteCriticalSection( &m_csLock );
}
//-----------------------------------------------------------------------------
// Name: InitializeLocalPlayer()
// Desc: Initialize the local player given the guessed local dpnid.
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::InitializeLocalPlayer( DPNID idLocal )
{
HRESULT hr = S_OK;
DPN_PLAYER_INFO* pInfo = NULL;
#ifdef _DEBUG
if( NULL == idLocal )
return E_INVALIDARG;
#endif // _DEBUG
hr = GetDpPlayerInfo( idLocal, &pInfo );
switch( m_eType )
{
// Peer types can query information for any peer, including
// themselves, so simply check the returned playerinfo structure
// for the local flag
case PEER:
if( SUCCEEDED(hr) )
{
if( pInfo->dwPlayerFlags & DPNPLAYER_LOCAL )
m_dpnidLocal = idLocal;
if( pInfo->dwPlayerFlags & DPNPLAYER_HOST )
m_dpnidHost = idLocal;
}
break;
// Server types can't query for local information. In a typical game,
// the player context would be checked to determine whether the created
// player is the server; to avoid changing the player contexts for
// every application this class is used with, we'll simply take a best
// guess and assume that if the new player isn't a client it must be
// the server.
case SERVER:
if( hr == DPNERR_INVALIDPLAYER )
{
m_dpnidLocal = m_dpnidHost = idLocal;
hr = S_OK;
}
break;
// Client types can simply wait for the server to send their local
// information.
case CLIENT:
break;
}
return hr;
}
//-----------------------------------------------------------------------------
// Name: FindPlayer
// Desc: Search for and return the player based on dpnid
//-----------------------------------------------------------------------------
CSIPlayer* CSessionInfo::FindPlayer( DPNID id )
{
// Find the player
for( UINT i=0; i < m_pPlayers->Count(); i++ )
{
CSIPlayer* pPlayer = (CSIPlayer*)m_pPlayers->GetPtr( i );
// Player found
if( id == pPlayer->id )
return pPlayer;
}
// Not found
return NULL;
}
//-----------------------------------------------------------------------------
// Name: FindGroup
// Desc: Search for and return the group based on dpnid
//-----------------------------------------------------------------------------
CSIGroup* CSessionInfo::FindGroup( DPNID id )
{
// Find the group
for( UINT i=0; i < m_pGroups->Count(); i++ )
{
CSIGroup* pGroup = (CSIGroup*) m_pGroups->GetPtr( i );
// Group found
if( id == pGroup->id )
return pGroup;
}
// Not found
return NULL;
}
//-----------------------------------------------------------------------------
// Name: CreatePlayer()
// Desc: Creates a new player with the given ID and name, and adds the new node
// to the player list
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::CreatePlayer( DPNID id )
{
HRESULT hr;
// Create a new player object
CSIPlayer* pNewPlayer = new CSIPlayer( id );
if( NULL == pNewPlayer )
return E_OUTOFMEMORY;
// Add the new object to the list
hr = m_pPlayers->Add( pNewPlayer );
if( FAILED(hr) )
{
// Release the allocated memory and return the error code
SAFE_DELETE( pNewPlayer );
return hr;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DestroyPlayer()
// Desc: Removes the player with the given ID from the player list
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::DestroyPlayer( DPNID id )
{
// Find the player
for( UINT i=0; i < m_pPlayers->Count(); i++ )
{
CSIPlayer* pPlayer = (CSIPlayer*)m_pPlayers->GetPtr( i );
// Player found
if( id == pPlayer->id )
{
// Zero out the spot and return
m_pPlayers->Remove( i );
SAFE_DELETE( pPlayer );
return S_OK;
}
}
// Not found
return E_FAIL;
}
//-----------------------------------------------------------------------------
// Name: CreateGroup()
// Desc: Creates a group with the given ID and name, and adds the new node to
// the group list
//-----------------------------------------------------------------------------
HRESULT CSessionInfo::CreateGroup( DPNID id )
{
HRESULT hr;
// Create a new group object
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -