home *** CD-ROM | disk | FTP | other *** search
/ Beginning Direct3D Game Programming / Direct3D.iso / directx / dxf / samples / multimedia / directshow / dvd / dvdsample / dialogs.cpp next >
Encoding:
C/C++ Source or Header  |  2000-11-04  |  38.9 KB  |  1,185 lines

  1. //------------------------------------------------------------------------------
  2. // File: Dialogs.cpp
  3. //
  4. // Desc: This file contains the implementation for the various dialog wrapper
  5. //       classes used in DvdSample.
  6. //
  7. // Copyright (c) 1999-2000, Microsoft Corporation. All rights reserved.
  8. //------------------------------------------------------------------------------
  9.  
  10. #include <dshow.h>
  11. #include <commctrl.h>
  12. #include "resource.h"
  13. #include "DvdCore.h" // so we can directly access the IdvdInfo2 pointers
  14. #include "DvdSample.h"
  15. #include "Dialogs.h"
  16. #include "StringUtil.h"
  17.  
  18.  
  19.  
  20. //------------------------------------------------------------------------------
  21. // Name: struct LANGINFO
  22. // Desc: An easy way of getting the lang code from the DVD_SubpictureATR data
  23. //------------------------------------------------------------------------------
  24.  
  25. struct LANGINFO 
  26. {
  27.     WORD  wRes1 ;  // don't care, just skip 2 bytes
  28.     WORD  wLang ;  // lang code as a WORD value
  29.     WORD  wRes2 ;  // don't care, another 2 bytes
  30. };
  31.  
  32.  
  33.  
  34.  
  35. //------------------------------------------------------------------------------
  36. // CAboutDlg
  37. //------------------------------------------------------------------------------
  38.  
  39.  
  40. //------------------------------------------------------------------------------
  41. // Name: CAboutDlg::CAboutDlg()
  42. // Desc: This is the CAboutDialog constructor.  It initializes some variables
  43. //       that we'll need later.
  44. //------------------------------------------------------------------------------
  45.  
  46. CAboutDlg::CAboutDlg(HINSTANCE hInstance, HWND hWnd):
  47.     m_hInstance(hInstance), m_hWnd(hWnd)
  48. {
  49.     DbgLog((LOG_TRACE, 5, TEXT("CAboutDlg::CAboutDlg()"))) ;
  50. }
  51.  
  52.  
  53. //------------------------------------------------------------------------------
  54. // Name: CAboutDlg::~CAboutDlg()
  55. // Desc: This is the CAboutDialog destructor.
  56. //------------------------------------------------------------------------------
  57.  
  58. CAboutDlg::~CAboutDlg()
  59. {
  60.     DbgLog((LOG_TRACE, 5, TEXT("CAboutDlg::~CAboutDlg()"))) ;
  61. }
  62.  
  63.  
  64. //------------------------------------------------------------------------------
  65. // Name: CAboutDlg::DoModa()
  66. // Desc: This method creates the dialog box and handles its return value.
  67. //------------------------------------------------------------------------------
  68. bool CAboutDlg::DoModal()
  69. {
  70.     DbgLog((LOG_TRACE, 5, TEXT("CAboutDlg::DoModal()"))) ;
  71.  
  72.     int retVal;
  73.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_ABOUT), m_hWnd, 
  74.         CAboutDlg::AboutDlgProc, reinterpret_cast<LPARAM>(this));
  75.     if (TRUE == retVal)
  76.     {
  77.         return true;
  78.     }
  79.     else return false;
  80. }
  81.  
  82.  
  83. //------------------------------------------------------------------------------
  84. // Name: CAboutDlg::AboutDlgProc()
  85. // Desc: This method is the MessageProc for the CAboutDlg dialog box.  It handles
  86. //       all windows messages sent to the dialog window.
  87. //------------------------------------------------------------------------------
  88.  
  89. BOOL CALLBACK CAboutDlg::AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  90. {
  91.     static CAboutDlg * pThis;
  92.  
  93.     switch (message)
  94.     {
  95.     case WM_INITDIALOG:
  96.         pThis = reinterpret_cast<CAboutDlg *>(lParam); // so we have a pointer to the calling object
  97.         return TRUE;
  98.  
  99.     case WM_COMMAND:
  100.         switch (LOWORD(wParam))
  101.         {
  102.         case IDOK:
  103.             EndDialog(hDlg, TRUE);
  104.             return TRUE;
  105.         }
  106.         break;
  107.     }
  108.     return FALSE;
  109. }
  110.  
  111.  
  112.  
  113.  
  114. //------------------------------------------------------------------------------
  115. // CSPLangDlg
  116. //------------------------------------------------------------------------------
  117.  
  118.  
  119. //------------------------------------------------------------------------------
  120. // Name: CSPLangDlg::CSPLangDlg()
  121. // Desc: This is the CSPLangDlg constructor.  It initializes some variables
  122. //       that we'll need later.
  123. //------------------------------------------------------------------------------
  124.  
  125. CSPLangDlg::CSPLangDlg(HINSTANCE hInstance, HWND hWnd):
  126.     m_hInstance(hInstance), m_hWnd(hWnd)
  127. {
  128.     DbgLog((LOG_TRACE, 5, TEXT("CSPLangDlg::CSPLangDlg()"))) ;
  129. }
  130.  
  131.  
  132. //------------------------------------------------------------------------------
  133. // Name: CSPLangDlg::~CSPLangDlg()
  134. // Desc: This is the CSPLangDlg destructor.
  135. //------------------------------------------------------------------------------
  136.  
  137. CSPLangDlg::~CSPLangDlg()
  138. {
  139.     DbgLog((LOG_TRACE, 5, TEXT("CSPLangDlg::~CSPLangDlg()"))) ;
  140. }
  141.  
  142.  
  143. //------------------------------------------------------------------------------
  144. // Name: CAboutDlg::DoModa()
  145. // Desc: This method creates the dialog box and handles its return value.
  146. //------------------------------------------------------------------------------
  147.  
  148. bool CSPLangDlg::DoModal()
  149. {
  150.     DbgLog((LOG_TRACE, 5, TEXT("CSPLangDlg::DoModal()"))) ;
  151.  
  152.     int retVal;
  153.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_SPDLG), m_hWnd, 
  154.         CSPLangDlg::SPDlgProc, reinterpret_cast<LPARAM>(this));
  155.     if (TRUE == retVal)
  156.     {
  157.         return true;
  158.     }
  159.     else return false;
  160. }
  161.  
  162.  
  163. //------------------------------------------------------------------------------
  164. // Name: CSPLangDlg::SPDlgProc()
  165. // Desc: This is the Dialog MessageProc for the subpicture language selection
  166. //       dialog.
  167. //------------------------------------------------------------------------------
  168.  
  169. BOOL CALLBACK CSPLangDlg::SPDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  170. {
  171.     static CSPLangDlg * pThis; 
  172.  
  173.     switch (message)
  174.     {
  175.  
  176.     case WM_INITDIALOG:
  177.         pThis = reinterpret_cast<CSPLangDlg *>(lParam); // get a pointer to the calling object
  178.         if (0 < pThis->MakeSPStreamList(hDlg, IDC_SPLANG))
  179.             return TRUE;
  180.         else
  181.         {
  182.              EndDialog(hDlg, FALSE);
  183.             return FALSE;
  184.         }
  185.  
  186.     case WM_COMMAND:
  187.         switch (LOWORD(wParam))
  188.         {
  189.         case IDOK:
  190.             {
  191.             HRESULT hr;
  192.  
  193.             // Set the SP state specified by the user
  194.             pThis->m_bSPOn = IsDlgButtonChecked(hDlg, IDC_SHOWSP) ;
  195.             hr = g_App.m_pDvdCore->m_pIDvdC2->SetSubpictureState(pThis->m_bSPOn, 0, NULL);
  196.             ASSERT(SUCCEEDED(hr)) ;
  197.  
  198.             // Set the SP stream specific by the user
  199.             LONG lStream;
  200.             lStream = SendDlgItemMessage(hDlg, IDC_SPLANG, CB_GETCURSEL, 
  201.                 static_cast<WPARAM>(0), static_cast<LPARAM>(0));
  202.             if (CB_ERR == lStream)
  203.                 DbgLog((LOG_ERROR, 1, 
  204.                 TEXT("WARNING: Couldn't get selected SP stream id (Error %d)"), lStream)) ;
  205.             else
  206.             {
  207.                 pThis->m_ulSPStream = lStream;
  208.                 hr = g_App.m_pDvdCore->m_pIDvdC2->SelectSubpictureStream(pThis->m_ulSPStream,
  209.                     0, NULL) ;
  210.                 ASSERT(SUCCEEDED(hr)) ;
  211.             }
  212.  
  213.             } // end of case brackets
  214.  
  215.             EndDialog(hDlg, TRUE);
  216.             return TRUE;
  217.  
  218.         case IDCANCEL:
  219.             EndDialog(hDlg, FALSE);
  220.             return TRUE;
  221.         }
  222.         break;
  223.     }
  224.     return FALSE;
  225. }
  226.  
  227.  
  228. //------------------------------------------------------------------------------
  229. // Name: CSPLangDlg::MakeSPStreamList()
  230. // Desc: This method will populate our dialog box and return the number of SP
  231. //       streams on this disc.  We do some extra work to get around LCID limitations
  232. //       on Win9x.
  233. //------------------------------------------------------------------------------
  234.  
  235. int CSPLangDlg::MakeSPStreamList(HWND hDlg, int iListID)
  236. {
  237.     DbgLog((LOG_TRACE, 5, TEXT("CSPLangDlg::MakeSPStreamList(0x%lx, %d)"), 
  238.         hDlg, iListID)) ;
  239.  
  240.     if (Uninitialized == g_App.m_pDvdCore->GetState())
  241.     {
  242.         DbgLog((LOG_ERROR, 0, TEXT("WARNING: DvdCore not initialized yet!"))) ;
  243.         return 0 ;
  244.     }
  245.  
  246.     // First clear the list box of all SP stream names
  247.     SendDlgItemMessage(hDlg, iListID, CB_RESETCONTENT, static_cast<WPARAM>(0), 
  248.         static_cast<LPARAM>(0)) ;
  249.  
  250.     // Find out how many SP streams are there and what's the current lang.
  251.     // This is our chance to find out if someone changed the SP lang through 
  252.     // DVD menu so that we can synch up our SP stream value now.
  253.     HRESULT hr = g_App.m_pDvdCore->m_pIDvdI2->GetCurrentSubpicture(&m_ulNumLang, &m_ulSPStream, 
  254.         &m_bSPOn) ;
  255.     if (FAILED(hr))
  256.     {
  257.         MessageBox(m_hWnd, TEXT("Not ready to find language information"), TEXT("Warning"), MB_OK) ;
  258.         return 0 ;
  259.     }
  260.     m_bSPOn = !m_bSPOn; // GetCurrentSubpicture returns IsDisabled, not IsOn
  261.  
  262.     LCID lcid;
  263.     TCHAR szLang[50];
  264.  
  265.     // Add all of the streams to the dialog box
  266.     for (ULONG ulStream = 0; ulStream < m_ulNumLang; ulStream++)
  267.     {
  268.         if (FAILED(g_App.m_pDvdCore->m_pIDvdI2->GetSubpictureLanguage(ulStream, &lcid)))
  269.         {
  270.             DbgLog((LOG_ERROR, 0, TEXT("WARNING: GetSubpictureLanguage Failed!"))) ;
  271.             return 0 ;
  272.         }
  273.  
  274.         if (0 == lcid || 0 == GetLocaleInfo(lcid, LOCALE_SLANGUAGE, szLang, sizeof(szLang))) 
  275.         // 0 is the failure code for GetLocaleInfo
  276.         {
  277.             GetSPLang(ulStream, szLang, sizeof(szLang));
  278.         }
  279.  
  280.         // Add the language to the listbox
  281.         SendDlgItemMessage(hDlg, iListID, CB_ADDSTRING, static_cast<WPARAM>(0),
  282.             reinterpret_cast<LPARAM>(static_cast<PVOID>(szLang)));
  283.     }
  284.  
  285.     // set the current stream as the selected item
  286.     if (m_ulNumLang > 0) // if there are any streams
  287.     {
  288.         int iRes = SendDlgItemMessage(hDlg, iListID, CB_SETCURSEL, 
  289.             static_cast<WPARAM>(m_ulSPStream), static_cast<LPARAM>(0)) ;
  290.         if (CB_ERR == iRes)
  291.             DbgLog((LOG_ERROR, 1, 
  292.             TEXT("WARNING: Couldn't set %ld as selected SP stream id (Error %d)"),
  293.             m_ulSPStream, iRes)) ;
  294.     }
  295.  
  296.     // set the checkbox to refect the current SP state
  297.     CheckDlgButton(hDlg, IDC_SHOWSP, m_bSPOn ? BST_CHECKED : BST_UNCHECKED) ;
  298.  
  299.     return m_ulNumLang;
  300. }
  301.  
  302.  
  303. //------------------------------------------------------------------------------
  304. // Name: CSPLangDlg::GetSPLang()
  305. // Desc: This method gets the LCID language code and looks up the subpicture
  306. //       language based on that.  This is to get around problems with Win95 where
  307. //       not all LCID's are recognized.
  308. //------------------------------------------------------------------------------
  309.  
  310. bool CSPLangDlg::GetSPLang(ULONG ulStream, TCHAR * buffer, int iBufLen)
  311. {
  312.     DbgLog((LOG_TRACE, 5, TEXT("CSPLangDlg::GetSPLang()"))) ;
  313.  
  314.     DVD_SubpictureAttributes SPATR ;
  315.     LANGINFO * pSPATR = reinterpret_cast<LANGINFO *>(&SPATR);
  316.     HRESULT hr = g_App.m_pDvdCore->m_pIDvdI2->GetSubpictureAttributes(ulStream, &SPATR);
  317.     ASSERT(SUCCEEDED(hr)) ;
  318.     return g_App.m_pLangLookup->GetLangString(SPATR.Language, buffer, iBufLen) ;
  319. }
  320.  
  321.  
  322.  
  323.  
  324. //------------------------------------------------------------------------------
  325. // CAudioLangDlg
  326. //------------------------------------------------------------------------------
  327.  
  328.  
  329. //------------------------------------------------------------------------------
  330. // Name: CAudioLangDlg::CAudioLangDlg()
  331. // Desc: This is the CAudioLangDlg Constructor.
  332. //------------------------------------------------------------------------------
  333.  
  334. CAudioLangDlg::CAudioLangDlg(HINSTANCE hInstance, HWND hWnd):
  335.     m_hInstance(hInstance), m_hWnd(hWnd)
  336. {
  337.     DbgLog((LOG_TRACE, 5, TEXT("CAudioLangDlg::CAudioLangDlg()"))) ;
  338. }
  339.  
  340.  
  341. //------------------------------------------------------------------------------
  342. // Name: CAudioLangDlg::~CAudioLangDlg()
  343. // Desc: This is the CAudioLangDlg destructor.
  344. //------------------------------------------------------------------------------
  345.  
  346. CAudioLangDlg::~CAudioLangDlg()
  347. {
  348.     DbgLog((LOG_TRACE, 5, TEXT("CAudioLangDlg::~CAudioLangDlg()"))) ;
  349. }
  350.  
  351.  
  352. //------------------------------------------------------------------------------
  353. // Name: CAudioLangDlg::DoModal()
  354. // Desc: This method creates the dialog box and handles its return value.
  355. //------------------------------------------------------------------------------
  356.  
  357. bool CAudioLangDlg::DoModal()
  358. {
  359.     DbgLog((LOG_TRACE, 5, TEXT("CAudioLangDlg::DoModal()"))) ;
  360.  
  361.     int retVal;
  362.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_AUDIODLG), m_hWnd, 
  363.         CAudioLangDlg::AudioDlgProc, reinterpret_cast<LPARAM>(this));
  364.     if (TRUE == retVal)
  365.     {
  366.         return true;
  367.     }
  368.     else return false;
  369. }
  370.  
  371.  
  372. //------------------------------------------------------------------------------
  373. // Name: CAudioLangDlg::AudioDlgProc()
  374. // Desc: This is the Dialog MessageProc for the audio language selection
  375. //       dialog.
  376. //------------------------------------------------------------------------------
  377.  
  378. BOOL CALLBACK CAudioLangDlg::AudioDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  379. {
  380.     static CAudioLangDlg * pThis; 
  381.  
  382.     switch (message)
  383.     {
  384.     case WM_INITDIALOG:
  385.         pThis = reinterpret_cast<CAudioLangDlg *>(lParam); // get a pointer to the calling object
  386.         if (0 < pThis->MakeAudioStreamList(hDlg, IDC_AUDIOLANG))
  387.             return TRUE;
  388.         else
  389.         {
  390.              EndDialog(hDlg, FALSE);
  391.             return FALSE;
  392.         }
  393.  
  394.     case WM_COMMAND:
  395.         switch (LOWORD(wParam))
  396.         {
  397.         case IDOK:
  398.             {
  399.             HRESULT hr;
  400.  
  401.             // Set the audio stream specific by the user
  402.             LONG lStream;
  403.             lStream = SendDlgItemMessage(hDlg, IDC_AUDIOLANG, CB_GETCURSEL, 
  404.                 static_cast<WPARAM>(0), static_cast<LPARAM>(0));
  405.             if (CB_ERR == lStream)
  406.                 DbgLog((LOG_ERROR, 1, 
  407.                 TEXT("WARNING: Couldn't get selected Audio stream ID (Error %d)"), lStream)) ;
  408.             else
  409.             {
  410.                 pThis->m_ulAudioStream = lStream;
  411.                 hr = g_App.m_pDvdCore->m_pIDvdC2->SelectAudioStream(pThis->m_ulAudioStream,
  412.                     0, NULL) ;
  413.                 ASSERT(SUCCEEDED(hr)) ;
  414.             }
  415.  
  416.             } // end of case brackets
  417.  
  418.             EndDialog(hDlg, TRUE);
  419.             return TRUE;
  420.  
  421.         case IDCANCEL:
  422.             EndDialog(hDlg, FALSE);
  423.             return TRUE;
  424.         }
  425.         break;
  426.     }
  427.     return FALSE;
  428. }
  429.  
  430.  
  431. //------------------------------------------------------------------------------
  432. // Name: CAudioLangDlg::MakeAudioStreamList()
  433. // Desc: This method will populate our dialog box and return the number of audio
  434. //       streams on this disc.  We do some extra work to get around LCID limitations
  435. //       on Win9x.
  436. //------------------------------------------------------------------------------
  437.  
  438. int CAudioLangDlg::MakeAudioStreamList(HWND hDlg, int iListID)
  439. {
  440.     DbgLog((LOG_TRACE, 5, TEXT("CAudioLangDlg::MakeAudioStreamList(0x%lx, %d)"), 
  441.         hDlg, iListID)) ;
  442.  
  443.     if (Uninitialized == g_App.m_pDvdCore->GetState())
  444.     {
  445.         DbgLog((LOG_ERROR, 0, TEXT("WARNING: DvdCore not initialized yet!"))) ;
  446.         return 0 ;
  447.     }
  448.  
  449.     // First clear the list box of all audio stream names
  450.     SendDlgItemMessage(hDlg, iListID, CB_RESETCONTENT, static_cast<WPARAM>(0), 
  451.         static_cast<LPARAM>(0)) ;
  452.  
  453.     // Find out how many audio streams are there and what's the current lang.
  454.     // This is our chance to find out if someone changed the audio lang through 
  455.     // DVD menu so that we can synch up our audio stream value now.
  456.     HRESULT hr = g_App.m_pDvdCore->m_pIDvdI2->GetCurrentAudio(&m_ulNumLang, &m_ulAudioStream) ;
  457.     if (FAILED(hr))
  458.     {
  459.         MessageBox(m_hWnd, TEXT("Not ready to find language information"), TEXT("Warning"), MB_OK) ;
  460.         return 0 ;
  461.     }
  462.  
  463.     LCID lcid;
  464.     TCHAR szLang[50];
  465.  
  466.     // Add all of the streams to the dialog box
  467.     for (ULONG ulStream = 0; ulStream < m_ulNumLang; ulStream++)
  468.     {
  469.         if (FAILED(g_App.m_pDvdCore->m_pIDvdI2->GetAudioLanguage(ulStream, &lcid)))
  470.         {
  471.             DbgLog((LOG_ERROR, 0, TEXT("WARNING: GetAudioLanguage Failed!"))) ;
  472.             return 0 ;
  473.         }
  474.  
  475.         if (0 == lcid || 0 == GetLocaleInfo(lcid, LOCALE_SLANGUAGE, szLang, sizeof(szLang))) 
  476.         // 0 is the failure code for GetLocaleInfo
  477.         {
  478.             GetAudioLang(ulStream, szLang, sizeof(szLang));
  479.         }
  480.  
  481.         // Add the language to the listbox
  482.         SendDlgItemMessage(hDlg, iListID, CB_ADDSTRING, static_cast<WPARAM>(0),
  483.             reinterpret_cast<LPARAM>(static_cast<PVOID>(szLang)));
  484.     }
  485.  
  486.     // set the current stream as the selected item
  487.     if (m_ulNumLang > 0) // if there are any streams
  488.     {
  489.         int iRes = SendDlgItemMessage(hDlg, iListID, CB_SETCURSEL, 
  490.             static_cast<WPARAM>(m_ulAudioStream), static_cast<LPARAM>(0)) ;
  491.         if (CB_ERR == iRes)
  492.             DbgLog((LOG_ERROR, 1, 
  493.             TEXT("WARNING: Couldn't set %ld as selected audio stream ID (Error %d)"),
  494.             m_ulAudioStream, iRes)) ;
  495.     }
  496.  
  497.     return m_ulNumLang;
  498. }
  499.  
  500.  
  501. //------------------------------------------------------------------------------
  502. // Name: CAudioLangDlg::GetAudioLang()
  503. // Desc: This method gets the LCID language code and looks up the audio
  504. //       language based on that.  This is to get around problems with Win95 where
  505. //       not all LCID's are recognized.
  506. //------------------------------------------------------------------------------
  507.  
  508. bool CAudioLangDlg::GetAudioLang(ULONG ulStream, TCHAR * buffer, int iBufLen)
  509. {
  510.     DbgLog((LOG_TRACE, 5, TEXT("CAudioLangDlg::GetAudioLang()"))) ;
  511.  
  512.     DVD_AudioAttributes AudATR ;
  513.     LANGINFO * pSPATR = reinterpret_cast<LANGINFO *>(&AudATR);
  514.     HRESULT hr = g_App.m_pDvdCore->m_pIDvdI2->GetAudioAttributes(ulStream, &AudATR);
  515.     ASSERT(SUCCEEDED(hr)) ;
  516.     return g_App.m_pLangLookup->GetLangString(AudATR.Language, buffer, iBufLen) ;
  517. }
  518.  
  519.  
  520.  
  521.  
  522. //------------------------------------------------------------------------------
  523. // CAngleDlg
  524. //------------------------------------------------------------------------------
  525.  
  526.  
  527. //------------------------------------------------------------------------------
  528. // Name: CAngleDlg::CAngleDlg()
  529. // Desc: This method is the constructor for CAngleDlg
  530. //------------------------------------------------------------------------------
  531.  
  532. CAngleDlg::CAngleDlg(HINSTANCE hInstance, HWND hWnd):
  533.     m_hInstance(hInstance), m_hWnd(hWnd)
  534. {
  535.     DbgLog((LOG_TRACE, 5, TEXT("CAngleDlg::CAngleDlg()"))) ;
  536. }
  537.  
  538.  
  539. //------------------------------------------------------------------------------
  540. // Name: CAngleDlg::CAngleDlg()
  541. // Desc: This method is the destructor for CAngleDlg
  542. //------------------------------------------------------------------------------
  543.  
  544. CAngleDlg::~CAngleDlg()
  545. {
  546.     DbgLog((LOG_TRACE, 5, TEXT("CAngleDlg::~CAngleDlg()"))) ;
  547. }
  548.  
  549.  
  550. //------------------------------------------------------------------------------
  551. // Name: CAngleDlg::DoModal()
  552. // Desc: This method creates the dialog and handles its return value.
  553. //------------------------------------------------------------------------------
  554.  
  555. bool CAngleDlg::DoModal()
  556. {
  557.     DbgLog((LOG_TRACE, 5, TEXT("CAngleDlg::DoModal()"))) ;
  558.  
  559.     int retVal;
  560.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_ANGLEDLG), m_hWnd, 
  561.         CAngleDlg::AngleDlgProc, reinterpret_cast<LPARAM>(this));
  562.     if (TRUE == retVal)
  563.     {
  564.         return true;
  565.     }
  566.     else return false;
  567. }
  568.  
  569.  
  570. //------------------------------------------------------------------------------
  571. // Name: CAngleDlg::AngleDlgProc()
  572. // Desc: This is the Dialog MessageProc for the angle selection dialog
  573. //------------------------------------------------------------------------------
  574.  
  575. BOOL CALLBACK CAngleDlg::AngleDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  576. {
  577.     static CAngleDlg * pThis; 
  578.  
  579.     switch (message)
  580.     {
  581.     case WM_INITDIALOG:
  582.         pThis = reinterpret_cast<CAngleDlg *>(lParam); // get a pointer to the calling object
  583.         if (0 < pThis->MakeAngleList(hDlg, IDC_ANGLE))
  584.             return TRUE;
  585.         else
  586.         {
  587.              EndDialog(hDlg, FALSE);
  588.             return FALSE;
  589.         }
  590.  
  591.     case WM_COMMAND:
  592.         switch (LOWORD(wParam))
  593.         {
  594.         case IDOK:
  595.             {
  596.             HRESULT hr;
  597.  
  598.             // Set the Angle specific by the user
  599.             LONG lAngle;
  600.             lAngle = SendDlgItemMessage(hDlg, IDC_ANGLE, CB_GETCURSEL, 
  601.                 static_cast<WPARAM>(0), static_cast<LPARAM>(0));
  602.             lAngle += 1; // angles start count at 1 so we have to account for that
  603.             if (CB_ERR == lAngle)
  604.                 DbgLog((LOG_ERROR, 1, 
  605.                 TEXT("WARNING: Couldn't get selected angle ID (Error %d)"), lAngle)) ;
  606.             else
  607.             {
  608.                 pThis->m_ulAngle = lAngle;
  609.                 hr = g_App.m_pDvdCore->m_pIDvdC2->SelectAngle(pThis->m_ulAngle, 0, NULL) ;
  610.                 ASSERT(SUCCEEDED(hr)) ;
  611.             }
  612.  
  613.             } // end of case brackets
  614.  
  615.             EndDialog(hDlg, TRUE);
  616.             return TRUE;
  617.  
  618.         case IDCANCEL:
  619.             EndDialog(hDlg, FALSE);
  620.             return TRUE;
  621.         }
  622.         break;
  623.     }
  624.     return FALSE;
  625. }
  626.  
  627.  
  628. //------------------------------------------------------------------------------
  629. // Name: CAngleDlg::MakeAngleList()
  630. // Desc: This method will populate our dialog box and return the number of angles
  631. //       on this disc.
  632. //------------------------------------------------------------------------------
  633.  
  634. int CAngleDlg::MakeAngleList(HWND hDlg, int iListID)
  635. {
  636.     DbgLog((LOG_TRACE, 5, TEXT("CAngleDlg::MakeAngleList(0x%lx, %d)"), 
  637.         hDlg, iListID)) ;
  638.  
  639.     if (Uninitialized == g_App.m_pDvdCore->GetState())
  640.     {
  641.         DbgLog((LOG_ERROR, 0, TEXT("WARNING: DvdCore not initialized yet!"))) ;
  642.         return 0 ;
  643.     }
  644.  
  645.     // First clear the list box of all angle names
  646.     SendDlgItemMessage(hDlg, iListID, CB_RESETCONTENT, static_cast<WPARAM>(0), 
  647.         static_cast<LPARAM>(0)) ;
  648.  
  649.     // Find out how many angles are there and what is the current angle.
  650.     // This is our chance to find out if someone changed the angle through 
  651.     // DVD menu so that we can synch up our angle value now.
  652.     HRESULT hr = g_App.m_pDvdCore->m_pIDvdI2->GetCurrentAngle(&m_ulNumAngle, &m_ulAngle) ;
  653.     if (FAILED(hr))
  654.     {
  655.         MessageBox(m_hWnd, TEXT("Not ready to find angle information"), TEXT("Warning"), MB_OK) ;
  656.         return 0 ;
  657.     }
  658.  
  659.     TCHAR szAngle[50];
  660.  
  661.     // Add all of the angles to the dialog box
  662.     for (ULONG ulAngle = 1; ulAngle <= m_ulNumAngle; ulAngle++) // angles start at 1
  663.     {
  664.         wsprintf(szAngle, TEXT("Angle %u"), ulAngle);
  665.  
  666.         // Add the language to the listbox
  667.         SendDlgItemMessage(hDlg, iListID, CB_ADDSTRING, static_cast<WPARAM>(0),
  668.             reinterpret_cast<LPARAM>(static_cast<PVOID>(szAngle)));
  669.     }
  670.  
  671.     // set the current angle as the selected item
  672.     if (m_ulNumAngle > 0) // if there are any angles
  673.     {
  674.         // angles start at 1 so we have to subtract 1 from the angle number to match the 
  675.         // correct angle
  676.         int iRes = SendDlgItemMessage(hDlg, iListID, CB_SETCURSEL, 
  677.             static_cast<WPARAM>(m_ulAngle - 1), static_cast<LPARAM>(0)) ;  
  678.         if (CB_ERR == iRes)
  679.             DbgLog((LOG_ERROR, 1, 
  680.             TEXT("WARNING: Couldn't set %ld as selected angle ID (Error %d)"),
  681.             m_ulAngle, iRes)) ;
  682.     }
  683.  
  684.     return m_ulNumAngle;
  685. }
  686.  
  687.  
  688.  
  689.  
  690. //------------------------------------------------------------------------------
  691. // CChapterDlg
  692. //------------------------------------------------------------------------------
  693.  
  694.  
  695. //------------------------------------------------------------------------------
  696. // Name: CChapterDlg::CChapterDlg()
  697. // Desc: This method is the constructor for CChapterDlg
  698. //------------------------------------------------------------------------------
  699.  
  700. CChapterDlg::CChapterDlg(HINSTANCE hInstance, HWND hWnd):
  701.     m_hInstance(hInstance), m_hWnd(hWnd)
  702. {
  703.     DbgLog((LOG_TRACE, 5, TEXT("CChapterDlg::CChapterDlg()"))) ;
  704.  
  705.     m_ulChapter = 1; // default value
  706. }
  707.  
  708.  
  709. //------------------------------------------------------------------------------
  710. // Name: CChapterDlg::CChapterDlg()
  711. // Desc: This method is the destructor for CChapterDlg
  712. //------------------------------------------------------------------------------
  713.  
  714. CChapterDlg::~CChapterDlg()
  715. {
  716.     DbgLog((LOG_TRACE, 5, TEXT("CChapterDlg::~CChapterDlg()"))) ;
  717. }
  718.  
  719.  
  720. //------------------------------------------------------------------------------
  721. // Name: CChapterDlg::DoModal()
  722. // Desc: This method creates the dialog and handles its return value.
  723. //------------------------------------------------------------------------------
  724.  
  725. bool CChapterDlg::DoModal()
  726. {
  727.     DbgLog((LOG_TRACE, 5, TEXT("CChapterDlg::DoModal()"))) ;
  728.  
  729.     int retVal;
  730.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_CHAPTERDLG), m_hWnd, 
  731.         CChapterDlg::ChapterDlgProc, reinterpret_cast<LPARAM>(this));
  732.     if (TRUE == retVal)
  733.     {
  734.         return true;
  735.     }
  736.     else return false;
  737. }
  738.  
  739.  
  740. //------------------------------------------------------------------------------
  741. // Name: CChapterDlg::ChapterDlgProc()
  742. // Desc: This is the Dialog MessageProc for the Chapter selection dialog
  743. //------------------------------------------------------------------------------
  744.  
  745. BOOL CALLBACK CChapterDlg::ChapterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  746. {
  747.     static CChapterDlg * pThis; 
  748.  
  749.     switch (message)
  750.     {
  751.     case WM_INITDIALOG:
  752.         {
  753.         pThis = reinterpret_cast<CChapterDlg *>(lParam); // get a pointer to the calling object
  754.         
  755.         // set default value
  756.         TCHAR buf[10];
  757.         wsprintf(buf, TEXT("%u"), pThis->m_ulChapter); 
  758.         SetDlgItemText(hDlg, IDC_PLAYCHAPTER, buf);
  759.         
  760.         //set up spin control
  761.         HWND hEBox = GetDlgItem(hDlg, IDC_PLAYCHAPTER);
  762.         CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, 
  763.             10, 10, 50, 50, hDlg, ID_SPINCONTROL, pThis->m_hInstance, hEBox, 999, 1, 1);
  764.         return TRUE;
  765.         }
  766.  
  767.     case WM_COMMAND:
  768.         switch (LOWORD(wParam))
  769.         {
  770.         case IDOK:
  771.             {
  772.             // Set the Chapter specified by the user
  773.             TCHAR buf[10];
  774.             GetDlgItemText(hDlg, IDC_PLAYCHAPTER, buf, sizeof(buf)/sizeof(TCHAR));
  775.             //sscanf(buf, TEXT("%u"), pThis->m_ulChapter);
  776.             pThis->m_ulChapter = atoi(buf);
  777.             } // end of case brackets
  778.  
  779.             EndDialog(hDlg, TRUE);
  780.             return TRUE;
  781.  
  782.         case IDCANCEL:
  783.             EndDialog(hDlg, FALSE);
  784.             return TRUE;
  785.         }
  786.         break;
  787.     }
  788.     return FALSE;
  789. }
  790.  
  791.  
  792.  
  793.  
  794. //------------------------------------------------------------------------------
  795. // CTitleDlg
  796. //------------------------------------------------------------------------------
  797.  
  798.  
  799. //------------------------------------------------------------------------------
  800. // Name: CTitleDlg::CTitleDlg()
  801. // Desc: This method is the constructor for CTitleDlg
  802. //------------------------------------------------------------------------------
  803.  
  804. CTitleDlg::CTitleDlg(HINSTANCE hInstance, HWND hWnd):
  805.     m_hInstance(hInstance), m_hWnd(hWnd)
  806. {
  807.     DbgLog((LOG_TRACE, 5, TEXT("CTitleDlg::CTitleDlg"))) ;
  808.  
  809.     m_ulTitle = 1; // default value
  810.     m_ulChapter = 1; 
  811. }
  812.  
  813.  
  814. //------------------------------------------------------------------------------
  815. // Name: CTitleDlg::CTitleDlg()
  816. // Desc: This method is the destructor for CTitleDlg
  817. //------------------------------------------------------------------------------
  818.  
  819. CTitleDlg::~CTitleDlg()
  820. {
  821.     DbgLog((LOG_TRACE, 5, TEXT("CTitleDlg::~CTitleDlg"))) ;
  822. }
  823.  
  824.  
  825. //------------------------------------------------------------------------------
  826. // Name: CTitleDlg::DoModal()
  827. // Desc: This method creates the dialog and handles its return value.
  828. //------------------------------------------------------------------------------
  829.  
  830. bool CTitleDlg::DoModal()
  831. {
  832.     DbgLog((LOG_TRACE, 5, TEXT("CTitleDlg::DoModal"))) ;
  833.  
  834.     int retVal;
  835.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_TITLEDLG), m_hWnd, 
  836.         CTitleDlg::TitleDlgProc, reinterpret_cast<LPARAM>(this));
  837.     if (TRUE == retVal)
  838.     {
  839.         return true;
  840.     }
  841.     else return false;
  842. }
  843.  
  844.  
  845. //------------------------------------------------------------------------------
  846. // Name: CTitleDlg::TitleDlgProc()
  847. // Desc: This is the Dialog MessageProc for the Title selection dialog
  848. //------------------------------------------------------------------------------
  849.  
  850. BOOL CALLBACK CTitleDlg::TitleDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  851. {
  852.     static CTitleDlg * pThis; 
  853.  
  854.     switch (message)
  855.     {
  856.     case WM_INITDIALOG:
  857.         {
  858.         pThis = reinterpret_cast<CTitleDlg *>(lParam); // get a pointer to the calling object
  859.         
  860.         // set default values
  861.         TCHAR buf[10];
  862.         wsprintf(buf, TEXT("%u"), pThis->m_ulTitle); 
  863.         SetDlgItemText(hDlg, IDC_PLAYCHAPTER, buf);
  864.         wsprintf(buf, TEXT("%u"), pThis->m_ulChapter); 
  865.         SetDlgItemText(hDlg, IDC_PLAYCHAPTER, buf);
  866.         
  867.         //set up spin control
  868.         HWND hEBox = GetDlgItem(hDlg, IDC_PLAYCHAPTER);
  869.         CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, 
  870.             10, 10, 50, 50, hDlg, ID_SPINCONTROL, pThis->m_hInstance, hEBox, 999, 1, 1);
  871.         hEBox = GetDlgItem(hDlg, IDC_PLAYTITLE);
  872.         CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, 
  873.             10, 10, 50, 50, hDlg, ID_SPINCONTROL, pThis->m_hInstance, hEBox, 99, 1, 1);
  874.         return TRUE;
  875.         }
  876.  
  877.     case WM_COMMAND:
  878.         switch (LOWORD(wParam))
  879.         {
  880.         case IDOK:
  881.             {
  882.             // Set the Title specified by the user
  883.             TCHAR buf[10];
  884.             GetDlgItemText(hDlg, IDC_PLAYCHAPTER, buf, sizeof(buf)/sizeof(TCHAR));
  885.             pThis->m_ulChapter = atoi(buf);
  886.             GetDlgItemText(hDlg, IDC_PLAYTITLE, buf, sizeof(buf)/sizeof(TCHAR));
  887.             pThis->m_ulTitle = atoi(buf);
  888.             } // end of case brackets
  889.  
  890.             EndDialog(hDlg, TRUE);
  891.             return TRUE;
  892.  
  893.         case IDCANCEL:
  894.             EndDialog(hDlg, FALSE);
  895.             return TRUE;
  896.         }
  897.         break;
  898.     }
  899.     return FALSE;
  900. }
  901.  
  902.  
  903.  
  904.  
  905. //------------------------------------------------------------------------------
  906. // CTimeDlg
  907. //------------------------------------------------------------------------------
  908.  
  909.  
  910. //------------------------------------------------------------------------------
  911. // Name: CTimeDlg::CTimeDlg()
  912. // Desc: This method is the constructor for CTimeDlg
  913. //------------------------------------------------------------------------------
  914.  
  915. CTimeDlg::CTimeDlg(HINSTANCE hInstance, HWND hWnd):
  916.     m_hInstance(hInstance), m_hWnd(hWnd)
  917. {
  918.     DbgLog((LOG_TRACE, 5, TEXT("CTimeDlg::CTimeDlg"))) ;
  919.  
  920.     ZeroMemory(&m_Time, sizeof(m_Time));
  921. }
  922.  
  923.  
  924. //------------------------------------------------------------------------------
  925. // Name: CTimeDlg::CTimeDlg()
  926. // Desc: This method is the destructor for CTimeDlg
  927. //------------------------------------------------------------------------------
  928.  
  929. CTimeDlg::~CTimeDlg()
  930. {
  931.     DbgLog((LOG_TRACE, 5, TEXT("CTimeDlg::~CTimeDlg"))) ;
  932. }
  933.  
  934.  
  935. //------------------------------------------------------------------------------
  936. // Name: CTimeDlg::DoModal()
  937. // Desc: This method creates the dialog and handles its return value.
  938. //------------------------------------------------------------------------------
  939.  
  940. bool CTimeDlg::DoModal()
  941. {
  942.     DbgLog((LOG_TRACE, 5, TEXT("CTimeDlg::DoModal"))) ;
  943.  
  944.     int retVal;
  945.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_TIMEDLG), m_hWnd, 
  946.         CTimeDlg::TimeDlgProc, reinterpret_cast<LPARAM>(this));
  947.     if (TRUE == retVal)
  948.     {
  949.         return true;
  950.     }
  951.     else return false;
  952. }
  953.  
  954.  
  955. //------------------------------------------------------------------------------
  956. // Name: CTimeDlg::TimeDlgProc()
  957. // Desc: This is the Dialog MessageProc for the Time selection dialog
  958. //------------------------------------------------------------------------------
  959.  
  960. BOOL CALLBACK CTimeDlg::TimeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  961. {
  962.     static CTimeDlg * pThis; 
  963.  
  964.     switch (message)
  965.     {
  966.     case WM_INITDIALOG:
  967.         {
  968.         pThis = reinterpret_cast<CTimeDlg *>(lParam); // get a pointer to the calling object
  969.         
  970.         // set default values
  971.         TCHAR buf[10];
  972.         wsprintf(buf, TEXT("%u"), pThis->m_Time.bHours); 
  973.         SetDlgItemText(hDlg, IDC_HOURS, buf);
  974.         wsprintf(buf, TEXT("%u"), pThis->m_Time.bMinutes); 
  975.         SetDlgItemText(hDlg, IDC_MINUTES, buf);
  976.         wsprintf(buf, TEXT("%u"), pThis->m_Time.bSeconds); 
  977.         SetDlgItemText(hDlg, IDC_SECONDS, buf);
  978.         
  979.         //set up spin controls
  980.         HWND hEBox = GetDlgItem(hDlg, IDC_HOURS);
  981.         CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, 
  982.             10, 10, 50, 50, hDlg, ID_SPINCONTROL, pThis->m_hInstance, hEBox, 99, 0, 
  983.             pThis->m_Time.bHours);
  984.         hEBox = GetDlgItem(hDlg, IDC_MINUTES);
  985.         CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, 
  986.             10, 10, 50, 50, hDlg, ID_SPINCONTROL, pThis->m_hInstance, hEBox, 60, 0, 
  987.             pThis->m_Time.bMinutes);
  988.         hEBox = GetDlgItem(hDlg, IDC_SECONDS);
  989.         CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, 
  990.             10, 10, 50, 50, hDlg, ID_SPINCONTROL, pThis->m_hInstance, hEBox, 60, 0, 
  991.             pThis->m_Time.bSeconds);
  992.         return TRUE;
  993.         }
  994.  
  995.     case WM_COMMAND:
  996.         switch (LOWORD(wParam))
  997.         {
  998.         case IDOK:
  999.             {
  1000.             // Set the Time specified by the user
  1001.             TCHAR buf[10];
  1002.             GetDlgItemText(hDlg, IDC_HOURS, buf, sizeof(buf)/sizeof(TCHAR));
  1003.             pThis->m_Time.bHours = (BYTE) atoi(buf);
  1004.             GetDlgItemText(hDlg, IDC_MINUTES, buf, sizeof(buf)/sizeof(TCHAR));
  1005.             pThis->m_Time.bMinutes = (BYTE) atoi(buf);
  1006.             GetDlgItemText(hDlg, IDC_SECONDS, buf, sizeof(buf)/sizeof(TCHAR));
  1007.             pThis->m_Time.bSeconds = (BYTE) atoi(buf);
  1008.             } // end of case brackets
  1009.  
  1010.             EndDialog(hDlg, TRUE);
  1011.             return TRUE;
  1012.  
  1013.         case IDCANCEL:
  1014.             EndDialog(hDlg, FALSE);
  1015.             return TRUE;
  1016.         }
  1017.         break;
  1018.     }
  1019.     return FALSE;
  1020. }
  1021.  
  1022.  
  1023.  
  1024.  
  1025. //------------------------------------------------------------------------------
  1026. // CKaraokeDlg
  1027. //------------------------------------------------------------------------------
  1028.  
  1029.  
  1030. //------------------------------------------------------------------------------
  1031. // Name: CKaraokeDlg::CKaraokeDlg()
  1032. // Desc: This method is the constructor for CKaraokeDlg
  1033. //------------------------------------------------------------------------------
  1034.  
  1035. CKaraokeDlg::CKaraokeDlg(HINSTANCE hInstance, HWND hWnd):
  1036.     m_hInstance(hInstance), m_hWnd(hWnd)
  1037. {
  1038.     DbgLog((LOG_TRACE, 5, TEXT("CKaraokeDlg::CKaraokeDlg"))) ;
  1039.  
  1040.     //ZeroMemory(&m_Karaoke, sizeof(m_Karaoke));
  1041. }
  1042.  
  1043.  
  1044. //------------------------------------------------------------------------------
  1045. // Name: CKaraokeDlg::CKaraokeDlg()
  1046. // Desc: This method is the destructor for CKaraokeDlg
  1047. //------------------------------------------------------------------------------
  1048.  
  1049. CKaraokeDlg::~CKaraokeDlg()
  1050. {
  1051.     DbgLog((LOG_TRACE, 5, TEXT("CKaraokeDlg::~CKaraokeDlg"))) ;
  1052. }
  1053.  
  1054.  
  1055. //------------------------------------------------------------------------------
  1056. // Name: CKaraokeDlg::DoModal()
  1057. // Desc: This method establishes that there is karaoke data in the current audio
  1058. //       stream.  If there is, it populates the dialog box and displays it.  It also
  1059. //       handles the mixing.  In a real application, it might be better to have a function
  1060. //       in CDvdCore which does the mixing, but we will violate encapsulation here to
  1061. //       make it easier to understand.
  1062. //
  1063. //       This method mixes a given channel into both speakers.  This can be controlled on 
  1064. //       a per-speaker basis if so desired. 
  1065. //------------------------------------------------------------------------------
  1066.  
  1067. bool CKaraokeDlg::DoModal()
  1068. {
  1069.     DbgLog((LOG_TRACE, 5, TEXT("CKaraokeDlg::DoModal"))) ;
  1070.  
  1071.     // first we should make sure that there is Karaoke Data available
  1072.     HRESULT hr;
  1073.  
  1074.     DVD_AudioAttributes audioAtr;
  1075.     hr = g_App.m_pDvdCore->m_pIDvdI2->GetAudioAttributes(DVD_STREAM_DATA_CURRENT, &audioAtr);
  1076.     if (FAILED(hr))
  1077.     {
  1078.         MessageBox(m_hWnd, TEXT("GetAudioAttributes Failed"), TEXT("Error!"), MB_OK);
  1079.         return false;
  1080.     }
  1081.  
  1082.     if( DVD_AudioMode_Karaoke != audioAtr.AppMode ) 
  1083.     {
  1084.         MessageBox(m_hWnd, TEXT("There is no Karaoke Data In This Audio Stream"), 
  1085.             TEXT("Error!"), MB_OK);
  1086.         return false;
  1087.     }
  1088.  
  1089.     // if we get here, we are in a karaoke section
  1090.     DVD_KaraokeAttributes karaokeAtr;
  1091.     hr = g_App.m_pDvdCore->m_pIDvdI2->GetKaraokeAttributes(DVD_STREAM_DATA_CURRENT, &karaokeAtr );
  1092.     if (FAILED(hr))
  1093.     {
  1094.         MessageBox(m_hWnd, TEXT("GetKaraokeAttributes Failed"), TEXT("Error!"), MB_OK);
  1095.         return false;
  1096.     }
  1097.  
  1098.     // assign names to the various channels.  Channels 0 and 1 are restricted
  1099.     m_pszChannel2 = KaraokeAsStr(karaokeAtr.wChannelContents[2]);
  1100.     m_pszChannel3 = KaraokeAsStr(karaokeAtr.wChannelContents[3]);
  1101.     m_pszChannel4 = KaraokeAsStr(karaokeAtr.wChannelContents[4]);
  1102.  
  1103.     int retVal;
  1104.     retVal = DialogBoxParam(m_hInstance, MAKEINTRESOURCE(IDD_KARAOKEDLG), m_hWnd, 
  1105.         CKaraokeDlg::KaraokeDlgProc, reinterpret_cast<LPARAM>(this));
  1106.     if (FALSE == retVal)
  1107.     {
  1108.         return false;
  1109.     }
  1110.     // else the user clicked OK
  1111.  
  1112.     ULONG ulMixFlags = NULL; // Initialize the flags variable to be blank
  1113.     INT chkChannel2, chkChannel3, chkChannel4;
  1114.  
  1115.     chkChannel2 = SendDlgItemMessage(m_hWnd, IDC_CHANNEL2, BM_GETCHECK, 0, 0);
  1116.     chkChannel3 = SendDlgItemMessage(m_hWnd, IDC_CHANNEL3, BM_GETCHECK, 0, 0);
  1117.     chkChannel4 = SendDlgItemMessage(m_hWnd, IDC_CHANNEL4, BM_GETCHECK, 0, 0);
  1118.  
  1119.     if (BST_CHECKED == chkChannel2)
  1120.     {
  1121.         ulMixFlags |= DVD_Mix_3to0;
  1122.         ulMixFlags |= DVD_Mix_3to1;
  1123.     }
  1124.     if (BST_CHECKED == chkChannel3)
  1125.     {
  1126.         ulMixFlags |= DVD_Mix_4to0;
  1127.         ulMixFlags |= DVD_Mix_4to1;
  1128.     }
  1129.     if (BST_CHECKED == chkChannel4)
  1130.     {
  1131.         ulMixFlags |= DVD_Mix_Lto0;
  1132.         ulMixFlags |= DVD_Mix_Lto1;
  1133.     }
  1134.  
  1135.     hr = g_App.m_pDvdCore->m_pIDvdC2->SelectKaraokeAudioPresentationMode(ulMixFlags);
  1136.     if (FAILED(hr))
  1137.     {
  1138.         MessageBox(m_hWnd, TEXT("SelectKaraokeAudioPresentationMode Failed"), TEXT("Error!"), MB_OK);
  1139.         return false;
  1140.     }
  1141.     else return true;
  1142. }
  1143.  
  1144.  
  1145. //------------------------------------------------------------------------------
  1146. // Name: CKaraokeDlg::KaraokeDlgProc()
  1147. // Desc: This is the Dialog MessageProc for the Karaoke selection dialog
  1148. //------------------------------------------------------------------------------
  1149.  
  1150. BOOL CALLBACK CKaraokeDlg::KaraokeDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1151. {
  1152.     static CKaraokeDlg * pThis; 
  1153.  
  1154.     switch (message)
  1155.     {
  1156.     case WM_INITDIALOG:
  1157.         {
  1158.         pThis = reinterpret_cast<CKaraokeDlg *>(lParam); // get a pointer to the calling object
  1159.         SetDlgItemText(hDlg, IDC_CHANNEL2, pThis->m_pszChannel2);
  1160.         SetDlgItemText(hDlg, IDC_CHANNEL3, pThis->m_pszChannel3);
  1161.         SetDlgItemText(hDlg, IDC_CHANNEL4, pThis->m_pszChannel4);
  1162.       return TRUE;
  1163.         }
  1164.  
  1165.     case WM_COMMAND:
  1166.         switch (LOWORD(wParam))
  1167.         {
  1168.         case IDOK:
  1169.             {
  1170.             } // end of case brackets
  1171.  
  1172.             EndDialog(hDlg, TRUE);
  1173.             return TRUE;
  1174.  
  1175.         case IDCANCEL:
  1176.             EndDialog(hDlg, FALSE);
  1177.             return TRUE;
  1178.         }
  1179.         break;
  1180.     }
  1181.     return FALSE;
  1182. }
  1183.  
  1184.  
  1185.