windows-nt/Source/XPSP1/NT/multimedia/dshow/mfvideo/msdvdopt/callback.cpp
2020-09-26 16:20:57 +08:00

519 lines
16 KiB
C++

// Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
/*************************************************************/
/* Name: callback.cpp
/* Description:
/*************************************************************/
#include "stdafx.h"
#include <streams.h>
#include <stdio.h>
#include "COptDlg.h"
const TCHAR g_szRegistryKey[] = TEXT("Software\\Microsoft\\Multimedia\\DVD");
/*************************************************************/
/* Name: GetRegistryDword
/* Description:
/*************************************************************/
BOOL GetRegistryDword(const TCHAR *pKey, DWORD* dwRet, DWORD dwDefault)
{
HKEY hKey;
LONG lRet;
*dwRet = dwDefault;
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szRegistryKey, 0, KEY_QUERY_VALUE, &hKey);
if (lRet == ERROR_SUCCESS) {
DWORD dwType, dwLen;
dwLen = sizeof(DWORD);
if (ERROR_SUCCESS != RegQueryValueEx(hKey, pKey, NULL, &dwType, (LPBYTE)dwRet, &dwLen))
*dwRet = dwDefault;
RegCloseKey(hKey);
}
return (lRet == ERROR_SUCCESS);
}
/*************************************************************/
/* Name: GetRegistryString
/* Description:
/*************************************************************/
BOOL GetRegistryString(const TCHAR *pKey, TCHAR* szRet, DWORD* dwLen, TCHAR* szDefault)
{
HKEY hKey;
LONG lRet;
lstrcpy(szRet, szDefault);
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szRegistryKey, 0, KEY_QUERY_VALUE, &hKey);
if (lRet == ERROR_SUCCESS) {
DWORD dwType;
if (ERROR_SUCCESS != RegQueryValueEx(hKey, pKey, NULL, &dwType, (LPBYTE)szRet, dwLen)) {
lstrcpy(szRet, szDefault);
*dwLen = 0;
}
*dwLen = *dwLen/sizeof(TCHAR);
RegCloseKey(hKey);
}
return (lRet == ERROR_SUCCESS);
}
/*************************************************************/
/* Name: LoadBSTRFromRes
/* Description: load string from resource and convert to wchar
/* if necessary, return the BSTR pointer if successful, NULL
/* otherwise
/*************************************************************/
CComBSTR LoadBSTRFromRes(DWORD resId)
{
CComBSTR pBSTR;
if (pBSTR.LoadString( _Module.GetModuleInstance(), resId))
return pBSTR;
else
return NULL;
}
/*************************************************************/
/* Name: LoadStringFromRes
/* Description: load a string from resource
/*************************************************************/
LPTSTR LoadStringFromRes(DWORD redId)
{
TCHAR *string = new TCHAR[MAX_PATH];
LoadString(_Module.GetModuleInstance(), redId, string, MAX_PATH);
return string;
}
/*************************************************************/
/* Function: lstrlenWInternal */
/*************************************************************/
int WINAPI lstrlenWInternal(LPCWSTR lpString){
int length = 0;
while (*lpString++ != L'\0')
length++;
return length;
}/* end of function lstrlenWInternal */
/*************************************************************/
/* Name: chapSrch_OnInitDialog
/* Description: OnInitDialog for Chapter Search page
/*************************************************************/
HRESULT COptionsDlg::chapSrch_OnInitDialog(HWND hwndDlg)
{
HWND titleWnd = ::GetDlgItem(hwndDlg, IDC_LIST_TITLES);
HWND chapWnd = ::GetDlgItem(hwndDlg, IDC_LIST_CHAPS);
if (!titleWnd || !chapWnd)
return S_FALSE;
::EnableWindow(titleWnd, TRUE);
::EnableWindow(chapWnd, TRUE);
ATLTRACE(TEXT("WM_INITDIALOG\n"));
HRESULT hr = S_OK;
try {
LONG nTitles;
hr = m_pDvd->get_TitlesAvailable(&nTitles);
if (FAILED(hr))
throw(hr);
LONG currentTitle = 0;
HRESULT hr = m_pDvd->get_CurrentTitle(&currentTitle);
for (long i=0; i<nTitles; i++) {
TCHAR name[32];
LPTSTR szTitleNo = LoadStringFromRes(IDS_INI_TITLE_NO);
wsprintf(name, szTitleNo, i+1);
delete[] szTitleNo;
::SendMessage(titleWnd, LB_INSERTSTRING, (UINT)-1, (LPARAM)name);
if (i+1 == currentTitle) {
::SendMessage(titleWnd, LB_SETCURSEL, (WPARAM)i, 0);
}
}
chapSrch_InitChapList(hwndDlg);
}
catch (HRESULT hr) {
::EnableWindow(titleWnd, FALSE);
::EnableWindow(chapWnd, FALSE);
return hr;
}
return hr;
}
/*************************************************************/
/* Name: chapSrch_InitChapList
/* Description:
/*************************************************************/
HRESULT COptionsDlg::chapSrch_InitChapList(HWND hwndDlg)
{
HWND titleWnd = ::GetDlgItem(hwndDlg, IDC_LIST_TITLES);
HWND chapWnd = ::GetDlgItem(hwndDlg, IDC_LIST_CHAPS);
if (!titleWnd || !chapWnd)
return S_FALSE;
::SendMessage(chapWnd, LB_RESETCONTENT, 0, 0);
LONG nTitle = (LONG) ::SendMessage(titleWnd, LB_GETCURSEL, 0, 0);
LONG nChaps;
HRESULT hr = m_pDvd->GetNumberOfChapters(nTitle+1, &nChaps);
if (FAILED(hr))
return hr;
long currentChap = 0;
hr = m_pDvd->get_CurrentChapter(&currentChap);
for (int j=0; j<nChaps; j++) {
TCHAR name[32];
LPTSTR szChapNo = LoadStringFromRes(IDS_INI_CHAP_NO);
wsprintf(name, szChapNo, j+1);
delete[] szChapNo;
::SendMessage(chapWnd, LB_INSERTSTRING, (UINT)-1, (LPARAM)name);
if (currentChap ==j+1)
::SendMessage(chapWnd, LB_SETCURSEL, (WPARAM)j, 0);
}
if (LB_ERR == ::SendMessage(chapWnd, LB_GETCURSEL, 0, 0))
::SendMessage(chapWnd, LB_SETCURSEL, (WPARAM)0, 0);
return hr;
}
/*************************************************************/
/* Name: chapSrch_OnApply
/* Description: OnApply for Chapter Search page
/*************************************************************/
HRESULT COptionsDlg::chapSrch_OnApply(HWND hwndDlg)
{
if (!m_bChapDirty)
return S_OK;
HWND titleWnd = ::GetDlgItem(hwndDlg, IDC_LIST_TITLES);
HWND chapWnd = ::GetDlgItem(hwndDlg, IDC_LIST_CHAPS);
if (!titleWnd || !chapWnd)
return S_FALSE;
LONG nTitle = (LONG) ::SendMessage(titleWnd, LB_GETCURSEL, 0, 0);
LONG nChapter = (LONG) ::SendMessage(chapWnd, LB_GETCURSEL, 0, 0);
if (nTitle == LB_ERR)
return S_FALSE;
HRESULT hr = S_OK;
if (nChapter == LB_ERR) {
hr = m_pDvd->PlayTitle(nTitle+1);
// if Title_Play is inhibited by UOP
if (hr == VFW_E_DVD_OPERATION_INHIBITED) {
hr = m_pDvd->PlayChapterInTitle(nTitle+1, 1);
}
}
else {
hr = m_pDvd->PlayChapterInTitle(nTitle+1, nChapter+1);
} /* end if statement */
// Play at the right speed
if (SUCCEEDED(hr)) {
double playSpeed;
GetDvdOpt()->get_PlaySpeed(&playSpeed);
hr = m_pDvd->PlayForwards(playSpeed, VARIANT_TRUE);
}
else {
DVDMessageBox(hwndDlg, IDS_INI_CANNOT_PLAYCHAP);
}
m_bChapDirty = FALSE;
return hr;
}
/*************************************************************/
/* Name: karaoke_OnInitDialog
/* Description: OnApply for Chapter Search page
/*************************************************************/
HRESULT COptionsDlg::karaoke_OnInitDialog(HWND hwnd)
{
if (!karaoke_HasKaraokeContent())
return E_FAIL;
USES_CONVERSION;
HWND audioList = ::GetDlgItem(hwnd, IDC_AUDIO_LIST);
if (!audioList)
return S_FALSE;
::SendMessage(audioList, LB_RESETCONTENT, 0, 0);
long nAudio;
HRESULT hr = m_pDvd->get_AudioStreamsAvailable(&nAudio);
if (FAILED(hr) || nAudio == 0)
return S_FALSE;
for (int i=0; i<nAudio; i++) {
CComBSTR strAudio;
hr = m_pDvd->GetAudioLanguage(i, VARIANT_TRUE, &strAudio);
if (SUCCEEDED(hr)) {
::SendMessage(audioList, LB_INSERTSTRING, (UINT)-1, (LPARAM)OLE2T(strAudio));
::SysFreeString(strAudio);
}
}
long nCurrentAudio = 0;
m_pDvd->get_CurrentAudioStream(&nCurrentAudio);
::SendMessage(audioList, LB_SETCURSEL, (WPARAM)nCurrentAudio, 0);
karaoke_InitChannelList(hwnd);
return S_OK;
}
/*************************************************************/
/* Name: karaoke_OnApply
/* Description: OnApply for Chapter Search page
/*************************************************************/
HRESULT COptionsDlg::karaoke_OnApply(HWND hwnd)
{
HWND audioList = ::GetDlgItem(hwnd, IDC_AUDIO_LIST);
if (!audioList)
return S_FALSE;
// Check if audio stream selection has changed
long nAudio = 0;
HRESULT hr = m_pDvd->get_CurrentAudioStream(&nAudio);
if(SUCCEEDED(hr) && nAudio != (long)::SendMessage(audioList, LB_GETCURSEL, 0, 0)) {
hr = VFW_E_DVD_INVALIDDOMAIN;
long nDomain;
HRESULT hrTmp = m_pDvd->get_CurrentDomain(&nDomain);
// Only allow it in title domain
if (SUCCEEDED(hrTmp) && nDomain == DVD_DOMAIN_Title) {
nAudio = (long)::SendMessage(audioList, LB_GETCURSEL, 0, 0);
hr = m_pDvd->put_CurrentAudioStream(nAudio);
}
if (!SUCCEEDED(hr)) {
LPTSTR strMsg = NULL;
switch(hr) {
case VFW_E_DVD_OPERATION_INHIBITED:
strMsg = LoadStringFromRes(IDS_INI_INVALIDEUOP);
break;
case VFW_E_DVD_INVALIDDOMAIN:
strMsg = LoadStringFromRes(IDS_INI_INVALIDEDOMAIN);
break;
}
if (strMsg) {
::MessageBox(hwnd, strMsg, NULL, MB_OK);
delete[] strMsg;
}
karaoke_OnInitDialog(hwnd);
}
}
HWND enableChan2 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN2);
HWND enableChan3 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN3);
HWND enableChan4 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN4);
if (!enableChan2 || !enableChan3 || !enableChan4)
return S_FALSE;
// No no check box is enabled
if (!(::IsWindowEnabled(enableChan2) ||
::IsWindowEnabled(enableChan3) ||
::IsWindowEnabled(enableChan4) ))
return S_FALSE;
BOOL bEnableChan2 = (BOOL) ::SendMessage(enableChan2, BM_GETCHECK, 0, 0);
BOOL bEnableChan3 = (BOOL) ::SendMessage(enableChan3, BM_GETCHECK, 0, 0);
BOOL bEnableChan4 = (BOOL) ::SendMessage(enableChan4, BM_GETCHECK, 0, 0);
long mixMode = 0;
if (bEnableChan2)
mixMode |= DVD_Mix_2to0 | DVD_Mix_2to1;
if (bEnableChan3)
mixMode |= DVD_Mix_3to0 | DVD_Mix_3to1;
if (bEnableChan4)
mixMode |= DVD_Mix_4to0 | DVD_Mix_4to1;
long mixModeSaved = 0;
hr = m_pDvd->get_KaraokeAudioPresentationMode(&mixModeSaved);
if (mixMode == mixModeSaved)
return hr;
hr = m_pDvd->put_KaraokeAudioPresentationMode(mixMode);
if (SUCCEEDED(hr))
return hr;
LPTSTR strMsg = NULL;
switch(hr) {
case VFW_E_DVD_OPERATION_INHIBITED:
strMsg = LoadStringFromRes(IDS_INI_INVALIDEUOP);
break;
case VFW_E_DVD_INVALIDDOMAIN:
strMsg = LoadStringFromRes(IDS_INI_INVALIDEDOMAIN);
break;
case E_PROP_SET_UNSUPPORTED:
default:
strMsg = LoadStringFromRes(IDS_INI_NOKARAOKESUPPORT);
break;
}
if (strMsg) {
::MessageBox(hwnd, strMsg, NULL, MB_OK);
delete[] strMsg;
}
karaoke_InitChannelList(hwnd);
HWND hwndParent = ::GetParent(hwnd);
::SetFocus(::GetDlgItem(hwndParent, IDCANCEL));
return hr;
}
/*************************************************************/
/* Name: karaoke_InitChannelList
/* Description:
/*************************************************************/
HRESULT COptionsDlg::karaoke_InitChannelList(HWND hwnd)
{
HWND audioList = ::GetDlgItem(hwnd, IDC_AUDIO_LIST);
if (!audioList)
return S_FALSE;
HWND enableChan2 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN2);
HWND enableChan3 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN3);
HWND enableChan4 = ::GetDlgItem(hwnd, IDC_CHECK_CHAN4);
if (!enableChan2 || !enableChan3 || !enableChan4)
return S_FALSE;
// hide all check boxes first
::ShowWindow(enableChan2, SW_HIDE);
::ShowWindow(enableChan3, SW_HIDE);
::ShowWindow(enableChan4, SW_HIDE);
HRESULT hr = S_OK;
try {
long mixMode = 0;
hr = m_pDvd->get_KaraokeAudioPresentationMode(&mixMode);
if (FAILED(hr))
return hr;
::SendMessage(enableChan2, BM_SETCHECK, (mixMode & (DVD_Mix_2to0 | DVD_Mix_2to1))?
BST_CHECKED:BST_UNCHECKED, 0);
::SendMessage(enableChan3, BM_SETCHECK, (mixMode & (DVD_Mix_3to0 | DVD_Mix_3to1))?
BST_CHECKED:BST_UNCHECKED, 0);
::SendMessage(enableChan4, BM_SETCHECK, (mixMode & (DVD_Mix_4to0 | DVD_Mix_4to1))?
BST_CHECKED:BST_UNCHECKED, 0);
long nAudio = (long) ::SendMessage(audioList, LB_GETCURSEL, 0, 0);
long nAssignment = 0;
hr = m_pDvd->GetKaraokeChannelAssignment(nAudio, &nAssignment);
if (FAILED(hr)) {
throw(hr);
}
for (int i=2; i<5; i++) {
long nContent;
hr = m_pDvd->GetKaraokeChannelContent(nAudio, i, &nContent);
if (FAILED(hr)) {
throw(hr);
}
LPTSTR strContent = karaoke_InitContentString(nContent);
if (lstrlen(strContent) > 0) {
::SetWindowText(::GetDlgItem(hwnd, IDC_CHECK_CHAN2+i-2), strContent);
::ShowWindow(::GetDlgItem(hwnd, IDC_CHECK_CHAN2+i-2), SW_SHOW);
}
delete[] strContent;
}
}
catch (...) {
}
return hr;
}
/*************************************************************/
/* Name: karaoke_InitContentString
/* Description:
/*************************************************************/
LPTSTR COptionsDlg::karaoke_InitContentString(long nContent)
{
TCHAR* strAllContent = new TCHAR[MAX_PATH];
strAllContent[0] = TEXT('\0');
if (nContent&DVD_Karaoke_GuideVocal1 &&
nContent&DVD_Karaoke_GuideVocal2) {
LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEVOCAL12);
_stprintf(strAllContent, TEXT("%s "), strContent);
delete[] strContent;
}
else if (nContent&DVD_Karaoke_GuideVocal1) {
LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEVOCAL1);
_stprintf(strAllContent, TEXT("%s "), strContent);
delete[] strContent;
}
else if (nContent&DVD_Karaoke_GuideVocal2) {
LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEVOCAL2);
_stprintf(strAllContent+lstrlen(strAllContent),TEXT("%s "), strContent);
delete[] strContent;
}
if (nContent&DVD_Karaoke_GuideMelody1 ||
nContent&DVD_Karaoke_GuideMelody2 ||
nContent&DVD_Karaoke_GuideMelodyA ||
nContent&DVD_Karaoke_GuideMelodyB) {
LPTSTR strContent = LoadStringFromRes(IDS_INI_GUIDEMELODY);
_stprintf(strAllContent+lstrlen(strAllContent), TEXT("%s "), strContent);
delete[] strContent;
}
if (nContent&DVD_Karaoke_SoundEffectA ||
nContent&DVD_Karaoke_SoundEffectB) {
LPTSTR strContent = LoadStringFromRes(IDS_INI_SOUNDEFFECT);
_stprintf(strAllContent+lstrlen(strAllContent), TEXT("%s "), strContent);
delete[] strContent;
}
return strAllContent;
}
/*************************************************************/
/* Name: karaoke_HasKaraokeContent
/* Description:
/*************************************************************/
BOOL COptionsDlg::karaoke_HasKaraokeContent() {
// Only allow it in title domain
long nDomain;
HRESULT hr = m_pDvd->get_CurrentDomain(&nDomain);
if (FAILED(hr) || nDomain != DVD_DOMAIN_Title)
return FALSE;
long nAudio;
hr = m_pDvd->get_AudioStreamsAvailable(&nAudio);
if (FAILED(hr) || nAudio == 0)
return FALSE;
long nAssignment = 0;
for (int i=0; i<nAudio; i++) {
hr = m_pDvd->GetKaraokeChannelAssignment(i, &nAssignment);
if (SUCCEEDED(hr) && nAssignment >= DVD_Assignment_LR) {
return TRUE;
}
}
return FALSE;
}