home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / DirectSound / PlaySound / playsound.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  11.4 KB  |  361 lines

  1. //----------------------------------------------------------------------------
  2. // File: PlaySound.cpp
  3. //
  4. // Desc: The PlaySound sample shows how to load and play a wave file using
  5. //       a DirectSound buffer.
  6. //
  7. // Copyright (c) 1999-2001 Microsoft Corp. All rights reserved.
  8. //-----------------------------------------------------------------------------
  9. #define STRICT
  10. #include <windows.h>
  11. #include <basetsd.h>
  12. #include <commdlg.h>
  13. #include <mmreg.h>
  14. #include <dxerr8.h>
  15. #include <dsound.h>
  16. #include "resource.h"
  17. #include "DSUtil.h"
  18. #include "DXUtil.h"
  19.  
  20.  
  21.  
  22.  
  23. //-----------------------------------------------------------------------------
  24. // Function-prototypes
  25. //-----------------------------------------------------------------------------
  26. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
  27. VOID    OnInitDialog( HWND hDlg );
  28. VOID    OnOpenSoundFile( HWND hDlg );
  29. HRESULT OnPlaySound( HWND hDlg );
  30. HRESULT PlayBuffer( BOOL bLooped );
  31. VOID    OnTimer( HWND hDlg );
  32. VOID    EnablePlayUI( HWND hDlg, BOOL bEnable );
  33.  
  34.  
  35.  
  36.  
  37. //-----------------------------------------------------------------------------
  38. // Defines, constants, and global variables
  39. //-----------------------------------------------------------------------------
  40. CSoundManager* g_pSoundManager = NULL;
  41. CSound*        g_pSound = NULL;
  42. BOOL           g_bBufferPaused;
  43.  
  44.  
  45.  
  46.  
  47. //-----------------------------------------------------------------------------
  48. // Name: WinMain()
  49. // Desc: Entry point for the application.  Since we use a simple dialog for 
  50. //       user interaction we don't need to pump messages.
  51. //-----------------------------------------------------------------------------
  52. INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, 
  53.                       INT nCmdShow )
  54. {
  55.     // Display the main dialog box.
  56.     DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );
  57.  
  58.     return TRUE;
  59. }
  60.  
  61.  
  62.  
  63.  
  64. //-----------------------------------------------------------------------------
  65. // Name: MainDlgProc()
  66. // Desc: Handles dialog messages
  67. //-----------------------------------------------------------------------------
  68. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  69. {
  70.     HRESULT hr;
  71.  
  72.     switch( msg ) 
  73.     {
  74.         case WM_INITDIALOG:
  75.             OnInitDialog( hDlg );
  76.             break;
  77.  
  78.         case WM_COMMAND:
  79.             switch( LOWORD(wParam) )
  80.             {
  81.                 case IDC_SOUNDFILE:
  82.                     OnOpenSoundFile( hDlg );
  83.                     break;
  84.  
  85.                 case IDCANCEL:
  86.                     EndDialog( hDlg, IDCANCEL );
  87.                     break;
  88.  
  89.                 case IDC_PLAY:
  90.                     // The 'play'/'pause' button was pressed
  91.                     if( FAILED( hr = OnPlaySound( hDlg ) ) )
  92.                     {
  93.                         DXTRACE_ERR( TEXT("OnPlaySound"), hr );
  94.                         MessageBox( hDlg, "Error playing DirectSound buffer. "
  95.                                     "Sample will now exit.", "DirectSound Sample", 
  96.                                     MB_OK | MB_ICONERROR );
  97.                         EndDialog( hDlg, IDABORT );
  98.                     }
  99.                     break;
  100.  
  101.                 case IDC_STOP:
  102.                     if( g_pSound )
  103.                     {
  104.                         g_pSound->Stop();
  105.                         g_pSound->Reset();
  106.                     }
  107.  
  108.                     EnablePlayUI( hDlg, TRUE );
  109.                     break;
  110.  
  111.                 default:
  112.                     return FALSE; // Didn't handle message
  113.             }
  114.             break;
  115.  
  116.         case WM_TIMER:
  117.             OnTimer( hDlg );
  118.             break;
  119.  
  120.         case WM_DESTROY:
  121.             // Cleanup everything
  122.             KillTimer( hDlg, 1 );    
  123.             SAFE_DELETE( g_pSound );
  124.             SAFE_DELETE( g_pSoundManager );
  125.             break; 
  126.  
  127.         default:
  128.             return FALSE; // Didn't handle message
  129.     }
  130.  
  131.     return TRUE; // Handled message
  132. }
  133.  
  134.  
  135.  
  136.  
  137. //-----------------------------------------------------------------------------
  138. // Name: OnInitDialog()
  139. // Desc: Initializes the dialogs (sets up UI controls, etc.)
  140. //-----------------------------------------------------------------------------
  141. VOID OnInitDialog( HWND hDlg )
  142. {
  143.     HRESULT hr;
  144.  
  145.     // Load the icon
  146. #ifdef _WIN64
  147.     HINSTANCE hInst = (HINSTANCE) GetWindowLongPtr( hDlg, GWLP_HINSTANCE );
  148. #else
  149.     HINSTANCE hInst = (HINSTANCE) GetWindowLong( hDlg, GWL_HINSTANCE );
  150. #endif
  151.     HICON hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDR_MAINFRAME ) );
  152.  
  153.     // Set the icon for this dialog.
  154.     SendMessage( hDlg, WM_SETICON, ICON_BIG,   (LPARAM) hIcon );  // Set big icon
  155.     SendMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon );  // Set small icon
  156.  
  157.     // Create a static IDirectSound in the CSound class.  
  158.     // Set coop level to DSSCL_PRIORITY, and set primary buffer 
  159.     // format to stereo, 22kHz and 16-bit output.
  160.     g_pSoundManager = new CSoundManager();
  161.  
  162.     if( FAILED( hr = g_pSoundManager->Initialize( hDlg, DSSCL_PRIORITY, 2, 22050, 16 ) ) )
  163.     {
  164.         DXTRACE_ERR( TEXT("Initialize"), hr );
  165.         MessageBox( hDlg, "Error initializing DirectSound.  Sample will now exit.", 
  166.                             "DirectSound Sample", MB_OK | MB_ICONERROR );
  167.         EndDialog( hDlg, IDABORT );
  168.         return;
  169.     }
  170.  
  171.     g_bBufferPaused = FALSE;
  172.  
  173.     // Create a timer, so we can check for when the soundbuffer is stopped
  174.     SetTimer( hDlg, 0, 250, NULL );
  175.  
  176.     // Set the UI controls
  177.     SetDlgItemText( hDlg, IDC_FILENAME, TEXT("No file loaded.") );
  178. }
  179.  
  180.  
  181.  
  182.  
  183. //-----------------------------------------------------------------------------
  184. // Name: OnOpenSoundFile()
  185. // Desc: Called when the user requests to open a sound file
  186. //-----------------------------------------------------------------------------
  187. VOID OnOpenSoundFile( HWND hDlg ) 
  188. {
  189.     HRESULT hr;
  190.  
  191.     static TCHAR strFileName[MAX_PATH] = TEXT("");
  192.     static TCHAR strPath[MAX_PATH] = TEXT("");
  193.  
  194.     // Setup the OPENFILENAME structure
  195.     OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL,
  196.                          TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL,
  197.                          0, 1, strFileName, MAX_PATH, NULL, 0, strPath,
  198.                          TEXT("Open Sound File"),
  199.                          OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0,
  200.                          TEXT(".wav"), 0, NULL, NULL };
  201.  
  202.     // Get the default media path (something like C:\WINDOWS\MEDIA)
  203.     if( '\0' == strPath[0] )
  204.     {
  205.         GetWindowsDirectory( strPath, MAX_PATH );
  206.         if( strcmp( &strPath[strlen(strPath)], TEXT("\\") ) )
  207.             strcat( strPath, TEXT("\\") );
  208.         strcat( strPath, TEXT("MEDIA") );
  209.     }
  210.  
  211.     if( g_pSound )
  212.     {
  213.         g_pSound->Stop();
  214.         g_pSound->Reset();
  215.     }
  216.  
  217.     // Update the UI controls to show the sound as loading a file
  218.     EnableWindow(  GetDlgItem( hDlg, IDC_PLAY ), FALSE);
  219.     EnableWindow(  GetDlgItem( hDlg, IDC_STOP ), FALSE);
  220.     SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Loading file...") );
  221.  
  222.     // Display the OpenFileName dialog. Then, try to load the specified file
  223.     if( TRUE != GetOpenFileName( &ofn ) )
  224.     {
  225.         SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Load aborted.") );
  226.         return;
  227.     }
  228.  
  229.     SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") );
  230.  
  231.     // Free any previous sound, and make a new one
  232.     SAFE_DELETE( g_pSound );
  233.  
  234.     // Load the wave file into a DirectSound buffer
  235.     if( FAILED( hr = g_pSoundManager->Create( &g_pSound, strFileName, 0, GUID_NULL ) ) )
  236.     {
  237.         // Not a critical failure, so just update the status
  238.         DXTRACE_ERR_NOMSGBOX( TEXT("Create"), hr );
  239.         SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Could not create sound buffer.") );
  240.         return; 
  241.     }
  242.  
  243.     // Update the UI controls to show the sound as the file is loaded
  244.     SetDlgItemText( hDlg, IDC_FILENAME, strFileName );
  245.     EnablePlayUI( hDlg, TRUE );
  246.  
  247.     // Remember the path for next time
  248.     strcpy( strPath, strFileName );
  249.     char* strLastSlash = strrchr( strPath, '\\' );
  250.     strLastSlash[0] = '\0';
  251. }
  252.  
  253.  
  254.  
  255.  
  256. //-----------------------------------------------------------------------------
  257. // Name: OnPlaySound()
  258. // Desc: User hit the "Play" button
  259. //-----------------------------------------------------------------------------
  260. HRESULT OnPlaySound( HWND hDlg ) 
  261. {
  262.     HRESULT hr;
  263.  
  264.     HWND hLoopButton = GetDlgItem( hDlg, IDC_LOOP_CHECK );
  265.     BOOL bLooped = ( SendMessage( hLoopButton, BM_GETSTATE, 0, 0 ) == BST_CHECKED );
  266.  
  267.     if( g_bBufferPaused )
  268.     {
  269.         // Play the buffer since it is currently paused
  270.         DWORD dwFlags = bLooped ? DSBPLAY_LOOPING : 0L;
  271.         if( FAILED( hr = g_pSound->Play( 0, dwFlags ) ) )
  272.             return DXTRACE_ERR( TEXT("Play"), hr );
  273.  
  274.         // Update the UI controls to show the sound as playing
  275.         g_bBufferPaused = FALSE;
  276.         EnablePlayUI( hDlg, FALSE );
  277.     }
  278.     else
  279.     {
  280.         if( g_pSound->IsSoundPlaying() )
  281.         {
  282.             // To pause, just stop the buffer, but don't reset the position
  283.             if( g_pSound )
  284.                 g_pSound->Stop();
  285.  
  286.             g_bBufferPaused = TRUE;
  287.             SetDlgItemText( hDlg, IDC_PLAY, "Play" );
  288.         }
  289.         else
  290.         {
  291.             // The buffer is not playing, so play it again
  292.             DWORD dwFlags = bLooped ? DSBPLAY_LOOPING : 0L;
  293.             if( FAILED( hr = g_pSound->Play( 0, dwFlags ) ) )
  294.                 return DXTRACE_ERR( TEXT("Play"), hr );
  295.  
  296.             // Update the UI controls to show the sound as playing
  297.             g_bBufferPaused = FALSE;
  298.             EnablePlayUI( hDlg, FALSE );
  299.         }
  300.     }
  301.  
  302.     return S_OK;
  303. }
  304.  
  305.  
  306.  
  307.  
  308. //-----------------------------------------------------------------------------
  309. // Name: OnTimer()
  310. // Desc: When we think the sound is playing this periodically checks to see if 
  311. //       the sound has stopped.  If it has then updates the dialog.
  312. //-----------------------------------------------------------------------------
  313. VOID OnTimer( HWND hDlg ) 
  314. {
  315.     if( IsWindowEnabled( GetDlgItem( hDlg, IDC_STOP ) ) )
  316.     {
  317.         // We think the sound is playing, so see if it has stopped yet.
  318.         if( !g_pSound->IsSoundPlaying() ) 
  319.         {
  320.             // Update the UI controls to show the sound as stopped
  321.             EnablePlayUI( hDlg, TRUE );
  322.         }
  323.     }
  324. }
  325.  
  326.  
  327.  
  328.  
  329. //-----------------------------------------------------------------------------
  330. // Name: EnablePlayUI( hDlg,)
  331. // Desc: Enables or disables the Play UI controls 
  332. //-----------------------------------------------------------------------------
  333. VOID EnablePlayUI( HWND hDlg, BOOL bEnable )
  334. {
  335.     if( bEnable )
  336.     {
  337.         EnableWindow(   GetDlgItem( hDlg, IDC_LOOP_CHECK ), TRUE );
  338.         EnableWindow(   GetDlgItem( hDlg, IDC_STOP ),       FALSE );
  339.  
  340.         EnableWindow(   GetDlgItem( hDlg, IDC_PLAY ),       TRUE );
  341.         SetFocus(       GetDlgItem( hDlg, IDC_PLAY ) );
  342.         SetDlgItemText( hDlg, IDC_PLAY, "&Play" );
  343.     }
  344.     else
  345.     {
  346.         EnableWindow(  GetDlgItem( hDlg, IDC_LOOP_CHECK ), FALSE );
  347.         EnableWindow(  GetDlgItem( hDlg, IDC_STOP ),       TRUE );
  348.         SetFocus(      GetDlgItem( hDlg, IDC_STOP ) );
  349.  
  350.         EnableWindow(  GetDlgItem( hDlg, IDC_PLAY ),       TRUE );
  351.         SetDlgItemText( hDlg, IDC_PLAY, "&Pause" );
  352.     }
  353. }
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.