home *** CD-ROM | disk | FTP | other *** search
- //------------------------------------------------------------------------------
- // File: DvdSample.cpp
- //
- // Desc: DVD Playback sample app using IDvdGraphBuilder,
- // IDvdInfo2, and IDvdControl2 interfaces.
- //
- // This contains all Windows-related "plumbing" for the application
- //
- // Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------------------------
-
- #include <windows.h>
- #include <commdlg.h>
- #include <commctrl.h>
-
- #include <dshow.h>
- #include "resource.h"
-
- #include "DvdCore.h"
- #include "Dialogs.h"
- #include "DvdSample.h"
-
-
-
-
- //------------------------------------------------------------------------------
- // Global data
- //------------------------------------------------------------------------------
-
- const PTSTR APPNAME = TEXT("DVDSample");
- CApp g_App;
-
-
-
-
- //------------------------------------------------------------------------------
- // Type Definitions
- //------------------------------------------------------------------------------
-
- typedef UINT (CALLBACK* PFNDLL_STES)(UINT);
-
-
-
-
- //------------------------------------------------------------------------------
- // Name: WinMain()
- // Desc: This method is the standard Windows program entry point.
- //------------------------------------------------------------------------------
-
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- PSTR pCmdLine,
- int nCmdShow)
- {
- DbgInitialise(hInstance);
- g_App.SetAppValues(hInstance, APPNAME, IDS_APP_TITLE) ;
-
- // Perform application initialization:
- if (! g_App.InitInstance(nCmdShow) )
- {
- DbgTerminate();
- return (FALSE) ;
- }
-
- HACCEL hAccelTable ;
- hAccelTable = LoadAccelerators(hInstance, g_App.GetAppName()) ;
-
- // Main message loop:
- MSG msg ;
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (! TranslateAccelerator(msg.hwnd, hAccelTable, &msg) )
- {
- TranslateMessage(&msg) ;
- DispatchMessage(&msg) ;
- }
- }
-
- DbgTerminate();
- return (msg.wParam) ;
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::CApp()
- // Desc: This is the constructor for CApp. It sets default values and disables
- // power saving.
- //------------------------------------------------------------------------------
-
- CApp::CApp() : m_hInstance(NULL),
- m_hWnd(NULL),
- m_bCaptionsOn(false),
- m_pDvdCore(NULL),
- m_bFullScreenOn(false),
- m_pParentLevels(NULL),
- m_pLangLookup(NULL),
- m_hwndToolBar(0),
- m_dwProhibitedTime(0)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::CApp()"))) ;
- ZeroMemory(m_szAppTitle, sizeof(m_szAppTitle)) ;
-
- ZeroMemory(m_szAppName, sizeof(m_szAppName)) ;
-
- m_pParentLevels = new CParentLevels();
- m_pLangLookup = new CDVDLanguages();
-
- // notify the power manager that the display is in use so it won't go to sleep
- // SetThreadExecutionState() is a Win98/Win2k API.
- // The following code lets it fail gracefully on Win95
-
- PFNDLL_STES pfn;
- pfn = (PFNDLL_STES) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
- "SetThreadExecutionState");
- if (pfn)
- {
- pfn(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::~CApp()
- // Desc: This is the destructor for CApp.
- //------------------------------------------------------------------------------
-
- CApp::~CApp()
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::~CApp()"))) ;
-
- delete m_pParentLevels;
- delete m_pLangLookup;
- if (m_pDvdCore)
- {
- delete m_pDvdCore;
- m_pDvdCore = NULL;
- }
-
- // notify the power manager that the display is no longer in use and it can go to sleep
- // SetThreadExecutionState() is a Win98/Win2k API.
- // The following code lets it fail gracefully on Win95
-
- PFNDLL_STES pfn;
- pfn = (PFNDLL_STES) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
- "SetThreadExecutionState");
- if (pfn)
- {
- pfn(ES_CONTINUOUS);
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::SetAppValues()
- // Desc: This method sets the basic application values like szAppName and hInstance
- //------------------------------------------------------------------------------
-
- void CApp::SetAppValues(HINSTANCE hInst, PTSTR szAppName, int iAppTitleResId)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::SetAppValues()"))) ;
-
- // The Windows stuff
- m_hInstance = hInst ;
- lstrcpy(m_szAppName, APPNAME) ;
- LoadString(m_hInstance, IDS_APP_TITLE, m_szAppTitle, 100) ;
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::InitInstance()
- // Desc: This method registers and creates our window and toolbar.
- //------------------------------------------------------------------------------
-
- bool CApp::InitInstance(int nCmdShow)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::InitInstance()"))) ;
-
- // Win32 will always set hPrevInstance to NULL, So lets check
- // things a little closer. This is because we only want a single
- // version of this app to run at a time
- m_hWnd = FindWindow (m_szAppName, m_szAppTitle) ;
- if (m_hWnd)
- {
- // We found another instance of ourself. Lets use that one:
- if (IsIconic(m_hWnd))
- {
- ShowWindow(m_hWnd, SW_RESTORE);
- }
- SetForegroundWindow(m_hWnd);
-
- // If this app actually had any methodality, we would
- // also want to communicate any action that our 'twin'
- // should now perform based on how the user tried to
- // execute us.
- return false;
- }
-
- // Register the app main window class
- WNDCLASSEX wc ;
- wc.cbSize = sizeof(wc) ;
- wc.style = CS_HREDRAW | CS_VREDRAW ;
- wc.lpfnWndProc = (WNDPROC) WndProc ;
- wc.cbClsExtra = 0 ;
- wc.cbWndExtra = 0 ;
- wc.hInstance = m_hInstance ;
- wc.hIcon = LoadIcon(m_hInstance, MAKEINTRESOURCE(IDI_APPICON));
- wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ;
- wc.lpszMenuName = TEXT("DvdSample_Menu");
- wc.lpszClassName = m_szAppName ;
- wc.hIconSm = NULL ;
-
- if (0 == RegisterClassEx(&wc))
- {
- DbgLog((LOG_ERROR, 0,
- TEXT("ERROR: RegisterClassEx() for app class failed (Error %ld)"),
- GetLastError())) ;
- return false ;
- }
-
- // Determine where to put the Application Window
- RECT rDesktop;
- SystemParametersInfo(SPI_GETWORKAREA, NULL, &rDesktop, NULL);
-
- // Create an instance of the window we just registered
- // locate it at the bottom of the screen (bottom of screen - height of player)
- m_hWnd = CreateWindowEx(0, m_szAppName, m_szAppTitle, WS_OVERLAPPEDWINDOW, //& ~WS_THICKFRAME,
- 160, rDesktop.bottom - 150, 300, 150, NULL, NULL, m_hInstance, NULL);
- if (!m_hWnd)
- {
- DbgLog((LOG_ERROR, 0,
- TEXT("ERROR: CreateWindowEx() failed (Error %ld)"),
- GetLastError())) ;
- return false ;
- }
-
- // We now create the toolbar
- INITCOMMONCONTROLSEX cc;
- cc.dwSize = sizeof(INITCOMMONCONTROLSEX);
- cc.dwICC = ICC_BAR_CLASSES; // register only the toolbar control
- InitCommonControlsEx(&cc);
-
- TBBUTTON tbb[] =
- {
- 0, ID_PLAYBACK_PREVIOUSCHAPTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 1, ID_PLAYBACK_REWIND, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 2, ID_PLAYBACK_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 3, ID_PLAYBACK_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 4, ID_PLAYBACK_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 5, ID_PLAYBACK_FASTFORWARD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 6, ID_PLAYBACK_NEXTCHAPTER, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 9, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0, 0, 0,
- 7, ID_PLAYBACK_MENUROOT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 8, ID_OPTIONS_FULLSCREEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0,
- 9, ID_PLAYBACK_STEPFORWARD, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, 0
- };
-
- m_hwndToolBar = CreateToolbarEx(m_hWnd, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | CCS_TOP
- | TBSTYLE_TOOLTIPS, 1, 10, m_hInstance, IDR_TOOLBAR1, tbb, 11, 0, 0, 0, 0,
- sizeof(TBBUTTON));
- if (!m_hwndToolBar)
- {
- DbgLog((LOG_ERROR, 0,
- TEXT("ERROR: CreateToolbarEx() failed (Error %ld)"),
- GetLastError())) ;
- return false ;
- }
-
- // we now set up the dvd playback class
- m_pDvdCore = new CDvdCore(m_hInstance, this);
- if (!m_pDvdCore->Init())
- {
- DbgLog((LOG_ERROR, 0, TEXT("ERROR: CDvdCore::Init() failed"))) ;
- return false;
- }
-
- m_pDvdCore->SetVideoWindowTitle(TEXT("DvdSample Video Window"));
-
- // and finally, we make the window visible
- ShowWindow(m_hWnd, nCmdShow);
- UpdateWindow(m_hWnd) ;
-
- return true;
- }
-
-
- //------------------------------------------------------------------------------
- // Name: WndProc()
- // Desc: This method is our main window procedure. It parses the messages
- // and farms out the work to other procedures.
- //------------------------------------------------------------------------------
-
- LRESULT CApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HDC hDC ;
- static PAINTSTRUCT ps ;
-
- switch (message) {
-
- case WM_INITMENUPOPUP:
- // UpdateMenuState() ;
- break ;
-
- case WM_PAINT:
- hDC = BeginPaint(hWnd, &ps) ;
- ASSERT(hDC) ;
- g_App.DrawStatus(hDC);
- EndPaint(hWnd, &ps) ;
- break ;
-
- case WM_KEYUP:
- g_App.KeyProc(wParam, lParam) ;
- break ;
-
- case WM_COMMAND:
- g_App.MenuProc(hWnd, wParam, lParam) ;
- break;
-
- case WM_NOTIFY:
- return g_App.ToolTipProc(hWnd, message, wParam, lParam);
- break;
-
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
-
- case WM_SIZE:
- // we do this to cause the toolbar to resize correctly
- SendMessage(g_App.m_hwndToolBar, WM_SIZE, wParam, lParam);
- return DefWindowProc(hWnd, message, wParam, lParam);
- break;
-
- default:
- return (DefWindowProc(hWnd, message, wParam, lParam));
- }
-
- return 0 ; // let Windows know we handled the message
-
- }
-
-
- //------------------------------------------------------------------------------
- // Name: ToolTipProc()
- // Desc: This method is a MessageProc for our toolbar tooltips.
- // This checks whether the WM_NOTIFY message is really a tooltip.
- // If it is, we compare it to the buttons on the toolbar and send the right text back.
- // Note that older code would use TTN_NEEDTEXT instead of TTN_GETDISPINFO.
- //------------------------------------------------------------------------------
-
- LRESULT CApp::ToolTipProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::ToolTipProc()"))) ;
-
- LPNMTTDISPINFO TText;
- TText = (LPNMTTDISPINFO) lParam;
- if (TTN_GETDISPINFO == TText->hdr.code)
- {
- switch (TText->hdr.idFrom)
- {
- case ID_PLAYBACK_PREVIOUSCHAPTER:
- TText->lpszText = TEXT("Previous Chapter");
- break;
- case ID_PLAYBACK_REWIND:
- TText->lpszText = TEXT("Rewind");
- break;
- case ID_PLAYBACK_PAUSE:
- TText->lpszText = TEXT("Pause");
- break;
- case ID_PLAYBACK_PLAY:
- TText->lpszText = TEXT("Play");
- break;
- case ID_PLAYBACK_STOP:
- TText->lpszText = TEXT("Stop");
- break;
- case ID_PLAYBACK_FASTFORWARD:
- TText->lpszText = TEXT("FastForward");
- break;
- case ID_PLAYBACK_NEXTCHAPTER:
- TText->lpszText = TEXT("Next Chapter");
- break;
- case ID_PLAYBACK_MENUROOT:
- TText->lpszText = TEXT("Root Menu / Resume");
- break;
- case ID_OPTIONS_FULLSCREEN:
- TText->lpszText = TEXT("Full Screen");
- break;
- case ID_PLAYBACK_STEPFORWARD:
- TText->lpszText = TEXT("Step Forward");
- break;
- }
- return 0;
- }
- else
- return DefWindowProc(hWnd, message, wParam, lParam); // it wasn't a tooltip message
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::MenuProc()
- // Desc: This method handles all of the menu messages for our application. It is
- // passed these messages by the main message proc.
- //------------------------------------------------------------------------------
-
- LRESULT CApp::MenuProc(HWND hWnd, WPARAM wParam, LPARAM lParam)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::MenuProc()"))) ;
-
- HMENU hMenu = GetMenu(hWnd) ;
-
- //Parse the menu selections:
- switch (LOWORD(wParam))
- {
- case ID_PLAYBACK_PLAY:
- m_pDvdCore->Play();
- break;
-
- case ID_PLAYBACK_PREVIOUSCHAPTER:
- m_pDvdCore->PrevChapter();
- break;
-
- case ID_PLAYBACK_REWIND:
- m_pDvdCore->Rewind();
- break;
-
- case ID_PLAYBACK_PAUSE:
- m_pDvdCore->Pause();
- break;
-
- case ID_PLAYBACK_STOP:
- m_pDvdCore->Stop();
- break;
-
- case ID_PLAYBACK_FASTFORWARD:
- m_pDvdCore->FastForward();
- break;
-
- case ID_PLAYBACK_NEXTCHAPTER:
- m_pDvdCore->NextChapter();
- break;
-
- case ID_PLAYBACK_MENUROOT:
- m_pDvdCore->RootMenu();
- break;
-
- case ID_OPTIONS_FULLSCREEN:
- {
- m_pDvdCore->ToggleFullScreen();
- }
- break;
-
- case ID_PLAYBACK_TITLEMENU:
- m_pDvdCore->TitleMenu();
- break;
-
- case ID_FILE_EXIT:
- DestroyWindow(m_hWnd);
- break;
-
- case ID_OPTIONS_CLOSEDCAPTION:
- if (false == m_bCaptionsOn) // turn them on
- {
- HMENU hSubMenu = GetSubMenu(hMenu, 2); // Options is the 3rd menu starting with 0
- CheckMenuItem(hSubMenu, ID_OPTIONS_CLOSEDCAPTION, MF_BYCOMMAND | MF_CHECKED);
- if (m_pDvdCore->EnableCaptions(true))
- m_bCaptionsOn = true;
- }
- else // turn them off
- {
- HMENU hSubMenu = GetSubMenu(hMenu, 2); // Options is the 3rd menu starting with 0
- CheckMenuItem(hSubMenu, ID_OPTIONS_CLOSEDCAPTION, MF_BYCOMMAND | MF_UNCHECKED);
- if (m_pDvdCore->EnableCaptions(false))
- m_bCaptionsOn = false;
- }
- break;
-
- case ID_OPTIONS_SAVEBOOKMARK:
- m_pDvdCore->SaveBookmark();
- break;
-
- case ID_OPTIONS_RESTOREBOOKMARK:
- m_pDvdCore->RestoreBookmark();
- break;
-
- case ID_OPTIONS_PARENTALLEVEL:
- if (Nav_Stopped != m_pDvdCore->GetState() && Graph_Stopped2 != m_pDvdCore->GetState())
- // can't change parental level except in stop state
- {
- MessageBox(m_hWnd,
- TEXT("Can't change parental control level during playback. Please stop (twice) first."),
- TEXT("Error"), MB_OK | MB_ICONINFORMATION) ;
- break ;
- }
- DialogBox(m_hInstance, MAKEINTRESOURCE(IDD_PARENTLEVELS), m_hWnd,
- reinterpret_cast<DLGPROC>(SelectParentalLevel));
-
- break;
-
- case ID_HELP_ABOUTDVDSAMPLE:
- {
- CAboutDlg aDlg(m_hInstance, m_hWnd);
- aDlg.DoModal();
- }
- break;
-
- case ID_OPTIONS_SUBPICTURE:
- {
- CSPLangDlg aDlg(m_hInstance, m_hWnd);
- aDlg.DoModal();
- }
- break;
-
- case ID_OPTIONS_AUDIOLANGUAGE:
- {
- CAudioLangDlg aDlg(m_hInstance, m_hWnd);
- aDlg.DoModal();
- }
- break;
-
- case ID_OPTIONS_ANGLE:
- {
- CAngleDlg aDlg(m_hInstance, m_hWnd);
- aDlg.DoModal();
- }
- break;
-
- case ID_FILE_SELECTDISC:
- OnSelectDisc();
- break;
-
- case ID_PLAYBACK_STEPFORWARD:
- m_pDvdCore->FrameStep();
- break;
-
- case ID_PLAYBACK_GOTO_CHAPTER:
- {
- CChapterDlg aDlg(m_hInstance, m_hWnd);
- if (false == aDlg.DoModal())
- break;
- m_pDvdCore->PlayChapter(aDlg.GetChapter());
- }
- break;
-
- case ID_PLAYBACK_GOTO_TITLE:
- {
- CTitleDlg aDlg(m_hInstance, m_hWnd);
- if (false == aDlg.DoModal())
- break;
- m_pDvdCore->PlayChapterInTitle(aDlg.GetTitle(), aDlg.GetChapter());
- }
- break;
-
- case ID_PLAYBACK_GOTO_TIME:
- {
- CTimeDlg aDlg(m_hInstance, m_hWnd);
-
- DVD_HMSF_TIMECODE time = m_pDvdCore->GetTime();
- aDlg.SetTime(time);
-
- if (false == aDlg.DoModal())
- break;
- m_pDvdCore->PlayTime(aDlg.GetTime());
- }
- break;
-
- case ID_OPTIONS_GETDISCTEXT:
- m_pDvdCore->GetDvdText();
- break;
-
- case ID_OPTIONS_GETAUDIOATTRIBUTES:
- m_pDvdCore->GetAudioAttributes();
- break;
-
- case ID_OPTIONS_GETVIDEOATTRIBUTES:
- m_pDvdCore->GetVideoAttributes();
- break;
-
- case ID_OPTIONS_GETSUBPICTUREATTRIBUTES:
- m_pDvdCore->GetSPAttributes();
- break;
-
- case ID_OPTIONS_SETKARAOKEMIXING:
- {
- CKaraokeDlg aDlg(m_hInstance, m_hWnd);
- aDlg.DoModal(); // all work happens in the dialog code
- }
- break;
-
- default:
- break;
- }
-
- return 0;
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::KeyProc()
- // Desc: This method will process all key presses sent to our application window.
- // At present it passes all of the keys along to the DvdCore but this is where
- // you would implement shortcut keys, etc.
- //------------------------------------------------------------------------------
-
- LRESULT CApp::KeyProc(WPARAM wParam, LPARAM lParam)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::KeyProc()"))) ;
-
- switch (wParam)
- {
- case VK_ESCAPE: // exit full screen
- case VK_RETURN: // activate the currently selected button
- case VK_LEFT: // select the left button
- case VK_RIGHT: // select the right button
- case VK_UP: // select the upper button
- case VK_DOWN: // select the lower button
- return m_pDvdCore->OnKeyEvent(wParam, lParam); // pass these keys on to the Core.
- }
- return DefWindowProc(m_hWnd, WM_KEYUP, wParam, lParam);
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::SelectParentalLevel()
- // Desc: This method is the MessageProc for the Parental Level Dialog. It is used
- // to allow the user to select the parental level setting.
- //
- // The Dialog wrapper class is not used to demonstrate an alternate way to
- // handle dialogs.
- //------------------------------------------------------------------------------
-
- BOOL CALLBACK CApp::SelectParentalLevel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::SelectParentalLevel()"))) ;
-
- switch (message)
- {
- case WM_INITDIALOG:
- g_App.MakeParentLevelList(hDlg, IDC_LEVEL_LIST) ;
- return TRUE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- {
- LONG lLevel ;
- lLevel = SendDlgItemMessage(hDlg, IDC_LEVEL_LIST, LB_GETCURSEL,
- static_cast<WPARAM>(0), static_cast<LPARAM>(0) );
- if (CB_ERR == lLevel)
- DbgLog((LOG_ERROR, 1, TEXT("WARNING: Couldn't get selected parental control level (Error %d)"), lLevel)) ;
- else
- g_App.m_pDvdCore->SetParentalLevel(g_App.m_pParentLevels->GetValue(lLevel)) ;
- }
-
- // Now fall through to just end the dialog
-
- case IDCANCEL:
- EndDialog(hDlg, TRUE);
- return TRUE;
- }
- break;
-
- default:
- break ;
- }
-
- return FALSE;
- }
-
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::UpdateStatus()
- // Desc: This method is notified every time that status of the player changes
- // (Time, title, Chapter, etc.). This invalidates the client rectangle to force
- // a redraw of the screen.
- //------------------------------------------------------------------------------
-
- void CApp::UpdateStatus(void)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::UpdateStatus()"))) ;
-
- RECT Rect;
- if (FALSE != GetClientRect(m_hWnd, &Rect))
- {
- Rect.top += 30; // so we don't redraw the toolbar - 30 is just a rough number
- InvalidateRect(m_hWnd, &Rect, TRUE);
- }
- else
- {
- DWORD res = GetLastError();
- DbgLog((LOG_ERROR, 1, TEXT("GetClientRect failed: %#x"), res)) ;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::DrawStatus()
- // Desc: This method draws our status test (time, title, chapter) on the screen
- //------------------------------------------------------------------------------
-
- void CApp::DrawStatus(HDC hDC)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::DrawStatus()"))) ;
-
- TCHAR location[25];
- wsprintf(location, TEXT("Title: %-6uChapter: %u"), m_pDvdCore->GetTitle(),
- m_pDvdCore->GetChapter());
- TextOut(hDC, 10, 50, location, lstrlen(location));
-
- TCHAR time[15];
- wsprintf(time, TEXT("Time: %02d:%02d:%02d"), m_pDvdCore->GetTime().bHours,
- m_pDvdCore->GetTime().bMinutes, m_pDvdCore->GetTime().bSeconds);
- TextOut(hDC, 10, 65, time, lstrlen(time));
-
- if (timeGetTime() <= (m_dwProhibitedTime + 5000)) // if less than 5 seconds has passed
- {
- SetTextColor(hDC, RGB(255, 0, 0));
- TextOut(hDC, 180, 80, TEXT("Prohibited!"), 11);
- }
- }
-
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::OnSelectDisc()
- // Desc: This method brings up a common file dialog to ask the user to find the
- // dvd disc they wish to watch. We look for the video_ts.ifo file.
- //------------------------------------------------------------------------------
-
- bool CApp::OnSelectDisc()
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::OnSelectDisc()"))) ;
-
- OPENFILENAME ofn ; // structure used by the common file dialog
- TCHAR szFileName[MAX_PATH] ;
-
- // Init the filename buffer with *.ifo
- lstrcpy(szFileName, TEXT("*.ifo")) ;
-
- ZeroMemory(&ofn, sizeof(OPENFILENAME)) ;
- ofn.lStructSize = sizeof(OPENFILENAME) ;
- ofn.hwndOwner = m_hWnd ;
- ofn.lpstrFilter = TEXT("IFO Files\0*.ifo\0All Files\0*.*\0") ;
- ofn.nFilterIndex = 1 ;
- ofn.lpstrFile = szFileName ;
- ofn.nMaxFile = sizeof(szFileName) ;
- ofn.lpstrFileTitle = NULL ;
- ofn.lpstrTitle = TEXT("Select DVD-Video Volume") ;
- ofn.nMaxFileTitle = 0 ;
- ofn.lpstrInitialDir = NULL ;
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY ;
-
- // GetOpenFileName will bring up the common file dialog in open mode
- if (GetOpenFileName(&ofn)) // user specified a file
- {
- return m_pDvdCore->SetDirectory(szFileName);
- }
-
- // Either failed or user hit Esc.
- DWORD dw = CommDlgExtendedError() ;
- DbgLog((LOG_TRACE, 3, TEXT("GetOpenFileName() cancelled/failed with error %lu"), dw)) ;
-
- return false ; // DVD-Video volume not changed
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::Prohibited()
- // Desc: This method is called by the DVDCore whenever an operation is attempted that
- // is prohibited by UOP. We set a time value and then invalidate the rectangle.
- //------------------------------------------------------------------------------
-
- void CApp::Prohibited()
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::Prohibited()"))) ;
-
- m_dwProhibitedTime = timeGetTime();
-
- RECT Rect;
- if (FALSE != GetClientRect(m_hWnd, &Rect))
- {
- Rect.top += 30; // so we don't redraw the toolbar - 30 is just a rough number
- InvalidateRect(m_hWnd, &Rect, TRUE);
- }
- else
- {
- DWORD res = GetLastError();
- DbgLog((LOG_ERROR, 1, TEXT("GetClientRect failed: %#x"), res)) ;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::Exit()
- // Desc: This method is part of IDvdCallBack. It is called by the DVDCore whenever
- // the playback window si closed. We then close down the application.
- //------------------------------------------------------------------------------
-
- void CApp::Exit()
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::Exit()"))) ;
- PostQuitMessage(0);
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::GetAppWindow()
- // Desc: This method is a member of IDVDCallback. It returns the location and size
- // of the player window to the application.
- //------------------------------------------------------------------------------
-
- RECT CApp::GetAppWindow()
- {
- RECT rWindow;
- GetWindowRect(m_hWnd, &rWindow);
- return rWindow;
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CApp::MakeParentLevelList()
- // Desc: This method creates a list of parental levels and adds them to the
- // parental level dialog box's listbox.
- //------------------------------------------------------------------------------
-
- int CApp::MakeParentLevelList(HWND hDlg, int iListID)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CApp::MakeParentalLevelList(0x%lx, %d)"),
- hDlg, iListID)) ;
-
- int iLevels = m_pParentLevels->GetCount() ;
- int iResult ;
-
- // add all defined parental levels
- for (int i = 0 ; i < iLevels ; i++)
- {
- // Add to the listbox now
- iResult = SendDlgItemMessage(hDlg, iListID, LB_ADDSTRING, (WPARAM) 0,
- (LPARAM)(LPVOID) m_pParentLevels->GetName(i)) ;
- if (LB_ERR == iResult || LB_ERRSPACE == iResult)
- {
- DbgLog((LOG_ERROR, 1,
- TEXT("Error (%d) adding parental level '%s'(%d) to list"),
- iResult, m_pParentLevels->GetName(i), i)) ;
- }
- }
-
- if (iLevels > 0)
- {
- iResult = SendDlgItemMessage(hDlg, iListID, LB_SETCURSEL,
- (WPARAM) m_pDvdCore->GetParentalLevel(), (LPARAM) 0) ;
- if (LB_ERR == iResult)
- {
- DbgLog((LOG_ERROR, 1,
- TEXT("WARNING: Couldn't set %ld as selected parent level (Error %d)"),
- m_ulParentCtrlLevel, iResult)) ;
- }
- }
- return iLevels ;
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CDVDLanguages::CDVDLanguages()
- // Desc: This is the constructor. It sets up our lookup table
- // Only 10 languages have been used here as a sample.
- // The list can be extended to include any language listed in ISO 639.
- //------------------------------------------------------------------------------
- CDVDLanguages::CDVDLanguages()
- {
- DbgLog((LOG_TRACE, 5, TEXT("CDVDLanguages::CDVDLanguages()"))) ;
-
- m_lcidCodes[0] = 0x0407 ; m_apszLangNames[0] = TEXT("German") ;
- m_lcidCodes[1] = 0x0409 ; m_apszLangNames[1] = TEXT("English") ;
- m_lcidCodes[2] = 0x040a ; m_apszLangNames[2] = TEXT("Spanish") ;
- m_lcidCodes[3] = 0x040c ; m_apszLangNames[3] = TEXT("French") ;
- m_lcidCodes[4] = 0x0411 ; m_apszLangNames[4] = TEXT("Japanese") ;
- m_lcidCodes[5] = 0x0412 ; m_apszLangNames[5] = TEXT("Korean") ;
- m_lcidCodes[6] = 0x0413 ; m_apszLangNames[6] = TEXT("Dutch") ;
- m_lcidCodes[7] = 0x0816 ; m_apszLangNames[7] = TEXT("Portuguese") ;
- m_lcidCodes[8] = 0x041d ; m_apszLangNames[8] = TEXT("Swedish") ;
- m_lcidCodes[9] = 0x0804 ; m_apszLangNames[9] = TEXT("Chinese") ;
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CDVDLanguages::GetLangString()
- // Desc: This method is our lookup function. It takes an LCID language code
- // and returns an English string language name.
- //------------------------------------------------------------------------------
-
- bool CDVDLanguages::GetLangString(LCID LangCode, PTSTR pszLang, int iMaxLen)
- {
- DbgLog((LOG_TRACE, 5, TEXT("CDVDLanguages::GetLangString()"))) ;
-
- for (int i = 0 ; i < 10 ; i++)
- {
- if (LangCode == m_lcidCodes[i]) // match!!
- {
- if (iMaxLen < lstrlen(m_apszLangNames[i]))
- {
- lstrcpy(pszLang, m_apszLangNames[i]) ;
- return true ; // got a match
- }
- // let it fall through if that fails
- }
- }
- if (iMaxLen < lstrlen(TEXT("Unknown")))
- {
- lstrcpy(pszLang, TEXT("Unknown")) ;
- }
- return false ; // didn't get a match
- }
-
-
- //------------------------------------------------------------------------------
- // Name: CParentLevels::CParentLevels()
- // Desc: This is the constructor for CParentLevels. It can be modified to change
- // the parental levels shown to the user.
- // Remember that the mapping of parental levels to MPAA ratings shown here
- // is only valid for the U.S. and Canada. In other countries, the parental
- // levels will have different specific meanings, although parental level 1
- // is always the least restrictive level and level 8 is the most restrictive.
- //------------------------------------------------------------------------------
-
- CParentLevels::CParentLevels()
- {
- DbgLog((LOG_TRACE, 5, TEXT("CParentLevels::CParentLevels()"))) ;
-
- m_iCount = LEVELS ;
- m_alpszNames[0] = TEXT(" G ") ; m_aiValues[0] = 1 ;
- m_alpszNames[1] = TEXT(" PG ") ; m_aiValues[1] = 3 ;
- m_alpszNames[2] = TEXT(" PG-13 ") ; m_aiValues[2] = 4 ;
- m_alpszNames[3] = TEXT(" R ") ; m_aiValues[3] = 6 ;
- m_alpszNames[4] = TEXT(" NC-17 ") ; m_aiValues[4] = 7 ;
- m_alpszNames[5] = TEXT(" Not Rated ") ; m_aiValues[5] = 8 ;
- }
-
-
-
-