Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

518 lines
16 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
  2. /*************************************************************/
  3. /* Name: callback.cpp
  4. /* Description:
  5. /*************************************************************/
  6. #include "stdafx.h"
  7. #include <streams.h>
  8. #include <stdio.h>
  9. #include "COptDlg.h"
  10. const TCHAR g_szRegistryKey[] = TEXT("Software\\Microsoft\\Multimedia\\DVD");
  11. /*************************************************************/
  12. /* Name: GetRegistryDword
  13. /* Description:
  14. /*************************************************************/
  15. BOOL GetRegistryDword(const TCHAR *pKey, DWORD* dwRet, DWORD dwDefault)
  16. {
  17. HKEY hKey;
  18. LONG lRet;
  19. *dwRet = dwDefault;
  20. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szRegistryKey, 0, KEY_QUERY_VALUE, &hKey);
  21. if (lRet == ERROR_SUCCESS) {
  22. DWORD dwType, dwLen;
  23. dwLen = sizeof(DWORD);
  24. if (ERROR_SUCCESS != RegQueryValueEx(hKey, pKey, NULL, &dwType, (LPBYTE)dwRet, &dwLen))
  25. *dwRet = dwDefault;
  26. RegCloseKey(hKey);
  27. }
  28. return (lRet == ERROR_SUCCESS);
  29. }
  30. /*************************************************************/
  31. /* Name: GetRegistryString
  32. /* Description:
  33. /*************************************************************/
  34. BOOL GetRegistryString(const TCHAR *pKey, TCHAR* szRet, DWORD* dwLen, TCHAR* szDefault)
  35. {
  36. HKEY hKey;
  37. LONG lRet;
  38. lstrcpy(szRet, szDefault);
  39. lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szRegistryKey, 0, KEY_QUERY_VALUE, &hKey);
  40. if (lRet == ERROR_SUCCESS) {
  41. DWORD dwType;
  42. if (ERROR_SUCCESS != RegQueryValueEx(hKey, pKey, NULL, &dwType, (LPBYTE)szRet, dwLen)) {
  43. lstrcpy(szRet, szDefault);
  44. *dwLen = 0;
  45. }
  46. *dwLen = *dwLen/sizeof(TCHAR);
  47. RegCloseKey(hKey);
  48. }
  49. return (lRet == ERROR_SUCCESS);
  50. }
  51. /*************************************************************/
  52. /* Name: LoadBSTRFromRes
  53. /* Description: load string from resource and convert to wchar
  54. /* if necessary, return the BSTR pointer if successful, NULL
  55. /* otherwise
  56. /*************************************************************/
  57. CComBSTR LoadBSTRFromRes(DWORD resId)
  58. {
  59. CComBSTR pBSTR;
  60. if (pBSTR.LoadString( _Module.GetModuleInstance(), resId))
  61. return pBSTR;
  62. else
  63. return NULL;
  64. }
  65. /*************************************************************/
  66. /* Name: LoadStringFromRes
  67. /* Description: load a string from resource
  68. /*************************************************************/
  69. LPTSTR LoadStringFromRes(DWORD redId)
  70. {
  71. TCHAR *string = new TCHAR[MAX_PATH];
  72. LoadString(_Module.GetModuleInstance(), redId, string, MAX_PATH);
  73. return string;
  74. }
  75. /*************************************************************/
  76. /* Function: lstrlenWInternal */
  77. /*************************************************************/
  78. int WINAPI lstrlenWInternal(LPCWSTR lpString){
  79. int length = 0;
  80. while (*lpString++ != L'\0')
  81. length++;
  82. return length;
  83. }/* end of function lstrlenWInternal */
  84. /*************************************************************/
  85. /* Name: chapSrch_OnInitDialog
  86. /* Description: OnInitDialog for Chapter Search page
  87. /*************************************************************/
  88. HRESULT COptionsDlg::chapSrch_OnInitDialog(HWND hwndDlg)
  89. {
  90. HWND titleWnd = ::GetDlgItem(hwndDlg, IDC_LIST_TITLES);
  91. HWND chapWnd = ::GetDlgItem(hwndDlg, IDC_LIST_CHAPS);
  92. if (!titleWnd || !chapWnd)
  93. return S_FALSE;
  94. ::EnableWindow(titleWnd, TRUE);
  95. ::EnableWindow(chapWnd, TRUE);
  96. ATLTRACE(TEXT("WM_INITDIALOG\n"));
  97. HRESULT hr = S_OK;
  98. try {
  99. LONG nTitles;
  100. hr = m_pDvd->get_TitlesAvailable(&nTitles);
  101. if (FAILED(hr))
  102. throw(hr);
  103. LONG currentTitle = 0;
  104. HRESULT hr = m_pDvd->get_CurrentTitle(&currentTitle);
  105. for (long i=0; i<nTitles; i++) {
  106. TCHAR name[32];
  107. LPTSTR szTitleNo = LoadStringFromRes(IDS_INI_TITLE_NO);
  108. wsprintf(name, szTitleNo, i+1);
  109. delete[] szTitleNo;
  110. ::SendMessage(titleWnd, LB_INSERTSTRING, (UINT)-1, (LPARAM)name);
  111. if (i+1 == currentTitle) {
  112. ::SendMessage(titleWnd, LB_SETCURSEL, (WPARAM)i, 0);
  113. }
  114. }
  115. chapSrch_InitChapList(hwndDlg);
  116. }
  117. catch (HRESULT hr) {
  118. ::EnableWindow(titleWnd, FALSE);
  119. ::EnableWindow(chapWnd, FALSE);
  120. return hr;
  121. }
  122. return hr;
  123. }
  124. /*************************************************************/
  125. /* Name: chapSrch_InitChapList
  126. /* Description:
  127. /*************************************************************/
  128. HRESULT COptionsDlg::chapSrch_InitChapList(HWND hwndDlg)
  129. {
  130. HWND titleWnd = ::GetDlgItem(hwndDlg, IDC_LIST_TITLES);
  131. HWND chapWnd = ::GetDlgItem(hwndDlg, IDC_LIST_CHAPS);
  132. if (!titleWnd || !chapWnd)
  133. return S_FALSE;
  134. ::SendMessage(chapWnd, LB_RESETCONTENT, 0, 0);
  135. LONG nTitle = (LONG) ::SendMessage(titleWnd, LB_GETCURSEL, 0, 0);
  136. LONG nChaps;
  137. HRESULT hr = m_pDvd->GetNumberOfChapters(nTitle+1, &nChaps);
  138. if (FAILED(hr))
  139. return hr;
  140. long currentChap = 0;
  141. hr = m_pDvd->get_CurrentChapter(&currentChap);
  142. for (int j=0; j<nChaps; j++) {
  143. TCHAR name[32];
  144. LPTSTR szChapNo = LoadStringFromRes(IDS_INI_CHAP_NO);
  145. wsprintf(name, szChapNo, j+1);
  146. delete[] szChapNo;
  147. ::SendMessage(chapWnd, LB_INSERTSTRING, (UINT)-1, (LPARAM)name);
  148. if (currentChap ==j+1)
  149. ::SendMessage(chapWnd, LB_SETCURSEL, (WPARAM)j, 0);
  150. }
  151. if (LB_ERR == ::SendMessage(chapWnd, LB_GETCURSEL, 0, 0))
  152. ::SendMessage(chapWnd, LB_SETCURSEL, (WPARAM)0, 0);
  153. return hr;
  154. }
  155. /*************************************************************/
  156. /* Name: chapSrch_OnApply
  157. /* Description: OnApply for Chapter Search page
  158. /*************************************************************/
  159. HRESULT COptionsDlg::chapSrch_OnApply(HWND hwndDlg)
  160. {
  161. if (!m_bChapDirty)
  162. return S_OK;
  163. HWND titleWnd = ::GetDlgItem(hwndDlg, IDC_LIST_TITLES);
  164. HWND chapWnd = ::GetDlgItem(hwndDlg, IDC_LIST_CHAPS);
  165. if (!titleWnd || !chapWnd)
  166. return S_FALSE;
  167. LONG nTitle = (LONG) ::SendMessage(titleWnd, LB_GETCURSEL, 0, 0);
  168. LONG nChapter = (LONG) ::SendMessage(chapWnd, LB_GETCURSEL, 0, 0);
  169. if (nTitle == LB_ERR)
  170. return S_FALSE;
  171. HRESULT hr = S_OK;
  172. if (nChapter == LB_ERR) {
  173. hr = m_pDvd->PlayTitle(nTitle+1);
  174. // if Title_Play is inhibited by UOP
  175. if (hr == VFW_E_DVD_OPERATION_INHIBITED) {
  176. hr = m_pDvd->PlayChapterInTitle(nTitle+1, 1);
  177. }
  178. }
  179. else {
  180. hr = m_pDvd->PlayChapterInTitle(nTitle+1, nChapter+1);
  181. } /* end if statement */
  182. // Play at the right speed
  183. if (SUCCEEDED(hr)) {
  184. double playSpeed;
  185. GetDvdOpt()->get_PlaySpeed(&playSpeed);
  186. hr = m_pDvd->PlayForwards(playSpeed, VARIANT_TRUE);
  187. }
  188. else {
  189. DVDMessageBox(hwndDlg, IDS_INI_CANNOT_PLAYCHAP);
  190. }
  191. m_bChapDirty = FALSE;
  192. return hr;
  193. }
  194. /*************************************************************/
  195. /* Name: karaoke_OnInitDialog
  196. /* Description: OnApply for Chapter Search page
  197. /*************************************************************/
  198. HRESULT COptionsDlg::karaoke_OnInitDialog(HWND hwnd)
  199. {
  200. if (!karaoke_HasKaraokeContent())
  201. return E_FAIL;
  202. USES_CONVERSION;
  203. HWND audioList = ::GetDlgItem(hwnd, IDC_AUDIO_LIST);
  204. if (!audioList)
  205. return S_FALSE;
  206. ::SendMessage(audioList, LB_RESETCONTENT, 0, 0);
  207. long nAudio;
  208. HRESULT hr = m_pDvd->get_AudioStreamsAvailable(&nAudio);
  209. if (FAILED(hr) || nAudio == 0)
  210. return S_FALSE;
  211. for (int i=0; i<nAudio; i++) {
  212. CComBSTR strAudio;
  213. hr = m_pDvd->GetAudioLanguage(i, VARIANT_TRUE, &strAudio);
  214. if (SUCCEEDED(hr)) {
  215. ::SendMessage(audioList, LB_INSERTSTRING, (UINT)-1, (LPARAM)OLE2T(strAudio));
  216. ::SysFreeString(strAudio);
  217. }
  218. }
  219. long nCurrentAudio = 0;
  220. m_pDvd->get_CurrentAudioStream(&nCurrentAudio);
  221. ::SendMessage(audioList, LB_SETCURSEL, (WPARAM)nCurrentAudio, 0);
  222. karaoke_InitChannelList(hwnd);
  223. return S_OK;
  224. }
  225. /*************************************************************/
  226. /* Name: karaoke_OnApply
  227. /* Description: OnApply for Chapter Search page
  228. /*************************************************************/
  229. HRESULT COptionsDlg::karaoke_OnApply(HWND hwnd)
  230. {
  231. HWND audioList = ::GetDlgItem(hwnd, IDC_AUDIO_LIST);
  232. if (!audioList)
  233. return S_FALSE;
  234. // Check if audio stream selection has changed
  235. long nAudio = 0;
  236. HRESULT hr = m_pDvd->get_CurrentAudioStream(&nAudio);
  237. if(SUCCEEDED(hr) && nAudio != (long)::SendMessage(audioList, LB_GETCURSEL, 0, 0)) {
  238. hr = VFW_E_DVD_INVALIDDOMAIN;
  239. long nDomain;
  240. HRESULT hrTmp = m_pDvd->get_CurrentDomain(&nDomain);
  241. // Only allow it in title domain
  242. if (SUCCEEDED(hrTmp) && nDomain == DVD_DOMAIN_Title) {
  243. nAudio = (long)::SendMessage(audioList, LB_GETCURSEL, 0, 0);
  244. hr = m_pDvd->put_CurrentAudioStream(nAudio);
  245. }
  246. if (!SUCCEEDED(hr)) {
  247. LPTSTR strMsg = NULL;
  248. switch(hr) {
  249. case VFW_E_DVD_OPERATION_INHIBITED:
  250. strMsg = LoadStringFromRes(IDS_INI_INVALIDEUOP);
  251. break;
  252. case VFW_E_DVD_INVALIDDOMAIN:
  253. strMsg = LoadStringFromRes(IDS_INI_INVALIDEDOMAIN);
  254. break;
  255. }
  256. if (strMsg) {
  257. ::MessageBox(hwnd, strMsg, NULL, MB_OK);
  258. delete[] strMsg;
  259. }
  260. karaoke_OnInitDialog(hwnd);
  261. }
  262. }
  263. HWND enableChan2 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN2);
  264. HWND enableChan3 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN3);
  265. HWND enableChan4 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN4);
  266. if (!enableChan2 || !enableChan3 || !enableChan4)
  267. return S_FALSE;
  268. // No no check box is enabled
  269. if (!(::IsWindowEnabled(enableChan2) ||
  270. ::IsWindowEnabled(enableChan3) ||
  271. ::IsWindowEnabled(enableChan4) ))
  272. return S_FALSE;
  273. BOOL bEnableChan2 = (BOOL) ::SendMessage(enableChan2, BM_GETCHECK, 0, 0);
  274. BOOL bEnableChan3 = (BOOL) ::SendMessage(enableChan3, BM_GETCHECK, 0, 0);
  275. BOOL bEnableChan4 = (BOOL) ::SendMessage(enableChan4, BM_GETCHECK, 0, 0);
  276. long mixMode = 0;
  277. if (bEnableChan2)
  278. mixMode |= DVD_Mix_2to0 | DVD_Mix_2to1;
  279. if (bEnableChan3)
  280. mixMode |= DVD_Mix_3to0 | DVD_Mix_3to1;
  281. if (bEnableChan4)
  282. mixMode |= DVD_Mix_4to0 | DVD_Mix_4to1;
  283. long mixModeSaved = 0;
  284. hr = m_pDvd->get_KaraokeAudioPresentationMode(&mixModeSaved);
  285. if (mixMode == mixModeSaved)
  286. return hr;
  287. hr = m_pDvd->put_KaraokeAudioPresentationMode(mixMode);
  288. if (SUCCEEDED(hr))
  289. return hr;
  290. LPTSTR strMsg = NULL;
  291. switch(hr) {
  292. case VFW_E_DVD_OPERATION_INHIBITED:
  293. strMsg = LoadStringFromRes(IDS_INI_INVALIDEUOP);
  294. break;
  295. case VFW_E_DVD_INVALIDDOMAIN:
  296. strMsg = LoadStringFromRes(IDS_INI_INVALIDEDOMAIN);
  297. break;
  298. case E_PROP_SET_UNSUPPORTED:
  299. default:
  300. strMsg = LoadStringFromRes(IDS_INI_NOKARAOKESUPPORT);
  301. break;
  302. }
  303. if (strMsg) {
  304. ::MessageBox(hwnd, strMsg, NULL, MB_OK);
  305. delete[] strMsg;
  306. }
  307. karaoke_InitChannelList(hwnd);
  308. HWND hwndParent = ::GetParent(hwnd);
  309. ::SetFocus(::GetDlgItem(hwndParent, IDCANCEL));
  310. return hr;
  311. }
  312. /*************************************************************/
  313. /* Name: karaoke_InitChannelList
  314. /* Description:
  315. /*************************************************************/
  316. HRESULT COptionsDlg::karaoke_InitChannelList(HWND hwnd)
  317. {
  318. HWND audioList = ::GetDlgItem(hwnd, IDC_AUDIO_LIST);
  319. if (!audioList)
  320. return S_FALSE;
  321. HWND enableChan2 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN2);
  322. HWND enableChan3 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN3);
  323. HWND enableChan4 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN4);
  324. if (!enableChan2 || !enableChan3 || !enableChan4)
  325. return S_FALSE;
  326. // hide all check boxes first
  327. ::ShowWindow(enableChan2, SW_HIDE);
  328. ::ShowWindow(enableChan3, SW_HIDE);
  329. ::ShowWindow(enableChan4, SW_HIDE);
  330. HRESULT hr = S_OK;
  331. try {
  332. long mixMode = 0;
  333. hr = m_pDvd->get_KaraokeAudioPresentationMode(&mixMode);
  334. if (FAILED(hr))
  335. return hr;
  336. ::SendMessage(enableChan2, BM_SETCHECK, (mixMode & (DVD_Mix_2to0 | DVD_Mix_2to1))?
  337. BST_CHECKED:BST_UNCHECKED, 0);
  338. ::SendMessage(enableChan3, BM_SETCHECK, (mixMode & (DVD_Mix_3to0 | DVD_Mix_3to1))?
  339. BST_CHECKED:BST_UNCHECKED, 0);
  340. ::SendMessage(enableChan4, BM_SETCHECK, (mixMode & (DVD_Mix_4to0 | DVD_Mix_4to1))?
  341. BST_CHECKED:BST_UNCHECKED, 0);
  342. long nAudio = (long) ::SendMessage(audioList, LB_GETCURSEL, 0, 0);
  343. long nAssignment = 0;
  344. hr = m_pDvd->GetKaraokeChannelAssignment(nAudio, &nAssignment);
  345. if (FAILED(hr)) {
  346. throw(hr);
  347. }
  348. for (int i=2; i<5; i++) {
  349. long nContent;
  350. hr = m_pDvd->GetKaraokeChannelContent(nAudio, i, &nContent);
  351. if (FAILED(hr)) {
  352. throw(hr);
  353. }
  354. LPTSTR strContent = karaoke_InitContentString(nContent);
  355. if (lstrlen(strContent) > 0) {
  356. ::SetWindowText(::GetDlgItem(hwnd, IDC_CHECK_CHAN2+i-2), strContent);
  357. ::ShowWindow(::GetDlgItem(hwnd, IDC_CHECK_CHAN2+i-2), SW_SHOW);
  358. }
  359. delete[] strContent;
  360. }
  361. }
  362. catch (...) {
  363. }
  364. return hr;
  365. }
  366. /*************************************************************/
  367. /* Name: karaoke_InitContentString
  368. /* Description:
  369. /*************************************************************/
  370. LPTSTR COptionsDlg::karaoke_InitContentString(long nContent)
  371. {
  372. TCHAR* strAllContent = new TCHAR[MAX_PATH];
  373. strAllContent[0] = TEXT('\0');
  374. if (nContent&DVD_Karaoke_GuideVocal1 &&
  375. nContent&DVD_Karaoke_GuideVocal2) {
  376. LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEVOCAL12);
  377. _stprintf(strAllContent, TEXT("%s "), strContent);
  378. delete[] strContent;
  379. }
  380. else if (nContent&DVD_Karaoke_GuideVocal1) {
  381. LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEVOCAL1);
  382. _stprintf(strAllContent, TEXT("%s "), strContent);
  383. delete[] strContent;
  384. }
  385. else if (nContent&DVD_Karaoke_GuideVocal2) {
  386. LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEVOCAL2);
  387. _stprintf(strAllContent+lstrlen(strAllContent),TEXT("%s "), strContent);
  388. delete[] strContent;
  389. }
  390. if (nContent&DVD_Karaoke_GuideMelody1 ||
  391. nContent&DVD_Karaoke_GuideMelody2 ||
  392. nContent&DVD_Karaoke_GuideMelodyA ||
  393. nContent&DVD_Karaoke_GuideMelodyB) {
  394. LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEMELODY);
  395. _stprintf(strAllContent+lstrlen(strAllContent), TEXT("%s "), strContent);
  396. delete[] strContent;
  397. }
  398. if (nContent&DVD_Karaoke_SoundEffectA ||
  399. nContent&DVD_Karaoke_SoundEffectB) {
  400. LPTSTR strContent = LoadStringFromRes(IDS_INI_SOUNDEFFECT);
  401. _stprintf(strAllContent+lstrlen(strAllContent), TEXT("%s "), strContent);
  402. delete[] strContent;
  403. }
  404. return strAllContent;
  405. }
  406. /*************************************************************/
  407. /* Name: karaoke_HasKaraokeContent
  408. /* Description:
  409. /*************************************************************/
  410. BOOL COptionsDlg::karaoke_HasKaraokeContent() {
  411. // Only allow it in title domain
  412. long nDomain;
  413. HRESULT hr = m_pDvd->get_CurrentDomain(&nDomain);
  414. if (FAILED(hr) || nDomain != DVD_DOMAIN_Title)
  415. return FALSE;
  416. long nAudio;
  417. hr = m_pDvd->get_AudioStreamsAvailable(&nAudio);
  418. if (FAILED(hr) || nAudio == 0)
  419. return FALSE;
  420. long nAssignment = 0;
  421. for (int i=0; i<nAudio; i++) {
  422. hr = m_pDvd->GetKaraokeChannelAssignment(i, &nAssignment);
  423. if (SUCCEEDED(hr) && nAssignment >= DVD_Assignment_LR) {
  424. return TRUE;
  425. }
  426. }
  427. return FALSE;
  428. }