home *** CD-ROM | disk | FTP | other *** search
/ NEXT Generation 27 / NEXT27.iso / pc / demos / emperor / dx3.exe / SDK / SAMPLES / DSSHOW3D / FINFO3D.CPP < prev    next >
C/C++ Source or Header  |  1996-08-28  |  30KB  |  980 lines

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #include <mmsystem.h>
  4. #include <commctrl.h>
  5. #include <dsound.h>
  6.  
  7. #include "wave.h"
  8. #include "debug.h"
  9. #include "DSShow3D.h"
  10. #include "FInfo3D.h"
  11. #include "GVars.h"
  12.  
  13.  
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // FileInfo3D()
  16. //
  17. //    Class constructor for the 3D interface/information class.
  18. //
  19. FileInfo3D::FileInfo3D( MainWnd * pmw ) : FileInfo( pmw )
  20.     {
  21.     ZeroMemory( &m_ht3d, sizeof(HWNDTABLE3D));
  22.     ZeroMemory( &m_vPos, sizeof(D3DVECTOR));
  23.     m_pDSB3D = NULL;
  24.  
  25.     m_dwInternalFlags |= FI_INTERNALF_3D;
  26.  
  27.     m_dwInnerAngle = FI3D_DEFAULT_INNER_ANGLE;
  28.     m_dwOuterAngle = FI3D_DEFAULT_OUTER_ANGLE;
  29.     }
  30.  
  31.  
  32. ///////////////////////////////////////////////////////////////////////////////
  33. // ~FileInfo3D()
  34. //
  35. //   Virtual destructor for the FileInfo3D class.  Should deallocate any space
  36. // allocated by the constructor.
  37. //
  38. FileInfo3D::~FileInfo3D()
  39.     {
  40.     // If we do an allocation of memory specific to the FileInfo3D class,
  41.     // we should free it here.
  42.  
  43.     // Release the 3D interface
  44.     if( m_pDSB3D != NULL )
  45.     {
  46.     m_pDSB3D->Release();
  47.     m_pDSB3D = NULL;
  48.     }
  49.     }
  50.  
  51.  
  52. ///////////////////////////////////////////////////////////////////////////////
  53. // NewDirectSoundBuffer()
  54. // 
  55. //    Virtual function which handles opening a new sound bufer by setting some
  56. // flags and calling down to the base class handler, which actually does most
  57. // of the work.  Upon return, this function will do a bit more work to get a 3D
  58. // interface.
  59. //
  60. int FileInfo3D::NewDirectSoundBuffer()
  61.     {
  62.     HRESULT hr;
  63.  
  64.     m_dsbd.dwFlags = DSBCAPS_CTRL3D;
  65.  
  66.     if( !FileInfo::NewDirectSoundBuffer())
  67.     {
  68.     // Try to grab the 3D interface pointer
  69.  
  70.     if( FAILED( hr = m_pDSB->QueryInterface( IID_IDirectSound3DBuffer,
  71.                             (void **)&m_pDSB3D )))
  72.         {
  73.         DPF( 0, "QI for DS3DBuffer interface: %s", TranslateDSError(hr));
  74.         return -1;
  75.         }
  76.     return 0;
  77.     }
  78.     else
  79.     return -1;
  80.     }
  81.  
  82.  
  83. ///////////////////////////////////////////////////////////////////////////////
  84. //
  85. //
  86. //
  87. //
  88. BOOL FileInfo3D::OnInitDialog( HWND hDlg, WPARAM wParam )
  89.     {
  90.     HRESULT hr;
  91.     char    szTS[6];
  92.  
  93.     // Grab some 3D interface HWND's and pass along to the base class
  94.     m_ht3d.hXSlider = GetDlgItem( hDlg, IDC_BUFFERDLG_X_SLIDER );
  95.     m_ht3d.hYSlider = GetDlgItem( hDlg, IDC_BUFFERDLG_Y_SLIDER );
  96.     m_ht3d.hZSlider = GetDlgItem( hDlg, IDC_BUFFERDLG_Z_SLIDER );
  97.     m_ht3d.hOuterVolSlider = GetDlgItem( hDlg, IDC_BUFFERDLG_OUTERVOL_SLIDER );
  98.     m_ht3d.hOuterVolText = GetDlgItem( hDlg, IDC_BUFFERDLG_OUTERVOL_TEXT );
  99.     m_ht3d.hInnerAngleEdit = GetDlgItem( hDlg, IDC_BUFFERDLG_INNERANGLE_EDIT );
  100.     m_ht3d.hInnerAngleSpin = GetDlgItem( hDlg, IDC_BUFFERDLG_INNERANGLE_SPIN );
  101.     m_ht3d.hOuterAngleEdit = GetDlgItem( hDlg, IDC_BUFFERDLG_OUTERANGLE_EDIT );
  102.     m_ht3d.hOuterAngleSpin = GetDlgItem( hDlg, IDC_BUFFERDLG_OUTERANGLE_SPIN );
  103.     m_ht3d.hXText = GetDlgItem( hDlg, IDC_BUFFERDLG_X_TEXT );
  104.     m_ht3d.hYText = GetDlgItem( hDlg, IDC_BUFFERDLG_Y_TEXT );
  105.     m_ht3d.hZText = GetDlgItem( hDlg, IDC_BUFFERDLG_Z_TEXT );
  106.     m_ht3d.hDisable3D = GetDlgItem( hDlg, IDC_BUFFERDLG_DISABLE );
  107.  
  108.     // The tab order in the dialog must be such that the spin control is
  109.     // immediately after the edit control it is expected to auto-buddy to.
  110.     // That case is tested here.
  111.     ASSERT( (HWND)SendMessage( m_ht3d.hInnerAngleSpin,
  112.                 UDM_GETBUDDY, 0, 0 ) == m_ht3d.hInnerAngleEdit );
  113.  
  114.     // If this fails, the tab order in the dialog resource is wrong (see above)
  115.     ASSERT( (HWND)SendMessage( m_ht3d.hOuterAngleSpin,
  116.                 UDM_GETBUDDY, 0, 0 ) == m_ht3d.hOuterAngleEdit );
  117.  
  118.     SendMessage( m_ht3d.hInnerAngleSpin, UDM_SETRANGE, 0, MAKELONG( 360, 0 ));
  119.     SendMessage( m_ht3d.hOuterAngleSpin, UDM_SETRANGE, 0, MAKELONG( 360, 0 ));
  120.  
  121.     SendMessage( m_ht3d.hInnerAngleSpin, UDM_SETPOS,
  122.                         0, MAKELONG(m_dwInnerAngle, 0));
  123.     wsprintf( szTS, "%u", m_dwInnerAngle );
  124.     Edit_SetText( m_ht3d.hInnerAngleEdit, szTS );
  125.  
  126.     SendMessage( m_ht3d.hOuterAngleSpin, UDM_SETPOS,
  127.                         0, MAKELONG(m_dwOuterAngle, 0));
  128.     wsprintf( szTS, "%u", m_dwOuterAngle );
  129.     Edit_SetText( m_ht3d.hOuterAngleEdit, szTS );
  130.  
  131.     if( m_pDSB3D )
  132.     {
  133.     if( FAILED( hr = m_pDSB3D->SetConeAngles( m_dwInnerAngle,
  134.                         m_dwOuterAngle, DS3D_IMMEDIATE )))
  135.         DPF( 0, "SetConeAngles: %s", TranslateDSError(hr));
  136.  
  137.     m_pDSB3D->GetPosition( &m_vPos );
  138.     }
  139.  
  140.     return FileInfo::OnInitDialog( hDlg, wParam );
  141.     }
  142.  
  143.  
  144. ///////////////////////////////////////////////////////////////////////////////
  145. //
  146. //
  147. //
  148. //
  149. BOOL FileInfo3D::OnCommand( WPARAM wParam, LPARAM lParam )
  150.     {
  151.     BOOL    fRet = FALSE;
  152.  
  153.     if( HandleOuterVolContext( wParam ) || HandlePositionContext( wParam ))
  154.     fRet = TRUE;
  155.     else if( HandleConeInnerEditNotify( wParam, lParam ))
  156.         fRet = TRUE;
  157.     else if( HandleConeOuterEditNotify( wParam, lParam ))
  158.         fRet = TRUE;
  159.     else if( HandleDisableNotify( wParam, lParam ))
  160.         fRet = TRUE;
  161.     else
  162.     fRet = FileInfo::OnCommand( wParam, lParam );
  163.  
  164.     return fRet;
  165.     }
  166.  
  167.  
  168. ///////////////////////////////////////////////////////////////////////////////
  169. // OnHScroll()
  170. //
  171. //
  172. //
  173. BOOL FileInfo3D::OnHScroll( WORD wNotification, LONG lPos, HWND hControl )
  174.     {
  175.     if( !hControl )
  176.     return FALSE;
  177.     if( hControl == m_ht3d.hOuterVolSlider )
  178.     HandleOuterVolSliderScroll( wNotification, lPos );
  179.     else if( hControl == m_ht3d.hXSlider )
  180.     HandleXSliderScroll( wNotification, lPos );
  181.     else if( hControl == m_ht3d.hYSlider )
  182.     HandleYSliderScroll( wNotification, lPos );
  183.     else if( hControl == m_ht3d.hZSlider )
  184.     HandleZSliderScroll( wNotification, lPos );
  185.     // All messages we don't handle pass through to the base class
  186.     else
  187.     return FileInfo::OnHScroll( wNotification, lPos, hControl );
  188.     
  189.     return TRUE;
  190.     }
  191.  
  192.  
  193. ///////////////////////////////////////////////////////////////////////////////
  194. //
  195. //
  196. //
  197. //
  198. void FileInfo3D::HandleOuterVolSliderScroll( WORD wNot, LONG lPos )
  199.     {
  200.     HRESULT hr;
  201.     BOOL fUpdate = TRUE;
  202.  
  203.     switch( wNot )
  204.     {
  205.     case TB_THUMBTRACK:
  206.         break;
  207.  
  208.     case TB_ENDTRACK:
  209.     case TB_LINEDOWN:
  210.     case TB_LINEUP:
  211.     case TB_PAGEDOWN:
  212.     case TB_PAGEUP:
  213.         lPos = SendMessage( m_ht3d.hOuterVolSlider, TBM_GETPOS, 0, 0 );
  214.         break;
  215.  
  216.     default:
  217.         fUpdate = FALSE;
  218.     }
  219.     
  220.     if( fUpdate && NULL != m_pDSB3D )
  221.     {
  222. //  DPF( 3, "SetConeOutsideVolume: %i", ( lPos * VOL_SLIDER_FACTOR ) - VOL_SLIDER_SHIFT );
  223.     if( FAILED( hr = m_pDSB3D->SetConeOutsideVolume(( lPos * VOL_SLIDER_FACTOR )
  224.                     - VOL_SLIDER_SHIFT, DS3D_IMMEDIATE )))
  225.         DPF( 0, "SetConeOutsideVolume: %s", TranslateDSError(hr));
  226.     UpdateOuterVolUI(( lPos * VOL_SLIDER_FACTOR ) - VOL_SLIDER_SHIFT,
  227.                                     FALSE );
  228.     }
  229.     }
  230.  
  231.  
  232. ///////////////////////////////////////////////////////////////////////////////
  233. //
  234. //
  235. //
  236. //
  237. void FileInfo3D::HandleXSliderScroll( WORD wNot, LONG lPos )
  238.     {
  239.     HRESULT hr;
  240.     BOOL fUpdate = TRUE;
  241.  
  242.     switch( wNot )
  243.     {
  244.     case TB_THUMBTRACK:
  245.         break;
  246.  
  247.     case TB_ENDTRACK:
  248.     case TB_LINEDOWN:
  249.     case TB_LINEUP:
  250.     case TB_PAGEDOWN:
  251.     case TB_PAGEUP:
  252.         lPos = SendMessage( m_ht3d.hXSlider, TBM_GETPOS, 0, 0 );
  253.         break;
  254.  
  255.     default:
  256.         fUpdate = FALSE;
  257.     }
  258.     
  259.     if( fUpdate && NULL != m_pDSB3D )
  260.     {
  261.     m_vPos.x = D3DVAL(lPos * X_SLIDER_FACTOR) - POS_SLIDER_SHIFT;
  262. //  DPF( 3, "Setting buffer pos: (%i, %i, %i)",
  263. //              (int)m_vPos.x, (int)m_vPos.y, (int)m_vPos.z );
  264.     if( FAILED( hr = m_pDSB3D->SetPosition( m_vPos.x, m_vPos.y,
  265.                         m_vPos.z, DS3D_IMMEDIATE )))
  266.         DPF( 0, "SetPosition: %s", TranslateDSError(hr));
  267.     UpdateXSliderUI((lPos * X_SLIDER_FACTOR) - POS_SLIDER_SHIFT, FALSE );
  268.     }
  269.     }
  270.  
  271.  
  272. ///////////////////////////////////////////////////////////////////////////////
  273. //
  274. //
  275. //
  276. //
  277. void FileInfo3D::HandleYSliderScroll( WORD wNot, LONG lPos )
  278.     {
  279.     HRESULT hr;
  280.     BOOL fUpdate = TRUE;
  281.  
  282.     switch( wNot )
  283.     {
  284.     case TB_THUMBTRACK:
  285.         break;
  286.  
  287.     case TB_ENDTRACK:
  288.     case TB_LINEDOWN:
  289.     case TB_LINEUP:
  290.     case TB_PAGEDOWN:
  291.     case TB_PAGEUP:
  292.         lPos = SendMessage( m_ht3d.hYSlider, TBM_GETPOS, 0, 0 );
  293.         break;
  294.  
  295.     default:
  296.         fUpdate = FALSE;
  297.     }
  298.     
  299.     if( fUpdate && NULL != m_pDSB3D )
  300.     {
  301.     m_vPos.y = D3DVAL(lPos * Y_SLIDER_FACTOR) - POS_SLIDER_SHIFT;
  302. //  DPF( 3, "Setting buffer pos: (%i, %i, %i)",
  303. //              (int)m_vPos.x, (int)m_vPos.y, (int)m_vPos.z );
  304.     if( FAILED( hr = m_pDSB3D->SetPosition( m_vPos.x, m_vPos.y,
  305.                         m_vPos.z, DS3D_IMMEDIATE )))
  306.         DPF( 0, "SetPosition: %s", TranslateDSError(hr));
  307.     UpdateYSliderUI((lPos * Y_SLIDER_FACTOR) - POS_SLIDER_SHIFT, FALSE );
  308.     }
  309.     }
  310.  
  311.  
  312. ///////////////////////////////////////////////////////////////////////////////
  313. //
  314. //
  315. //
  316. //
  317. void FileInfo3D::HandleZSliderScroll( WORD wNot, LONG lPos )
  318.     {
  319.     HRESULT hr;
  320.     BOOL fUpdate = TRUE;
  321.  
  322.     switch( wNot )
  323.     {
  324.     case TB_THUMBTRACK:
  325.         break;
  326.  
  327.     case TB_ENDTRACK:
  328.     case TB_LINEDOWN:
  329.     case TB_LINEUP:
  330.     case TB_PAGEDOWN:
  331.     case TB_PAGEUP:
  332.         lPos = SendMessage( m_ht3d.hZSlider, TBM_GETPOS, 0, 0 );
  333.         break;
  334.  
  335.     default:
  336.         fUpdate = FALSE;
  337.     }
  338.     
  339.     if( fUpdate && NULL != m_pDSB3D )
  340.     {
  341.     m_vPos.z = D3DVAL(lPos * Z_SLIDER_FACTOR) - POS_SLIDER_SHIFT;
  342. //  DPF( 3, "Setting buffer pos: (%i, %i, %i)",
  343. //              (int)m_vPos.x, (int)m_vPos.y, (int)m_vPos.z );
  344.     if( FAILED( hr = m_pDSB3D->SetPosition( m_vPos.x, m_vPos.y,
  345.                         m_vPos.z, DS3D_IMMEDIATE )))
  346.         DPF( 0, "SetPosition: %s", TranslateDSError(hr));
  347.     UpdateZSliderUI((lPos * Z_SLIDER_FACTOR) - POS_SLIDER_SHIFT, FALSE );
  348.     }
  349.     }
  350.  
  351.  
  352. ///////////////////////////////////////////////////////////////////////////////
  353. // UpdateOuterVolUI()
  354. //
  355. //
  356. //
  357. //
  358. //
  359. void FileInfo3D::UpdateOuterVolUI( LONG lForceVol, BOOL fFromBuffer )
  360.     {
  361.     HRESULT hr;
  362.     LONG    lVol;
  363.     char    szText[16];
  364.  
  365.     if( fFromBuffer )
  366.         {
  367.     if( NULL != m_pDSB3D )
  368.         {
  369.         if( FAILED( hr = m_pDSB3D->GetConeOutsideVolume( &lVol )))
  370.         DPF( 0, "GetConeOutsideVolume: %s", TranslateDSError(hr));
  371.         }
  372.     else
  373.         lVol = 0;
  374.     }
  375.     else
  376.     lVol = lForceVol;
  377.  
  378.     SendMessage( m_ht3d.hOuterVolSlider, TBM_SETPOS, (WPARAM)TRUE,
  379.             (LPARAM)(lVol + VOL_SLIDER_SHIFT) / VOL_SLIDER_FACTOR );
  380.  
  381.     // Print volume in decibels
  382.     wsprintf( szText, "%i dB", lVol / 100 );
  383.  
  384.     Static_SetText( m_ht3d.hOuterVolText, szText );
  385.     }
  386.  
  387.  
  388. ///////////////////////////////////////////////////////////////////////////////
  389. //
  390. //
  391. //
  392. //
  393. BOOL FileInfo3D::OnContextMenu( HWND hDlg, int x, int y )
  394.     {
  395.     HMENU   hm, hSub;
  396.     int     nSubMenu = -1;
  397.     POINT   pt = { x, y };
  398.     RECT    rectWind1, rectWind2, rectWind3;
  399.  
  400.     // Set the sub-menu to the Outer Volume context menu if we hit the proper
  401.     // slider or text control
  402.     GetWindowRect( m_ht3d.hOuterVolSlider, &rectWind1 );
  403.     GetWindowRect( m_ht3d.hOuterVolText, &rectWind2 );
  404.  
  405.     if( PtInRect( &rectWind1, pt ) || PtInRect( &rectWind2, pt ))
  406.     nSubMenu = 3;
  407.  
  408.     // Set the POS_CONTEXT submenu if there's a click on the position sliders
  409.     // or text controls
  410.     GetWindowRect( m_ht3d.hXSlider, &rectWind1 );
  411.     GetWindowRect( m_ht3d.hYSlider, &rectWind2 );
  412.     GetWindowRect( m_ht3d.hZSlider, &rectWind3 );
  413.  
  414.     if( PtInRect( &rectWind1, pt ) || PtInRect( &rectWind2, pt )
  415.         || PtInRect( &rectWind3, pt ))
  416.     nSubMenu = 4;
  417.  
  418.     GetWindowRect( m_ht3d.hXText, &rectWind1 );
  419.     GetWindowRect( m_ht3d.hYText, &rectWind2 );
  420.     GetWindowRect( m_ht3d.hZText, &rectWind3 );
  421.  
  422.     if( PtInRect( &rectWind1, pt ) || PtInRect( &rectWind2, pt )
  423.         || PtInRect( &rectWind3, pt ))
  424.     nSubMenu = 4;
  425.  
  426.     // We didn't detect any "interesting" hotspots, so pass along to base class
  427.     if( nSubMenu < 0 )
  428.     return FileInfo::OnContextMenu( hDlg, x, y );
  429.  
  430.     // If we make it here, we're gonna popup a context menu of some sort
  431.  
  432.     // Attempt to load our menu.  If we fail, we still handled the message
  433.     // so return TRUE
  434.     if(( hm = LoadMenu( ghInst, MAKEINTRESOURCE(IDM_POPUPS))) == NULL )
  435.     return TRUE;
  436.  
  437.     hSub = GetSubMenu( hm, nSubMenu );
  438.     TrackPopupMenu( hSub, TPM_LEFTALIGN | TPM_RIGHTBUTTON,
  439.             pt.x, pt.y, 0, m_hwndInterface, NULL );
  440.     
  441.     DestroyMenu( hm );
  442.  
  443.     return TRUE;
  444.     }
  445.  
  446.  
  447. ///////////////////////////////////////////////////////////////////////////////
  448. //
  449. //
  450. //
  451. //
  452. void FileInfo3D::OnDestroy()
  453.     {
  454.     FileInfo::OnDestroy();
  455.     return;
  456.     }
  457.  
  458.  
  459. void FileInfo3D::Duplicate( FileInfo *pfiSource )
  460.     {
  461.     HRESULT hr;
  462.  
  463.     FileInfo::Duplicate( pfiSource );
  464.  
  465.     if( FAILED( hr = m_pDSB->QueryInterface( IID_IDirectSound3DBuffer,
  466.                             (void **)&m_pDSB3D )))
  467.     {
  468.     DPF( 0, "QI for DS3DBuffer interface: %s", TranslateDSError(hr));
  469.     }
  470.     else
  471.     {
  472.     // Update the UI from the interface we just got
  473.     UpdateOuterVolUI( 0, TRUE );
  474.     UpdateXSliderUI( 0, TRUE );
  475.     UpdateYSliderUI( 0, TRUE );
  476.     UpdateZSliderUI( 0, TRUE );
  477.  
  478.     m_pDSB3D->GetConeAngles( &m_dwInnerAngle, &m_dwOuterAngle );
  479.  
  480.     DWORD   dwMode;
  481.     char    szTS[6];
  482.  
  483.     SendMessage( m_ht3d.hInnerAngleSpin, UDM_SETPOS,
  484.                         0, MAKELONG(m_dwInnerAngle, 0));
  485.     wsprintf( szTS, "%u", m_dwInnerAngle );
  486.     Edit_SetText( m_ht3d.hInnerAngleEdit, szTS );
  487.  
  488.     SendMessage( m_ht3d.hOuterAngleSpin, UDM_SETPOS,
  489.                         0, MAKELONG(m_dwOuterAngle, 0));
  490.     wsprintf( szTS, "%u", m_dwOuterAngle );
  491.     Edit_SetText( m_ht3d.hOuterAngleEdit, szTS );
  492.  
  493.     m_pDSB3D->GetMode( &dwMode );
  494.     Button_SetCheck( m_ht3d.hDisable3D, dwMode == DS3DMODE_DISABLE );
  495.     }
  496.     }
  497.  
  498.  
  499. ///////////////////////////////////////////////////////////////////////////////
  500. // CreateInterface()
  501. // 
  502. //    Very similar to the interface creation code for 2D objects, but creates a
  503. // different dialog.  (Eventually may do more stuff related to D3D display).
  504. //
  505. BOOL FileInfo3D::CreateInterface( HWND hwndOwner )
  506.     {
  507.     m_hwndInterface = CreateDialogParam( ghInst, MAKEINTRESOURCE(IDD_BUFFER3D),
  508.                     hwndOwner, (DLGPROC)FileInfo3DDlgProc,
  509.                     (LPARAM)this );
  510.  
  511.     if( NULL == m_hwndInterface )
  512.     goto FICI_Fail;
  513.     else
  514.     UpdateFileName();
  515.  
  516.     CascadeWindow();
  517.     ShowWindow( m_hwndInterface, SW_SHOW );
  518.  
  519.     // This flag tells us an interface window was successfully created
  520.     m_dwInternalFlags |= FI_INTERNALF_INTERFACE;
  521.     return TRUE;
  522.  
  523.  
  524. FICI_Fail:
  525.     if( m_hwndInterface )
  526.     {
  527.     DestroyWindow( m_hwndInterface );
  528.     m_hwndInterface = NULL;
  529.     }
  530.     // Clear the flag that says we have a good interface window created
  531.     m_dwInternalFlags &= ~FI_INTERNALF_INTERFACE;
  532.     return FALSE;
  533.     }
  534.  
  535.  
  536. ///////////////////////////////////////////////////////////////////////////////
  537. //
  538. //
  539. //
  540. //
  541. void FileInfo3D::SetSliders( void )
  542.     {
  543.     // Do 3D controls slider initialization
  544.  
  545.     // Intentionally set the range backwards because a large number means
  546.     // a smaller value
  547.     SendMessage( m_ht3d.hOuterVolSlider, TBM_SETRANGEMIN, FALSE,
  548.     (LPARAM)(VOL_MIN + VOL_SLIDER_SHIFT) / VOL_SLIDER_FACTOR );
  549.     SendMessage( m_ht3d.hOuterVolSlider, TBM_SETRANGEMAX, FALSE,
  550.     (LPARAM)(VOL_MAX + VOL_SLIDER_SHIFT) / VOL_SLIDER_FACTOR );
  551.     SendMessage( m_ht3d.hOuterVolSlider, TBM_SETPAGESIZE, 0,
  552.                 VOL_SLIDER_PAGE / VOL_SLIDER_FACTOR );
  553.     // NOTE: No TICs on the cone volume slider
  554.  
  555.     SendMessage( m_ht3d.hXSlider, TBM_SETRANGEMIN, FALSE,
  556.     (LPARAM)(POS_SLIDER_MIN + POS_SLIDER_SHIFT) / X_SLIDER_FACTOR );
  557.     SendMessage( m_ht3d.hXSlider, TBM_SETRANGEMAX, FALSE,
  558.     (LPARAM)(POS_SLIDER_MAX + POS_SLIDER_SHIFT) / X_SLIDER_FACTOR );
  559.     SendMessage( m_ht3d.hXSlider, TBM_SETPAGESIZE, 0, X_SLIDER_FACTOR );
  560.  
  561.     SendMessage( m_ht3d.hYSlider, TBM_SETRANGEMIN, FALSE,
  562.     (LPARAM)(POS_SLIDER_MIN + POS_SLIDER_SHIFT) / Y_SLIDER_FACTOR );
  563.     SendMessage( m_ht3d.hYSlider, TBM_SETRANGEMAX, FALSE,
  564.     (LPARAM)(POS_SLIDER_MAX + POS_SLIDER_SHIFT) / Y_SLIDER_FACTOR );
  565.     SendMessage( m_ht3d.hYSlider, TBM_SETPAGESIZE, 0, Y_SLIDER_FACTOR );
  566.  
  567.     SendMessage( m_ht3d.hZSlider, TBM_SETRANGEMIN, FALSE,
  568.     (LPARAM)(POS_SLIDER_MIN + POS_SLIDER_SHIFT) / Z_SLIDER_FACTOR );
  569.     SendMessage( m_ht3d.hZSlider, TBM_SETRANGEMAX, FALSE,
  570.     (LPARAM)(POS_SLIDER_MAX + POS_SLIDER_SHIFT) / Z_SLIDER_FACTOR );
  571.     SendMessage( m_ht3d.hZSlider, TBM_SETPAGESIZE, 0, Z_SLIDER_FACTOR );
  572.  
  573. //    SendMessage( m_ht3d.hOuterVolSlider, TBM_SETPAGESIZE, 0,
  574. //              VOL_SLIDER_PAGE / VOL_SLIDER_FACTOR );
  575.     // NOTE: No TICs on the position sliders
  576.  
  577.     // Update the display from the buffer's current settings
  578.     UpdateOuterVolUI( 0, TRUE );
  579.     UpdateXSliderUI( 0, TRUE );
  580.     UpdateYSliderUI( 0, TRUE );
  581.     UpdateZSliderUI( 0, TRUE );
  582.  
  583.     FileInfo::SetSliders();
  584.     }
  585.  
  586.  
  587. ///////////////////////////////////////////////////////////////////////////////
  588. //
  589. //
  590. //
  591. //
  592. void FileInfo3D::UpdateUI( void )
  593.     {
  594.     FileInfo::UpdateUI();
  595.     }
  596.  
  597.  
  598. ///////////////////////////////////////////////////////////////////////////////
  599. // UpdateFileName()
  600. //
  601. //    Updates the file name which is displayed in the dialog window caption.
  602. //
  603. void FileInfo3D::UpdateFileName( void )
  604.     {
  605.     char    szTitle[MAX_PATH + 5];
  606.  
  607.     if( NULL != m_hwndInterface )
  608.     {
  609.     lstrcpy( szTitle, &m_szFileName[m_nFileIndex] );
  610.     lstrcat( szTitle, TEXT(" (3D)"));
  611.     SendMessage( m_hwndInterface, WM_SETTEXT, 0L, (LPARAM)szTitle );
  612.     }
  613.     }
  614.  
  615.  
  616. ///////////////////////////////////////////////////////////////////////////////
  617. // FileInfo3DDlgProc()
  618. //
  619. //    
  620. //
  621. BOOL CALLBACK FileInfo3DDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
  622.     {
  623.     FileInfo3D *pfi3d;
  624.  
  625.     switch( message )
  626.     {
  627.     // The first step is to stash our class object pointer in the user data
  628.     // and Initialize all our controls and internal data members.
  629.     case WM_INITDIALOG:
  630.         ASSERT( NULL != lParam );
  631.         pfi3d = (FileInfo3D *)lParam;
  632.         SetWindowLong( hDlg, DWL_USER, (LONG)pfi3d );
  633.  
  634.         if( !pfi3d->OnInitDialog( hDlg, wParam ))
  635.         {
  636.         DestroyWindow( hDlg );
  637.         }
  638.         return TRUE;
  639.  
  640.     case WM_COMMAND:
  641.         pfi3d = (FileInfo3D*)GetWindowLong( hDlg, DWL_USER );
  642.         // It's possible to get notification messages from child controls
  643.         // before we have been given a WM_INITDIALOG message.  This is not
  644.         // a good thing for dereferencing the pointer because we won't have
  645.         // class info. Specifically, the spin controls in our dialog force
  646.         // the edit control to send EN_CHANGE and EN_UPDATE messages when
  647.         // they set the text of the edit control they're tied to.
  648.         if( NULL == pfi3d || NULL == pfi3d->m_hwndInterface )
  649.         return FALSE;
  650.         return !pfi3d->OnCommand( wParam, lParam );
  651.  
  652.     // Handle this to deal with right-clicks on our controls -- we have a
  653.     // bunch of different context menus that we can popup
  654.     case WM_CONTEXTMENU:
  655.         pfi3d = (FileInfo3D*)GetWindowLong( hDlg, DWL_USER );
  656.         ASSERT( NULL != pfi3d );
  657.         return pfi3d->OnContextMenu( hDlg, LOWORD(lParam), HIWORD(lParam));
  658.  
  659.     // Trackbar slider notifications come through here
  660.     case WM_HSCROLL:
  661.         pfi3d = (FileInfo3D*)GetWindowLong( hDlg, DWL_USER );
  662.         ASSERT( NULL != pfi3d );
  663.         return pfi3d->OnHScroll( LOWORD(wParam), (LONG)HIWORD(wParam), (HWND)lParam );
  664.  
  665.     case WM_DESTROY:
  666.         pfi3d = (FileInfo3D*)GetWindowLong( hDlg, DWL_USER );
  667.         ASSERT( NULL != pfi3d );
  668.         pfi3d->OnDestroy();
  669.         return TRUE;
  670.  
  671.     default:
  672.         return FileInfoDlgProc( hDlg, message, wParam, lParam );
  673.     }
  674.  
  675.     ASSERT( FALSE );
  676.     }
  677.  
  678.  
  679. ///////////////////////////////////////////////////////////////////////////////
  680. // HandleOuterVolContext()
  681. //
  682. //    Pre-process the parameters to WM_COMMAND messages we get and sees if we
  683. // knows how to handle any of them.  We know how to handle any message that
  684. // comes from the Outer Volume controls' context menu.
  685. //
  686. BOOL FileInfo3D::HandleOuterVolContext( WPARAM wParam )
  687.     {
  688.     HRESULT hr;
  689.  
  690.     switch( wParam )
  691.     {
  692.     case ID_OUTERVOLCONTEXT_0DB:
  693.         if( FAILED( hr = m_pDSB3D->SetConeOutsideVolume( 0,
  694.                                 DS3D_IMMEDIATE )))
  695.         DPF( 0, "SetConeOutsideVolume: %s", TranslateDSError(hr));
  696.         UpdateOuterVolUI( 0, TRUE );
  697.         break;
  698.  
  699.     case ID_OUTERVOLCONTEXT_10DB:
  700.         if( FAILED( hr = m_pDSB3D->SetConeOutsideVolume( -1000,
  701.                                 DS3D_IMMEDIATE )))
  702.         DPF( 0, "SetConeOutsideVolume: %s", TranslateDSError(hr));
  703.         UpdateOuterVolUI( -1000, TRUE );
  704.         break;
  705.  
  706.     case ID_OUTERVOLCONTEXT_20DB:
  707.         if( FAILED( hr = m_pDSB3D->SetConeOutsideVolume( -2000,
  708.                                 DS3D_IMMEDIATE )))
  709.         DPF( 0, "SetConeOutsideVolume: %s", TranslateDSError(hr));
  710.         UpdateOuterVolUI( -2000, TRUE );
  711.         break;
  712.  
  713.     case ID_OUTERVOLCONTEXT_30DB:
  714.         if( FAILED( hr = m_pDSB3D->SetConeOutsideVolume( -3000,
  715.                                 DS3D_IMMEDIATE )))
  716.         DPF( 0, "SetConeOutsideVolume: %s", TranslateDSError(hr));
  717.         UpdateOuterVolUI( -3000, TRUE );
  718.         break;
  719.  
  720.     case ID_OUTERVOLCONTEXT_100DB:
  721.         if( FAILED( hr = m_pDSB3D->SetConeOutsideVolume( -10000,
  722.                                 DS3D_IMMEDIATE )))
  723.         DPF( 0, "SetConeOutsideVolume: %s", TranslateDSError(hr));
  724.         UpdateOuterVolUI( -10000, TRUE );
  725.         break;
  726.  
  727.     default:
  728.         return FALSE;
  729.     }
  730.  
  731.     return TRUE;
  732.     }
  733.  
  734.  
  735. ///////////////////////////////////////////////////////////////////////////////
  736. // HandlePositionContext()
  737. //
  738. //    Pre-process the parameters to WM_COMMAND messages we get and sees if we
  739. // knows how to handle any of them.  We know how to handle any message that
  740. // comes from the Position controls' context menu.
  741. //
  742. BOOL FileInfo3D::HandlePositionContext( WPARAM wParam )
  743.     {
  744.     D3DVECTOR   d3dListener;
  745.  
  746.     switch( wParam )
  747.     {
  748.     case ID_POSCONTEXT_ORIGIN:
  749.         ASSERT( NULL != m_pDSB3D );
  750.         m_pDSB3D->SetPosition( D3DVAL(0), D3DVAL(0), D3DVAL(0), DS3D_IMMEDIATE );
  751.         UpdateXSliderUI( 0, TRUE );
  752.         UpdateYSliderUI( 0, TRUE );
  753.         UpdateZSliderUI( 0, TRUE );
  754.         break;
  755.  
  756.     case ID_POSCONTEXT_LISTENERPOSITION:
  757.         ASSERT( NULL != m_pDSB3D );
  758.         ASSERT( NULL != gp3DListener );
  759.         gp3DListener->GetPosition( &d3dListener );
  760.         m_pDSB3D->SetPosition( d3dListener.x, d3dListener.y,
  761.                     d3dListener.z, DS3D_IMMEDIATE );
  762.         UpdateXSliderUI( (DWORD)d3dListener.x, TRUE );
  763.         UpdateYSliderUI( (DWORD)d3dListener.y, TRUE );
  764.         UpdateZSliderUI( (DWORD)d3dListener.z, TRUE );
  765.         break;
  766.  
  767.     default:
  768.         return FALSE;
  769.     }
  770.  
  771.     return TRUE;
  772.     }
  773.  
  774.  
  775. ///////////////////////////////////////////////////////////////////////////////
  776. // UpdateXSliderUI()
  777. //
  778. //    Update anything that displays the position of the X slider in some manner
  779. // to reflect the new position, either from the buffer or from the parameter.
  780. //
  781. void FileInfo3D::UpdateXSliderUI( LONG lForcePos, BOOL fFromBuffer )
  782.     {
  783.     char    szText[8];
  784.     LONG    lPos;
  785.  
  786.     if( fFromBuffer )
  787.         {
  788.     if( NULL != m_pDSB3D )
  789.         {
  790.         m_pDSB3D->GetPosition( &m_vPos );
  791.         lPos = (LONG)m_vPos.x;
  792.         }
  793.     else
  794.         lPos = 0;
  795.     }
  796.     else
  797.     lPos = lForcePos;
  798.  
  799.     SendMessage( m_ht3d.hXSlider, TBM_SETPOS, (WPARAM)TRUE,
  800.             (LPARAM)(lPos + POS_SLIDER_SHIFT) / X_SLIDER_FACTOR );
  801.     wsprintf( szText, "%i", lPos );
  802.     Static_SetText( m_ht3d.hXText, szText );
  803.     }
  804.  
  805.  
  806. ///////////////////////////////////////////////////////////////////////////////
  807. // UpdateYSliderUI()
  808. //
  809. //    Update anything that displays the position of the Y slider in some manner
  810. // to reflect the new position, either from the buffer or from the parameter.
  811. //
  812. void FileInfo3D::UpdateYSliderUI( LONG lForcePos, BOOL fFromBuffer )
  813.     {
  814.     char    szText[8];
  815.     LONG    lPos;
  816.  
  817.     if( fFromBuffer )
  818.         {
  819.     if( NULL != m_pDSB3D )
  820.         {
  821.         m_pDSB3D->GetPosition( &m_vPos );
  822.         lPos = (LONG)m_vPos.y;
  823.         }
  824.     else
  825.         lPos = 0;
  826.     }
  827.     else
  828.     lPos = lForcePos;
  829.  
  830.     SendMessage( m_ht3d.hYSlider, TBM_SETPOS, (WPARAM)TRUE,
  831.             (LPARAM)(lPos + POS_SLIDER_SHIFT) / Y_SLIDER_FACTOR );
  832.     wsprintf( szText, "%i", lPos );
  833.     Static_SetText( m_ht3d.hYText, szText );
  834.     }
  835.  
  836.  
  837. ///////////////////////////////////////////////////////////////////////////////
  838. // UpdateZSliderUI()
  839. //
  840. //    Update anything that displays the position of the Z slider in some manner
  841. // to reflect the new position, either from the buffer or from the parameter.
  842. //
  843. void FileInfo3D::UpdateZSliderUI( LONG lForcePos, BOOL fFromBuffer )
  844.     {
  845.     char    szText[8];
  846.     LONG    lPos;
  847.  
  848.     if( fFromBuffer )
  849.         {
  850.     if( NULL != m_pDSB3D )
  851.         {
  852.         m_pDSB3D->GetPosition( &m_vPos );
  853.         lPos = (LONG)m_vPos.z;
  854.         }
  855.     else
  856.         lPos = 0;
  857.     }
  858.     else
  859.     lPos = lForcePos;
  860.  
  861.     SendMessage( m_ht3d.hZSlider, TBM_SETPOS, (WPARAM)TRUE,
  862.             (LPARAM)(lPos + POS_SLIDER_SHIFT) / Z_SLIDER_FACTOR );
  863.     wsprintf( szText, "%i", lPos );
  864.     Static_SetText( m_ht3d.hZText, szText );
  865.     }
  866.  
  867.  
  868. BOOL FileInfo3D::HandleConeInnerEditNotify( WPARAM wParam, LPARAM lParam )
  869.     {
  870.     HRESULT hr;
  871.     BOOL    fRet = FALSE;
  872.     LONG    lValue;
  873.     char    szTS[6];
  874.  
  875.     if( HIWORD( wParam ) == EN_CHANGE )
  876.     {
  877.     if( (HWND)lParam == m_ht3d.hInnerAngleEdit )
  878.         {
  879.         Edit_GetText( m_ht3d.hInnerAngleEdit, szTS, sizeof(szTS));
  880.         lValue = atol(szTS);
  881.         if( lValue < 0 )
  882.         {
  883.         Edit_SetText( m_ht3d.hInnerAngleEdit, "0" );
  884.         return TRUE;
  885.         }
  886.         else
  887.         m_dwInnerAngle = (DWORD)lValue;
  888.  
  889.         // Make sure we haven't incremented the inner cone larger than
  890.         // the outer cone
  891.         if( m_dwInnerAngle > m_dwOuterAngle )
  892.         {
  893.         m_dwOuterAngle = m_dwInnerAngle;
  894.         SendMessage( m_ht3d.hOuterAngleSpin, UDM_SETPOS,
  895.                     0, MAKELONG(m_dwOuterAngle, 0));
  896.         wsprintf( szTS, "%u", m_dwOuterAngle );
  897.         Edit_SetText( m_ht3d.hOuterAngleEdit, szTS );
  898.         }
  899.         if( m_pDSB3D )
  900.         if( FAILED( hr = m_pDSB3D->SetConeAngles( m_dwInnerAngle,
  901.                     m_dwOuterAngle, DS3D_IMMEDIATE )))
  902.             DPF( 0, "SetConeAngles: %s", TranslateDSError(hr));
  903.         fRet = TRUE;
  904.         }
  905.     }
  906.  
  907.     return fRet;
  908.     }
  909.  
  910.  
  911. BOOL FileInfo3D::HandleConeOuterEditNotify( WPARAM wParam, LPARAM lParam )
  912.     {
  913.     HRESULT hr;
  914.     BOOL    fRet = FALSE;
  915.     LONG    lValue;
  916.     char    szTS[6];
  917.  
  918.     if( HIWORD( wParam ) == EN_CHANGE )
  919.     {
  920.     if( (HWND)lParam == m_ht3d.hOuterAngleEdit )
  921.         {
  922.         Edit_GetText( m_ht3d.hOuterAngleEdit, szTS, sizeof(szTS));
  923.         lValue = atol(szTS);
  924.         if( lValue < 0 )
  925.         {
  926.         Edit_SetText( m_ht3d.hOuterAngleEdit, "0" );
  927.         return TRUE;
  928.         }
  929.         else
  930.         m_dwOuterAngle = (DWORD)lValue;
  931.         // Make sure we haven't decremented the outer cone smaller than
  932.         // the inner cone
  933.         if( m_dwInnerAngle > m_dwOuterAngle )
  934.         {
  935.         m_dwInnerAngle = m_dwOuterAngle;
  936.         SendMessage( m_ht3d.hInnerAngleSpin, UDM_SETPOS,
  937.                     0, MAKELONG(m_dwInnerAngle, 0));
  938.         wsprintf( szTS, "%u", m_dwInnerAngle );
  939.         Edit_SetText( m_ht3d.hInnerAngleEdit, szTS );
  940.         }
  941.         if( m_pDSB3D )
  942.         if( FAILED( hr = m_pDSB3D->SetConeAngles( m_dwInnerAngle,
  943.                     m_dwOuterAngle, DS3D_IMMEDIATE )))
  944.             DPF( 0, "SetConeAngles: %s", TranslateDSError(hr));
  945.         fRet = TRUE;
  946.         }
  947.     }
  948.  
  949.     return fRet;
  950.     }
  951.  
  952. BOOL FileInfo3D::HandleDisableNotify( WPARAM wParam, LPARAM lParam )
  953.     {
  954.     HRESULT hr;
  955.     BOOL    fRet = FALSE;
  956.  
  957.     if( (HWND)lParam == m_ht3d.hDisable3D )
  958.     {
  959.         if( Button_GetCheck( m_ht3d.hDisable3D ))
  960.         {
  961.             if( m_pDSB3D ) {
  962.             if( FAILED( hr = m_pDSB3D->SetMode( DS3DMODE_DISABLE, 0 )))
  963.                 DPF( 0, "SetMode: %s", TranslateDSError(hr));
  964.             fRet = TRUE;
  965.             }
  966.         }
  967.         else
  968.         {
  969.             if( m_pDSB3D ) {
  970.             if( FAILED( hr = m_pDSB3D->SetMode( DS3DMODE_NORMAL, 0 )))
  971.                 DPF( 0, "SetMode: %s", TranslateDSError(hr));
  972.             fRet = TRUE;
  973.             }
  974.         }
  975.     }
  976.  
  977.     return fRet;
  978.     }
  979.  
  980.