HRESULT CClientWizard::Init(HWND hWnd, const PFNDPNMESSAGEHANDLER pfn) { HRESULT hr = S_OK; m_hWnd = hWnd; if(pfn) { if(FAILED(hr = InitDirectPlay(pfn))) { return hr; } } else { if(FAILED(hr = InitDirectPlay(StaticClientMessageHandler))) { return hr; } } // InitializeCriticalSection(&m_critDecomposer); if(FAILED(hr = CreateDeviceAddress())) { MessageBox(NULL, ("DirectPlay Client Device 생성에 실패하였습니다.\n프로그램을 종료합니다."), NULL, MB_OK); return hr; } return hr; }
//----------------------------------------------------------------------------- // Name: WinMain() // Desc: Entry point for the application. Since we use a simple dialog for // user interaction we don't need to pump messages. //----------------------------------------------------------------------------- INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, INT nCmdShow ) { HRESULT hr; HKEY hDPlaySampleRegKey; BOOL bConnectSuccess = FALSE; InitCommonControls(); ZeroMemory( &g_playerHead, sizeof(APP_PLAYER_INFO) ); g_playerHead.pNext = &g_playerHead; g_playerHead.pPrev = &g_playerHead; g_hInst = hInst; InitializeCriticalSection( &g_csPlayerContext ); // Read persistent state information from registry RegCreateKeyEx( HKEY_CURRENT_USER, DPLAY_SAMPLE_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hDPlaySampleRegKey, NULL ); DXUtil_ReadStringRegKey( hDPlaySampleRegKey, TEXT("Player Name"), g_strLocalPlayerName, MAX_PATH, TEXT("TestPlayer") ); // Init COM so we can use CoCreateInstance CoInitializeEx( NULL, COINIT_MULTITHREADED ); // Create helper class g_pNetClientWizard = new CNetClientWizard( hInst, g_strAppName, &g_guidApp ); g_pNetVoice = new CNetVoice( DirectPlayVoiceClientMessageHandler, NULL ); if( FAILED( hr = InitDirectPlay() ) ) { DXTRACE_ERR( TEXT("InitDirectPlay"), hr ); MessageBox( NULL, TEXT("Failed initializing IDirectPlay8Peer. ") TEXT("The sample will now quit."), g_strAppName, MB_OK | MB_ICONERROR ); return FALSE; } // If we were launched from a lobby client, then we may have connection settings // that we can use either host or join a game. If not, then we'll need to prompt // the user to detrimine how to connect. if( g_bWasLobbyLaunched && g_pNetClientWizard->HaveConnectionSettingsFromLobby() ) { // If were lobby launched then the DPL_MSGID_CONNECT has already been // handled, and since the lobby client also sent us connection settings // we can use them to either host or join a DirectPlay session. if( FAILED( hr = g_pNetClientWizard->ConnectUsingLobbySettings() ) ) { DXTRACE_ERR( TEXT("ConnectUsingLobbySettings"), hr ); MessageBox( NULL, TEXT("Failed to connect using lobby settings. ") TEXT("The sample will now quit."), g_strAppName, MB_OK | MB_ICONERROR ); bConnectSuccess = FALSE; } else { // Read information from g_pNetClientWizard _tcscpy( g_strLocalPlayerName, g_pNetClientWizard->GetPlayerName() ); bConnectSuccess = TRUE; } } else { // If not lobby launched, prompt the user about the network // connection and which session they would like to join or // if they want to create a new one. // Setup connection wizard g_pNetClientWizard->SetPlayerName( g_strLocalPlayerName ); // Start a connection wizard. The wizard uses GDI dialog boxes. // More complex games can use this as a starting point and add a // fancier graphics layer such as Direct3D. hr = g_pNetClientWizard->DoConnectWizard(); if( FAILED( hr ) ) { DXTRACE_ERR( TEXT("DoConnectWizard"), hr ); MessageBox( NULL, TEXT("Multiplayer connect failed. ") TEXT("The sample will now quit."), g_strAppName, MB_OK | MB_ICONERROR ); bConnectSuccess = FALSE; } else if( hr == NCW_S_QUIT ) { // The user canceled the Multiplayer connect, so quit bConnectSuccess = FALSE; } else { bConnectSuccess = TRUE; // Read information from g_pNetClientWizard _tcscpy( g_strLocalPlayerName, g_pNetClientWizard->GetPlayerName() ); // Write information to the registry DXUtil_WriteStringRegKey( hDPlaySampleRegKey, TEXT("Player Name"), g_strLocalPlayerName ); } } if( bConnectSuccess ) { // Set default DirectPlayVoice setup options ZeroMemory( &g_dvClientConfig, sizeof(g_dvClientConfig) ); g_dvClientConfig.dwSize = sizeof(g_dvClientConfig); g_dvClientConfig.dwFlags = DVCLIENTCONFIG_AUTOVOICEACTIVATED | DVCLIENTCONFIG_AUTORECORDVOLUME; g_dvClientConfig.lPlaybackVolume = DVPLAYBACKVOLUME_DEFAULT; g_dvClientConfig.dwBufferQuality = DVBUFFERQUALITY_DEFAULT; g_dvClientConfig.dwBufferAggressiveness = DVBUFFERAGGRESSIVENESS_DEFAULT; g_dvClientConfig.dwThreshold = DVTHRESHOLD_UNUSED; g_dvClientConfig.lRecordVolume = DVRECORDVOLUME_LAST; g_dvClientConfig.dwNotifyPeriod = 0; // App is now connected via DirectPlay, so start the game. // For this sample, we just start a simple dialog box game. g_hrDialog = S_OK; DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN_GAME), NULL, (DLGPROC) SampleDlgProc ); if( FAILED( g_hrDialog ) ) { if( g_hrDialog == DPNERR_CONNECTIONLOST ) { MessageBox( NULL, TEXT("The DirectPlay session was lost. ") TEXT("The sample will now quit."), g_strAppName, MB_OK | MB_ICONERROR ); } else { DXTRACE_ERR( TEXT("DialogBox"), g_hrDialog ); MessageBox( NULL, TEXT("An error occured during the game. ") TEXT("The sample will now quit."), g_strAppName, MB_OK | MB_ICONERROR ); } } } // Disconnect from the DirectPlayVoice session, // and destory it if we are the host player. SAFE_DELETE( g_pNetVoice ); // Cleanup DirectPlay and helper classes if( g_pDPClient ) { g_pDPClient->Close( 0 ); SAFE_RELEASE( g_pDPClient ); } if( g_pLobbiedApp ) { g_pLobbiedApp->Close( 0 ); SAFE_RELEASE( g_pLobbiedApp ); } // Don't delete the wizard until we know that // DirectPlay is out of its message handlers. // This will be true after Close() has been called. SAFE_DELETE( g_pNetClientWizard ); RegCloseKey( hDPlaySampleRegKey ); DeleteCriticalSection( &g_csPlayerContext ); CoUninitialize(); return TRUE; }
//----------------------------------------------------------------------------- // Name: WinMain() // Desc: Entry point for the application. Since we use a simple dialog for // user interaction we don't need to pump messages. //----------------------------------------------------------------------------- INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, INT nCmdShow ) { HRESULT hr; HKEY hDPlaySampleRegKey; BOOL bConnectSuccess = FALSE; g_hInst = hInst; InitializeCriticalSection( &g_csPlayerContext ); // Read persistent state information from registry RegCreateKeyEx( HKEY_CURRENT_USER, DPLAY_SAMPLE_KEY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hDPlaySampleRegKey, NULL ); DXUtil_ReadStringRegKey( hDPlaySampleRegKey, TEXT("Player Name"), g_strLocalPlayerName, MAX_PATH, TEXT("TestPlayer") ); DXUtil_ReadStringRegKey( hDPlaySampleRegKey, TEXT("Session Name"), g_strSessionName, MAX_PATH, TEXT("TestGame") ); DXUtil_ReadStringRegKey( hDPlaySampleRegKey, TEXT("Preferred Provider"), g_strPreferredProvider, MAX_PATH, TEXT("DirectPlay8 TCP/IP Service Provider") ); // Init COM so we can use CoCreateInstance CoInitializeEx( NULL, COINIT_MULTITHREADED ); // Create helper class g_pNetConnectWizard = new CNetConnectWizard( hInst, NULL, g_strAppName, &g_guidApp ); g_pNetStage = new CNetStage( hInst, g_strAppName ); if( FAILED( hr = InitDirectPlay() ) ) { DXTRACE_ERR( TEXT("InitDirectPlay"), hr ); MessageBox( NULL, TEXT("Failed initializing IDirectPlay8Peer. ") TEXT("The sample will now quit."), TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR ); return FALSE; } // Check if we were launched from a lobby client if( g_bWasLobbyLaunched && g_pNetConnectWizard->HaveConnectionSettingsFromLobby() ) { // If were lobby launched then DPL_MSGID_CONNECT has already been // handled, so we can just tell the wizard to connect to the lobby // that has sent us a DPL_MSGID_CONNECT msg. if( FAILED( hr = g_pNetConnectWizard->ConnectUsingLobbySettings() ) ) { DXTRACE_ERR( TEXT("ConnectUsingLobbySettings"), hr ); MessageBox( NULL, TEXT("Failed to connect using lobby settings. ") TEXT("The sample will now quit."), TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR ); bConnectSuccess = FALSE; } else { // Read information from g_pNetConnectWizard _tcscpy( g_strLocalPlayerName, g_pNetConnectWizard->GetPlayerName() ); bConnectSuccess = TRUE; } } else { // If not lobby launched, prompt the user about the network // connection and which session they would like to join or // if they want to create a new one. // Setup connection wizard g_pNetConnectWizard->SetMaxPlayers( 10 ); g_pNetConnectWizard->SetPlayerName( g_strLocalPlayerName ); g_pNetConnectWizard->SetSessionName( g_strSessionName ); g_pNetConnectWizard->SetPreferredProvider( g_strPreferredProvider ); int nStep = 0; BOOL bBacktrack = FALSE; BOOL bHostPlayer; // Show the dialog boxes to start a DirectPlay connect, and loop // until the user completes them all successfully or quits. while( TRUE ) { switch( nStep ) { case 0: // The first step is to prompt the users about the network // connection and which session they would like to join or // if they want to create a new one. g_pNetStage->Init( g_pDP ); hr = g_pNetConnectWizard->DoConnectWizard( bBacktrack ); bHostPlayer = g_pNetConnectWizard->IsHostPlayer(); bBacktrack = TRUE; break; case 1: if( !g_bWasLobbyLaunched ) { // The second step is to start a multiplayer stage hr = g_pNetStage->DoStage( g_strLocalPlayerName, bHostPlayer ); } else { // If lobby launched, then skip the stage hr = NS_S_FORWARD; } break; } if( FAILED(hr) ) { DXTRACE_ERR( TEXT("DoConnectWizard"), hr ); MessageBox( NULL, TEXT("Multiplayer connect failed. ") TEXT("The sample will now quit."), TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR ); bConnectSuccess = FALSE; break; } else if( hr == NCW_S_QUIT || hr == NS_S_QUIT ) { // The user canceled the multiplayer connect. // The sample will now quit. bConnectSuccess = FALSE; break; } else if( hr == NCW_S_BACKUP || hr == NS_S_BACKUP ) { // If backing up, then close down and re-create // the DirectPlay interface since we'll need // to connect to a new host. nStep--; hr = InitDirectPlay(); if( FAILED( hr ) ) { DXTRACE_ERR( TEXT("InitDirectPlay"), hr ); MessageBox( NULL, TEXT("Failed initializing IDirectPlay8Peer. ") TEXT("The sample will now quit."), TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR ); return FALSE; } } else { nStep++; } // If we go beyond the last dialog box, then we are done if( nStep == 2 ) { bConnectSuccess = TRUE; // Read information from g_pNetConnectWizard _tcscpy( g_strLocalPlayerName, g_pNetConnectWizard->GetPlayerName() ); _tcscpy( g_strSessionName, g_pNetConnectWizard->GetSessionName() ); _tcscpy( g_strPreferredProvider, g_pNetConnectWizard->GetPreferredProvider() ); // Write information to the registry DXUtil_WriteStringRegKey( hDPlaySampleRegKey, TEXT("Player Name"), g_strLocalPlayerName ); DXUtil_WriteStringRegKey( hDPlaySampleRegKey, TEXT("Session Name"), g_strSessionName ); DXUtil_WriteStringRegKey( hDPlaySampleRegKey, TEXT("Preferred Provider"), g_strPreferredProvider ); break; } } } if( bConnectSuccess ) { // App is now connected via DirectPlay, so start the game. // For this sample, we just start a simple dialog box game. g_hrDialog = S_OK; DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN_GAME), NULL, (DLGPROC) GreetingDlgProc ); if( FAILED( g_hrDialog ) ) { if( g_hrDialog == DPNERR_CONNECTIONLOST ) { MessageBox( NULL, TEXT("The DirectPlay session was lost. ") TEXT("The sample will now quit."), TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR ); } else { DXTRACE_ERR( TEXT("DialogBox"), g_hrDialog ); MessageBox( NULL, TEXT("An error occured during the game. ") TEXT("The sample will now quit."), TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR ); } } } // Cleanup DirectPlay and helper classes g_pNetConnectWizard->Shutdown(); if( g_pDP ) { g_pDP->Close(0); SAFE_RELEASE( g_pDP ); } if( g_pLobbiedApp ) { g_pLobbiedApp->Close( 0 ); SAFE_RELEASE( g_pLobbiedApp ); } // Don't delete the wizard until we know that // DirectPlay is out of its message handlers. // This will be true after Close() has been called. SAFE_DELETE( g_pNetConnectWizard ); SAFE_DELETE( g_pNetStage ); RegCloseKey( hDPlaySampleRegKey ); DeleteCriticalSection( &g_csPlayerContext ); CoUninitialize(); return TRUE; }