📄 netclient.cpp
字号:
DXTRACE_ERR_MSGBOX( TEXT("SessionsDlgJoinGame"), hr );
MessageBox( hDlg, TEXT("Unable to join game."),
TEXT("DirectPlay Sample"),
MB_OK | MB_ICONERROR );
}
break;
case IDCANCEL: // The close button was press
m_hrDialog = NCW_S_QUIT;
EndDialog( hDlg, 0 );
break;
default:
return FALSE; // Message not handled
}
break;
case WM_DESTROY:
{
KillTimer( hDlg, 1 );
// Cancel the enum hosts search
// if the enumeration is going on
if( m_bSearchingForSessions && m_hEnumAsyncOp )
{
m_pDPClient->CancelAsyncOperation( m_hEnumAsyncOp, 0 );
m_bSearchingForSessions = FALSE;
}
break;
}
default:
return FALSE; // Message not handled
}
// Message was handled
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: SessionsDlgInitListbox()
// Desc: Initializes the listbox
//-----------------------------------------------------------------------------
VOID CNetClientWizard::SessionsDlgInitListbox( HWND hDlg )
{
HWND hWndListBox = GetDlgItem( hDlg, IDC_GAMES_LIST );
// Clear the contents from the list box, and
// display "Looking for games" text in listbox
SendMessage( hWndListBox, LB_RESETCONTENT, 0, 0 );
if( m_bSearchingForSessions )
{
SendMessage( hWndListBox, LB_ADDSTRING, 0,
(LPARAM) TEXT("Looking for games...") );
}
else
{
SendMessage( hWndListBox, LB_ADDSTRING, 0,
(LPARAM) TEXT("Click Start Search to see a list of games."));
}
SendMessage( hWndListBox, LB_SETITEMDATA, 0, NULL );
SendMessage( hWndListBox, LB_SETCURSEL, 0, 0 );
// Disable the join button until sessions are found
EnableWindow( GetDlgItem( hDlg, IDC_JOIN ), FALSE );
// Query for the enum host timeout for this SP
DPN_SP_CAPS dpspCaps;
ZeroMemory( &dpspCaps, sizeof(DPN_SP_CAPS) );
dpspCaps.dwSize = sizeof(DPN_SP_CAPS);
if( SUCCEEDED( m_pDPClient->GetSPCaps( &CLSID_DP8SP_TCPIP, &dpspCaps, 0 ) ) )
{
// Set the host expire time to around 3 times
// length of the dwDefaultEnumRetryInterval
m_dwEnumHostExpireInterval = dpspCaps.dwDefaultEnumRetryInterval * 3;
}
}
//-----------------------------------------------------------------------------
// Name: SessionsDlgEnumHosts()
// Desc: Enumerates the DirectPlay sessions, and displays them in the listbox
//-----------------------------------------------------------------------------
HRESULT CNetClientWizard::SessionsDlgEnumHosts( HWND hDlg )
{
HRESULT hr;
m_bEnumListChanged = TRUE;
DPN_APPLICATION_DESC dpnAppDesc;
IDirectPlay8Address* pDP8AddressHost = NULL;
IDirectPlay8Address* pDP8AddressLocal = NULL;
WCHAR* wszHostName = NULL;
// Create the local device address object
if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,
CLSCTX_ALL, IID_IDirectPlay8Address,
(LPVOID*) &pDP8AddressLocal ) ) )
{
DXTRACE_ERR_MSGBOX( TEXT("CoCreateInstance"), hr );
goto LCleanup;
}
// Set IP service provider
if( FAILED( hr = pDP8AddressLocal->SetSP( &CLSID_DP8SP_TCPIP ) ) )
{
DXTRACE_ERR_MSGBOX( TEXT("SetSP"), hr );
goto LCleanup;
}
// Create the remote host address object
if( FAILED( hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,
CLSCTX_ALL, IID_IDirectPlay8Address,
(LPVOID*) &pDP8AddressHost ) ) )
{
DXTRACE_ERR_MSGBOX( TEXT("CoCreateInstance"), hr );
goto LCleanup;
}
// Set IP service provider
if( FAILED( hr = pDP8AddressHost->SetSP( &CLSID_DP8SP_TCPIP ) ) )
{
DXTRACE_ERR_MSGBOX( TEXT("SetSP"), hr );
goto LCleanup;
}
// Set the remote host name (if provided)
TCHAR strIPAddress[MAX_PATH];
GetDlgItemText( hDlg, IDC_IP_ADDRESS, strIPAddress, MAX_PATH );
if( strIPAddress != NULL && strIPAddress[0] != 0 )
{
wszHostName = new WCHAR[_tcslen(strIPAddress)+1];
if( NULL == wszHostName )
{
hr = E_OUTOFMEMORY;
DXTRACE_ERR_MSGBOX( TEXT("SessionsDlgEnumHosts"), hr );
goto LCleanup;
}
DXUtil_ConvertGenericStringToWideCch( wszHostName, strIPAddress, (int)_tcslen(strIPAddress)+1 );
hr = pDP8AddressHost->AddComponent( DPNA_KEY_HOSTNAME, wszHostName,
(DWORD) (wcslen(wszHostName)+1)*sizeof(WCHAR),
DPNA_DATATYPE_STRING );
if( FAILED(hr) )
{
DXTRACE_ERR_MSGBOX( TEXT("AddComponent"), hr );
goto LCleanup;
}
}
TCHAR strPort[40];
GetDlgItemText( hDlg, IDC_REMOTE_PORT, strPort, 40 );
strPort[39] = 0;
m_dwPort = _ttoi( strPort );
// If a port was specified in the IP string, then add it.
// Games will typically hard code the port so the user need not know it
if( m_dwPort != 0 )
{
hr = pDP8AddressHost->AddComponent( DPNA_KEY_PORT,
&m_dwPort, sizeof(m_dwPort),
DPNA_DATATYPE_DWORD );
if( FAILED(hr) )
{
DXTRACE_ERR_MSGBOX( TEXT("AddComponent"), hr );
goto LCleanup;
}
}
ZeroMemory( &dpnAppDesc, sizeof( DPN_APPLICATION_DESC ) );
dpnAppDesc.dwSize = sizeof( DPN_APPLICATION_DESC );
dpnAppDesc.guidApplication = m_guidApp;
// Enumerate all StressMazeApp hosts running on IP service providers
hr = m_pDPClient->EnumHosts( &dpnAppDesc, pDP8AddressHost,
pDP8AddressLocal, NULL,
0, INFINITE, 0, INFINITE, NULL,
&m_hEnumAsyncOp, 0 );
if( FAILED(hr) )
{
if( hr != DPNERR_INVALIDDEVICEADDRESS &&
hr != DPNERR_ADDRESSING ) // This will be returned if the ip address is is invalid.
DXTRACE_ERR_MSGBOX( TEXT("EnumHosts"), hr );
goto LCleanup;
}
LCleanup:
SAFE_RELEASE( pDP8AddressHost);
SAFE_RELEASE( pDP8AddressLocal );
SAFE_DELETE_ARRAY( wszHostName );
if( hr == DPNERR_PENDING )
hr = DPN_OK;
return hr;
}
//-----------------------------------------------------------------------------
// Name: SessionsDlgNoteEnumResponse()
// Desc: Stores them in the linked list, m_DPHostEnumHead. This is
// called from the DirectPlay message handler so it could be
// called simultaneously from multiple threads.
//-----------------------------------------------------------------------------
HRESULT CNetClientWizard::SessionsDlgNoteEnumResponse( PDPNMSG_ENUM_HOSTS_RESPONSE pEnumHostsResponseMsg )
{
HRESULT hr = S_OK;
BOOL bFound;
// This function is called from the DirectPlay message handler so it could be
// called simultaneously from multiple threads, so enter a critical section
// to assure that it we don't get race conditions. Locking the entire
// function is crude, and could be more optimal but is effective for this
// simple sample
EnterCriticalSection( &m_csHostEnum );
DPHostEnumInfo* pDPHostEnum = m_DPHostEnumHead.pNext;
DPHostEnumInfo* pDPHostEnumNext = NULL;
const DPN_APPLICATION_DESC* pResponseMsgAppDesc =
pEnumHostsResponseMsg->pApplicationDescription;
// Look for a matching session instance GUID.
bFound = FALSE;
while ( pDPHostEnum != &m_DPHostEnumHead )
{
if( pResponseMsgAppDesc->guidInstance == pDPHostEnum->pAppDesc->guidInstance )
{
bFound = TRUE;
break;
}
pDPHostEnumNext = pDPHostEnum;
pDPHostEnum = pDPHostEnum->pNext;
}
if( !bFound )
{
m_bEnumListChanged = TRUE;
// If there's no match, then look for invalid session and use it
pDPHostEnum = m_DPHostEnumHead.pNext;
while ( pDPHostEnum != &m_DPHostEnumHead )
{
if( !pDPHostEnum->bValid )
break;
pDPHostEnum = pDPHostEnum->pNext;
}
// If no invalid sessions are found then make a new one
if( pDPHostEnum == &m_DPHostEnumHead )
{
// Found a new session, so create a new node
pDPHostEnum = new DPHostEnumInfo;
if( NULL == pDPHostEnum )
{
hr = E_OUTOFMEMORY;
DXTRACE_ERR_MSGBOX( TEXT("SessionsDlgNoteEnumResponse"), hr );
goto LCleanup;
}
ZeroMemory( pDPHostEnum, sizeof(DPHostEnumInfo) );
// Add pDPHostEnum to the circular linked list, m_DPHostEnumHead
pDPHostEnum->pNext = m_DPHostEnumHead.pNext;
m_DPHostEnumHead.pNext = pDPHostEnum;
}
}
// Update the pDPHostEnum with new information
TCHAR strName[MAX_PATH];
if( pResponseMsgAppDesc->pwszSessionName )
{
DXUtil_ConvertWideStringToGenericCch( strName, pResponseMsgAppDesc->pwszSessionName, MAX_PATH );
}
// Cleanup any old enum
if( pDPHostEnum->pAppDesc )
{
SAFE_DELETE_ARRAY( pDPHostEnum->pAppDesc->pwszSessionName );
SAFE_DELETE( pDPHostEnum->pAppDesc );
}
SAFE_RELEASE( pDPHostEnum->pHostAddr );
SAFE_RELEASE( pDPHostEnum->pDeviceAddr );
//
// Duplicate pEnumHostsResponseMsg->pAddressSender in pDPHostEnum->pHostAddr.
// Duplicate pEnumHostsResponseMsg->pAddressDevice in pDPHostEnum->pDeviceAddr.
//
if( FAILED( hr = pEnumHostsResponseMsg->pAddressSender->Duplicate( &pDPHostEnum->pHostAddr ) ) )
{
DXTRACE_ERR_MSGBOX( TEXT("Duplicate"), hr );
goto LCleanup;
}
if( FAILED( hr = pEnumHostsResponseMsg->pAddressDevice->Duplicate( &pDPHostEnum->pDeviceAddr ) ) )
{
DXTRACE_ERR_MSGBOX( TEXT("Duplicate"), hr );
goto LCleanup;
}
// Deep copy the DPN_APPLICATION_DESC from
pDPHostEnum->pAppDesc = new DPN_APPLICATION_DESC;
if( NULL == pDPHostEnum->pAppDesc )
{
hr = E_OUTOFMEMORY;
DXTRACE_ERR_MSGBOX( TEXT("SessionsDlgNoteEnumResponse"), hr );
goto LCleanup;
}
ZeroMemory( pDPHostEnum->pAppDesc, sizeof(DPN_APPLICATION_DESC) );
memcpy( pDPHostEnum->pAppDesc, pResponseMsgAppDesc, sizeof(DPN_APPLICATION_DESC) );
if( pResponseMsgAppDesc->pwszSessionName )
{
WCHAR* wstr = new WCHAR[ wcslen(pResponseMsgAppDesc->pwszSessionName)+1 ];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -