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.

2317 lines
58 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: app.cpp
  3. *
  4. * A simple Video CD player
  5. *
  6. *
  7. * Created: dd-mm-94
  8. * Author: Stephen Estrop [StephenE]
  9. *
  10. * Copyright (c) 1994 - 1999 Microsoft Corporation. All Rights Reserved.
  11. \**************************************************************************/
  12. #include <streams.h>
  13. #include <atlbase.h>
  14. #include <atlconv.cpp>
  15. #include <mmreg.h>
  16. #include <commctrl.h>
  17. #include "project.h"
  18. #include <initguid.h>
  19. #include "mpgcodec.h"
  20. #include <stdarg.h>
  21. #include <stdio.h>
  22. /* -------------------------------------------------------------------------
  23. ** Global variables that are initialized at run time and then stay constant.
  24. ** -------------------------------------------------------------------------
  25. */
  26. HINSTANCE hInst;
  27. HICON hIconVideoCd;
  28. HWND hwndApp;
  29. HWND g_hwndToolbar;
  30. HWND g_hwndStatusbar;
  31. HWND g_hwndTrackbar;
  32. CMpegMovie *pMpegMovie;
  33. double g_TrackBarScale = 1.0;
  34. BOOL g_bUseThreadedGraph;
  35. BOOL g_bPlay = FALSE;
  36. int dyToolbar, dyStatusbar, dyTrackbar;
  37. MSR_DUMPPROC *lpDumpProc;
  38. MSR_CONTROLPROC *lpControlProc;
  39. HINSTANCE hInstMeasure;
  40. /* -------------------------------------------------------------------------
  41. ** True Globals - these may change during execution of the program.
  42. ** -------------------------------------------------------------------------
  43. */
  44. TCHAR g_achFileName[MAX_PATH];
  45. TCHAR g_szPerfLog[MAX_PATH];
  46. OPENFILENAME ofn;
  47. DWORD g_State = VCD_NO_CD;
  48. RECENTFILES aRecentFiles[MAX_RECENT_FILES];
  49. int nRecentFiles;
  50. LONG lMovieOrgX, lMovieOrgY;
  51. int g_TimeFormat = IDM_TIME;
  52. HANDLE hRenderLog = INVALID_HANDLE_VALUE;
  53. TCHAR * g_szOtherStuff;
  54. BOOL g_IsNT;
  55. /* -------------------------------------------------------------------------
  56. ** Constants
  57. ** -------------------------------------------------------------------------
  58. */
  59. const TCHAR szClassName[] = TEXT("SJE_VCDPlayer_CLASS");
  60. const TCHAR g_szNULL[] = TEXT("\0");
  61. const TCHAR g_szEmpty[] = TEXT("");
  62. const TCHAR g_szMovieX[] = TEXT("MovieOriginX");
  63. const TCHAR g_szMovieY[] = TEXT("MovieOriginY");
  64. /*
  65. ** these values are defined by the UI gods...
  66. */
  67. const int dxBitmap = 16;
  68. const int dyBitmap = 15;
  69. const int dxButtonSep = 8;
  70. const TCHAR g_chNULL = TEXT('\0');
  71. const TBBUTTON tbButtons[DEFAULT_TBAR_SIZE] = {
  72. { IDX_SEPARATOR, 1, 0, TBSTYLE_SEP },
  73. { IDX_1, IDM_MOVIE_PLAY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  74. { IDX_2, IDM_MOVIE_PAUSE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  75. { IDX_3, IDM_MOVIE_STOP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  76. { IDX_SEPARATOR, 2, 0, TBSTYLE_SEP },
  77. { IDX_4, IDM_MOVIE_PREVTRACK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  78. { IDX_5, IDM_MOVIE_SKIP_BACK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  79. { IDX_6, IDM_MOVIE_SKIP_FORE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  80. { IDX_7, IDM_MOVIE_NEXTTRACK, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  81. { IDX_SEPARATOR, 3, 0, TBSTYLE_SEP },
  82. { IDX_9, IDM_PERF_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  83. { IDX_10, IDM_PERF_DUMP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0, 0, -1 },
  84. { IDX_SEPARATOR, 4, 0, TBSTYLE_SEP },
  85. { IDX_11, IDM_FULL_SCREEN, TBSTATE_ENABLED, TBSTYLE_CHECK, 0, 0, 0, -1 }
  86. };
  87. const int CX_DEFAULT = 310;
  88. const int CY_DEFAULT = 120;
  89. const int CX_MOVIE_DEFAULT = 352;
  90. const int CY_MOVIE_DEFAULT = 120;
  91. /******************************Public*Routine******************************\
  92. * WinMain
  93. *
  94. *
  95. * Windows recognizes this function by name as the initial entry point
  96. * for the program. This function calls the application initialization
  97. * routine, if no other instance of the program is running, and always
  98. * calls the instance initialization routine. It then executes a message
  99. * retrieval and dispatch loop that is the top-level control structure
  100. * for the remainder of execution. The loop is terminated when a WM_QUIT
  101. * message is received, at which time this function exits the application
  102. * instance by returning the value passed by PostQuitMessage().
  103. *
  104. * If this function must abort before entering the message loop, it
  105. * returns the conventional value NULL.
  106. *
  107. *
  108. *
  109. * History:
  110. * dd-mm-94 - StephenE - Created
  111. *
  112. \**************************************************************************/
  113. int PASCAL
  114. WinMain(
  115. HINSTANCE hInstance,
  116. HINSTANCE hPrevInstance,
  117. LPSTR lpCmdLineOld,
  118. int nCmdShow
  119. )
  120. {
  121. USES_CONVERSION;
  122. lstrcpy(g_szPerfLog, TEXT("c:\\perfdata.log"));
  123. LPTSTR lpCmdLine = A2T(lpCmdLineOld);
  124. if ( !hPrevInstance ) {
  125. if ( !InitApplication( hInstance ) ) {
  126. return FALSE;
  127. }
  128. }
  129. /*
  130. ** Perform initializations that apply to a specific instance
  131. */
  132. if ( !InitInstance( hInstance, nCmdShow ) ) {
  133. return FALSE;
  134. }
  135. /* Look for options */
  136. while (lpCmdLine && (*lpCmdLine == '-' || *lpCmdLine == '/')) {
  137. if (lpCmdLine[1] == 'T') {
  138. // No threaded graph
  139. g_bUseThreadedGraph = TRUE;
  140. lpCmdLine += 2;
  141. } else if (lpCmdLine[1] == 'P') {
  142. g_bPlay = TRUE;
  143. lpCmdLine += 2;
  144. } else {
  145. break;
  146. }
  147. while (lpCmdLine[0] == ' ') {
  148. lpCmdLine++;
  149. }
  150. }
  151. if (lpCmdLine != NULL && lstrlen(lpCmdLine) > 0) {
  152. ProcessOpen(lpCmdLine, g_bPlay);
  153. SetPlayButtonsEnableState();
  154. }
  155. /*
  156. ** Acquire and dispatch messages until a WM_QUIT message is received.
  157. */
  158. return DoMainLoop();
  159. }
  160. /*****************************Private*Routine******************************\
  161. * DoMainLoop
  162. *
  163. * Process the main message loop
  164. *
  165. * History:
  166. * dd-mm-94 - StephenE - Created
  167. *
  168. \**************************************************************************/
  169. int
  170. DoMainLoop(
  171. void
  172. )
  173. {
  174. MSG msg;
  175. HANDLE ahObjects[1]; // handles that need to be waited on
  176. const int cObjects = 1; // no of objects that we are waiting on
  177. HACCEL haccel = LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCELERATOR));
  178. //
  179. // message loop lasts until we get a WM_QUIT message
  180. // upon which we shall return from the function
  181. //
  182. for ( ;; ) {
  183. if (pMpegMovie != NULL) {
  184. ahObjects[0] = pMpegMovie->GetMovieEventHandle();
  185. }
  186. else {
  187. ahObjects[0] = NULL;
  188. }
  189. if (ahObjects[0] == NULL) {
  190. WaitMessage();
  191. }
  192. else {
  193. //
  194. // wait for any message sent or posted to this queue
  195. // or for a graph notification
  196. //
  197. DWORD result;
  198. result = MsgWaitForMultipleObjects(cObjects, ahObjects, FALSE,
  199. INFINITE, QS_ALLINPUT);
  200. if (result != (WAIT_OBJECT_0 + cObjects)) {
  201. if (result == WAIT_OBJECT_0) {
  202. VideoCd_OnGraphNotify();
  203. }
  204. continue;
  205. }
  206. }
  207. //
  208. // When here, we either have a message or no event handle
  209. // has been created yet.
  210. //
  211. // read all of the messages in this next loop
  212. // removing each message as we read it
  213. //
  214. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  215. if (msg.message == WM_QUIT) {
  216. return (int) msg.wParam;
  217. }
  218. if (!TranslateAccelerator(hwndApp, haccel, &msg)) {
  219. TranslateMessage(&msg);
  220. DispatchMessage(&msg);
  221. }
  222. }
  223. }
  224. } // DoMainLoop
  225. //
  226. // InitAboutString
  227. //
  228. // Obtains the version information from the binary file. Note that if
  229. // we fail we just return. The template for the about dialog has a
  230. // "Version not available" as default.
  231. //
  232. TCHAR *InitAboutString()
  233. {
  234. //
  235. // Find the version of this binary
  236. //
  237. TCHAR achFileName[128];
  238. if ( !GetModuleFileName(hInst, achFileName, sizeof(achFileName)) )
  239. return((TCHAR *)g_szEmpty);
  240. DWORD dwTemp;
  241. DWORD dwVerSize = GetFileVersionInfoSize( achFileName, &dwTemp );
  242. if ( !dwVerSize)
  243. return((TCHAR *)g_szEmpty);
  244. HLOCAL hTemp = LocalAlloc( LHND, dwVerSize );
  245. if (!hTemp)
  246. return((TCHAR *)g_szEmpty);
  247. LPVOID lpvVerBuffer = LocalLock( hTemp );
  248. if (!lpvVerBuffer) {
  249. LocalFree( hTemp );
  250. return((TCHAR *)g_szEmpty);
  251. }
  252. if ( !GetFileVersionInfo( achFileName, 0L, dwVerSize, lpvVerBuffer ) ) {
  253. LocalUnlock( hTemp );
  254. LocalFree( hTemp );
  255. return((TCHAR *)g_szEmpty);
  256. }
  257. // "040904E4" is the code page for US English (Andrew believes).
  258. LPVOID lpvValue;
  259. UINT uLen;
  260. if (VerQueryValue( lpvVerBuffer,
  261. TEXT("\\StringFileInfo\\040904E4\\ProductVersion"),
  262. (LPVOID *) &lpvValue, &uLen)) {
  263. //
  264. // Get creation date of executable (date of build)
  265. //
  266. WIN32_FIND_DATA FindFileData;
  267. HANDLE hFind = FindFirstFile(achFileName, &FindFileData);
  268. ASSERT(hFind != INVALID_HANDLE_VALUE);
  269. FindClose(hFind);
  270. FILETIME ModTime = FindFileData.ftLastWriteTime;
  271. SYSTEMTIME SysTime;
  272. FileTimeToSystemTime(&ModTime,&SysTime);
  273. char szBuildDate[20];
  274. sprintf(szBuildDate, " - Build: %2.2u%2.2u%2.2u",
  275. SysTime.wYear % 100, SysTime.wMonth, SysTime.wDay);
  276. strcat((LPSTR) lpvValue, szBuildDate);
  277. }
  278. TCHAR *szAbout = (TCHAR *) _strdup((LPSTR) lpvValue);
  279. LocalUnlock( hTemp );
  280. LocalFree( hTemp );
  281. return(szAbout);
  282. }
  283. /*****************************Private*Routine******************************\
  284. * InitApplication(HANDLE)
  285. *
  286. * This function is called at initialization time only if no other
  287. * instances of the application are running. This function performs
  288. * initialization tasks that can be done once for any number of running
  289. * instances.
  290. *
  291. * In this case, we initialize a window class by filling out a data
  292. * structure of type WNDCLASS and calling the Windows RegisterClass()
  293. * function. Since all instances of this application use the same window
  294. * class, we only need to do this when the first instance is initialized.
  295. *
  296. * History:
  297. * dd-mm-94 - StephenE - Created
  298. *
  299. \**************************************************************************/
  300. BOOL
  301. InitApplication(
  302. HINSTANCE hInstance
  303. )
  304. {
  305. WNDCLASS wc;
  306. hInstMeasure = LoadLibraryA("measure.dll");
  307. if (hInstMeasure) {
  308. *(FARPROC *)&lpDumpProc = GetProcAddress(hInstMeasure, "Msr_Dump");
  309. *(FARPROC *)&lpControlProc = GetProcAddress(hInstMeasure, "Msr_Control");
  310. }
  311. /*
  312. ** Fill in window class structure with parameters that describe the
  313. ** main window.
  314. */
  315. hIconVideoCd = LoadIcon( hInstance, MAKEINTRESOURCE(IDR_VIDEOCD_ICON) );
  316. wc.style = CS_VREDRAW | CS_HREDRAW;
  317. wc.lpfnWndProc = VideoCdWndProc;
  318. wc.cbClsExtra = 0;
  319. wc.cbWndExtra = 0;
  320. wc.hInstance = hInstance;
  321. wc.hIcon = hIconVideoCd;
  322. wc.hCursor = LoadCursor( NULL, IDC_ARROW );
  323. wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
  324. wc.lpszMenuName = MAKEINTRESOURCE( IDR_MAIN_MENU);
  325. wc.lpszClassName = szClassName;
  326. OSVERSIONINFO OSVer;
  327. OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  328. BOOL bRet = GetVersionEx((LPOSVERSIONINFO) &OSVer);
  329. ASSERT(bRet);
  330. g_IsNT = (OSVer.dwPlatformId == VER_PLATFORM_WIN32_NT);
  331. g_szOtherStuff = InitAboutString();
  332. /*
  333. ** Register the window class and return success/failure code.
  334. */
  335. return RegisterClass( &wc );
  336. }
  337. /*****************************Private*Routine******************************\
  338. * InitInstance
  339. *
  340. *
  341. * This function is called at initialization time for every instance of
  342. * this application. This function performs initialization tasks that
  343. * cannot be shared by multiple instances.
  344. *
  345. * In this case, we save the instance handle in a static variable and
  346. * create and display the main program window.
  347. *
  348. *
  349. * History:
  350. * dd-mm-94 - StephenE - Created
  351. *
  352. \**************************************************************************/
  353. BOOL
  354. InitInstance(
  355. HINSTANCE hInstance,
  356. int nCmdShow
  357. )
  358. {
  359. HWND hwnd;
  360. RECT rc;
  361. POINT pt;
  362. /*
  363. ** Save the instance handle in static variable, which will be used in
  364. ** many subsequence calls from this application to Windows.
  365. */
  366. hInst = hInstance;
  367. if ( ! LoadWindowPos(&rc))
  368. rc.left = rc.top = CW_USEDEFAULT;
  369. /*
  370. ** Create a main window for this application instance.
  371. */
  372. hwnd = CreateWindow( szClassName, IdStr(STR_APP_TITLE),
  373. WS_THICKFRAME | WS_POPUP | WS_CAPTION |
  374. WS_SYSMENU | WS_MINIMIZEBOX,
  375. rc.left, rc.top,
  376. rc.right - rc.left, rc.bottom - rc.top,
  377. NULL, NULL, hInstance, NULL );
  378. /*
  379. ** If window could not be created, return "failure"
  380. */
  381. if ( NULL == hwnd ) {
  382. return FALSE;
  383. }
  384. hwndApp = hwnd;
  385. nRecentFiles = GetRecentFiles(nRecentFiles);
  386. pt.x = lMovieOrgX = ProfileIntIn(g_szMovieX, 0);
  387. pt.y = lMovieOrgY = ProfileIntIn(g_szMovieY, 0);
  388. // if we fail to get the working area (screen-tray), then assume
  389. // the screen is 640x480
  390. //
  391. if (!SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, FALSE)) {
  392. rc.top = rc.left = 0;
  393. rc.right = 640;
  394. rc.bottom = 480;
  395. }
  396. if (!PtInRect(&rc, pt)) {
  397. lMovieOrgX = lMovieOrgY = 0L;
  398. }
  399. /*
  400. ** Make the window visible; update its client area; and return "success"
  401. */
  402. SetPlayButtonsEnableState();
  403. ShowWindow( hwnd, nCmdShow );
  404. UpdateWindow( hwnd );
  405. return TRUE;
  406. }
  407. /******************************Public*Routine******************************\
  408. * VideoCdWndProc
  409. *
  410. *
  411. *
  412. * History:
  413. * dd-mm-94 - StephenE - Created
  414. *
  415. \**************************************************************************/
  416. LRESULT CALLBACK
  417. VideoCdWndProc(
  418. HWND hwnd,
  419. UINT message,
  420. WPARAM wParam,
  421. LPARAM lParam
  422. )
  423. {
  424. switch ( message ) {
  425. HANDLE_MSG( hwnd, WM_CREATE, VideoCd_OnCreate );
  426. HANDLE_MSG( hwnd, WM_PAINT, VideoCd_OnPaint );
  427. HANDLE_MSG( hwnd, WM_COMMAND, VideoCd_OnCommand );
  428. HANDLE_MSG( hwnd, WM_CLOSE, VideoCd_OnClose );
  429. HANDLE_MSG( hwnd, WM_QUERYENDSESSION, VideoCd_OnQueryEndSession );
  430. HANDLE_MSG( hwnd, WM_DESTROY, VideoCd_OnDestroy );
  431. HANDLE_MSG( hwnd, WM_SIZE, VideoCd_OnSize );
  432. HANDLE_MSG( hwnd, WM_SYSCOLORCHANGE, VideoCd_OnSysColorChange );
  433. HANDLE_MSG( hwnd, WM_MENUSELECT, VideoCd_OnMenuSelect );
  434. HANDLE_MSG( hwnd, WM_INITMENUPOPUP, VideoCd_OnInitMenuPopup );
  435. HANDLE_MSG( hwnd, WM_HSCROLL, VideoCd_OnHScroll );
  436. HANDLE_MSG( hwnd, WM_TIMER, VideoCd_OnTimer );
  437. HANDLE_MSG( hwnd, WM_NOTIFY, VideoCd_OnNotify );
  438. HANDLE_MSG( hwnd, WM_DROPFILES, VideoCd_OnDropFiles);
  439. HANDLE_MSG( hwnd, WM_KEYUP, VideoCd_OnKeyUp);
  440. // Note: we do not use HANDLE_MSG here as we want to call
  441. // DefWindowProc after we have notifed the FilterGraph Resource Manager,
  442. // otherwise our window will not finish its activation process.
  443. case WM_ACTIVATE: VideoCd_OnActivate(hwnd, wParam, lParam);
  444. // IMPORTANT - let this drop through to DefWindowProc
  445. default:
  446. return DefWindowProc( hwnd, message, wParam, lParam );
  447. }
  448. return 0L;
  449. }
  450. /*****************************Private*Routine******************************\
  451. * VideoCd_OnCreate
  452. *
  453. *
  454. *
  455. * History:
  456. * 18-11-93 - StephenE - Created
  457. *
  458. \**************************************************************************/
  459. BOOL
  460. VideoCd_OnCreate(
  461. HWND hwnd,
  462. LPCREATESTRUCT lpCreateStruct
  463. )
  464. {
  465. RECT rc;
  466. int Pane[2];
  467. InitCommonControls();
  468. /*
  469. ** Create the toolbar and statusbar.
  470. */
  471. g_hwndToolbar = CreateToolbarEx( hwnd,
  472. WS_VISIBLE | WS_CHILD |
  473. TBSTYLE_TOOLTIPS | CCS_NODIVIDER,
  474. ID_TOOLBAR, NUMBER_OF_BITMAPS,
  475. hInst, IDR_TOOLBAR, tbButtons,
  476. DEFAULT_TBAR_SIZE, dxBitmap, dyBitmap,
  477. dxBitmap, dyBitmap, sizeof(TBBUTTON) );
  478. if ( g_hwndToolbar == NULL ) {
  479. return FALSE;
  480. }
  481. g_hwndStatusbar = CreateStatusWindow( WS_VISIBLE | WS_CHILD | CCS_BOTTOM,
  482. TEXT("Example Text"),
  483. hwnd, ID_STATUSBAR );
  484. GetWindowRect(g_hwndToolbar, &rc);
  485. dyToolbar = rc.bottom - rc.top;
  486. GetWindowRect(g_hwndStatusbar, &rc);
  487. dyStatusbar = rc.bottom - rc.top;
  488. dyTrackbar = 30;
  489. GetClientRect(hwnd, &rc);
  490. Pane[0] = (rc.right - rc.left) / 2 ;
  491. Pane[1] = -1;
  492. SendMessage(g_hwndStatusbar, SB_SETPARTS, 2, (LPARAM)Pane);
  493. g_hwndTrackbar = CreateWindowEx(0, TRACKBAR_CLASS, TEXT("Trackbar Control"),
  494. WS_CHILD | WS_VISIBLE |
  495. TBS_AUTOTICKS | TBS_ENABLESELRANGE,
  496. LEFT_MARGIN, dyToolbar - 1,
  497. (rc.right - rc.left) - (2* LEFT_MARGIN),
  498. dyTrackbar, hwnd, (HMENU)ID_TRACKBAR,
  499. hInst, NULL);
  500. SetDurationLength((REFTIME)0);
  501. SetCurrentPosition((REFTIME)0);
  502. SetTimer(hwnd, StatusTimer, 500, NULL);
  503. if (g_hwndStatusbar == NULL || g_hwndTrackbar == NULL) {
  504. return FALSE;
  505. }
  506. // accept filemanager WM_DROPFILES messages
  507. DragAcceptFiles(hwnd, TRUE);
  508. return TRUE;
  509. }
  510. /*****************************Private*Routine******************************\
  511. * VideoCd_OnActivate
  512. *
  513. *
  514. *
  515. * History:
  516. * 18/9/1996 - SteveDav - Created
  517. *
  518. \**************************************************************************/
  519. void
  520. VideoCd_OnActivate(
  521. HWND hwnd,
  522. WPARAM wParam,
  523. LPARAM lParam
  524. )
  525. {
  526. if ((UINT)LOWORD(wParam)) {
  527. // we are being activated - tell the Filter graph (for Sound follows focus)
  528. if (pMpegMovie) {
  529. pMpegMovie->SetFocus();
  530. }
  531. }
  532. }
  533. /*****************************Private*Routine******************************\
  534. * VideoCd_OnKeyUp
  535. *
  536. *
  537. *
  538. * History:
  539. * 23/3/1996 - AnthonyP - Created
  540. *
  541. \**************************************************************************/
  542. void
  543. VideoCd_OnKeyUp(
  544. HWND hwnd,
  545. UINT vk,
  546. BOOL fDown,
  547. int cRepeat,
  548. UINT flags
  549. )
  550. {
  551. // Catch escape sequences to stop fullscreen mode
  552. if (vk == VK_ESCAPE) {
  553. if (pMpegMovie) {
  554. pMpegMovie->SetFullScreenMode(FALSE);
  555. SetPlayButtonsEnableState();
  556. }
  557. }
  558. }
  559. /*****************************Private*Routine******************************\
  560. * VideoCd_OnHScroll
  561. *
  562. *
  563. *
  564. * History:
  565. * 11/3/1995 - StephenE - Created
  566. *
  567. \**************************************************************************/
  568. void
  569. VideoCd_OnHScroll(
  570. HWND hwnd,
  571. HWND hwndCtl,
  572. UINT code,
  573. int pos
  574. )
  575. {
  576. static BOOL fWasPlaying = FALSE;
  577. static BOOL fBeginScroll = FALSE;
  578. if (pMpegMovie == NULL) {
  579. return;
  580. }
  581. if (hwndCtl == g_hwndTrackbar) {
  582. REFTIME rtCurrPos;
  583. REFTIME rtTrackPos;
  584. REFTIME rtDuration;
  585. pos = (int)SendMessage(g_hwndTrackbar, TBM_GETPOS, 0, 0);
  586. rtTrackPos = (REFTIME)pos * g_TrackBarScale;
  587. switch (code) {
  588. case TB_BOTTOM:
  589. rtDuration = pMpegMovie->GetDuration();
  590. rtCurrPos = pMpegMovie->GetCurrentPosition();
  591. VcdPlayerSeekCmd(rtDuration - rtCurrPos);
  592. SetCurrentPosition(pMpegMovie->GetCurrentPosition());
  593. break;
  594. case TB_TOP:
  595. rtCurrPos = pMpegMovie->GetCurrentPosition();
  596. VcdPlayerSeekCmd(-rtCurrPos);
  597. SetCurrentPosition(pMpegMovie->GetCurrentPosition());
  598. break;
  599. case TB_LINEDOWN:
  600. VcdPlayerSeekCmd(10.0);
  601. SetCurrentPosition(pMpegMovie->GetCurrentPosition());
  602. break;
  603. case TB_LINEUP:
  604. VcdPlayerSeekCmd(-10.0);
  605. SetCurrentPosition(pMpegMovie->GetCurrentPosition());
  606. break;
  607. case TB_ENDTRACK:
  608. fBeginScroll = FALSE;
  609. if (fWasPlaying) {
  610. VcdPlayerPauseCmd();
  611. fWasPlaying = FALSE;
  612. }
  613. break;
  614. case TB_THUMBTRACK:
  615. if (!fBeginScroll) {
  616. fBeginScroll = TRUE;
  617. fWasPlaying = (g_State & VCD_PLAYING);
  618. if (fWasPlaying) {
  619. VcdPlayerPauseCmd();
  620. }
  621. }
  622. case TB_PAGEUP:
  623. case TB_PAGEDOWN:
  624. rtCurrPos = pMpegMovie->GetCurrentPosition();
  625. VcdPlayerSeekCmd(rtTrackPos - rtCurrPos);
  626. SetCurrentPosition(pMpegMovie->GetCurrentPosition());
  627. break;
  628. }
  629. }
  630. }
  631. /*****************************Private*Routine******************************\
  632. * VideoCd_OnTimer
  633. *
  634. *
  635. *
  636. * History:
  637. * dd-mm-95 - StephenE - Created
  638. *
  639. \**************************************************************************/
  640. void
  641. VideoCd_OnTimer(
  642. HWND hwnd,
  643. UINT id
  644. )
  645. {
  646. HDC hdc;
  647. if (pMpegMovie && pMpegMovie->StatusMovie() == MOVIE_PLAYING) {
  648. switch (id) {
  649. case StatusTimer:
  650. SetCurrentPosition(pMpegMovie->GetCurrentPosition());
  651. break;
  652. case PerformanceTimer:
  653. hdc = GetDC(hwnd);
  654. DrawStats(hdc);
  655. ReleaseDC(hwnd, hdc);
  656. break;
  657. }
  658. }
  659. }
  660. /*****************************Private*Routine******************************\
  661. * DrawStats
  662. *
  663. * Gets some stats from the decoder and displays them on the display.
  664. *
  665. * History:
  666. * dd-mm-95 - StephenE - Created
  667. *
  668. \**************************************************************************/
  669. BOOL
  670. DrawStats(
  671. HDC hdc
  672. )
  673. {
  674. HFONT hFont;
  675. TCHAR Text[1024];
  676. TCHAR szSurface[64];
  677. RECT rc;
  678. DWORD IFramesDecoded;
  679. DWORD PFramesDecoded;
  680. DWORD BFramesDecoded;
  681. DWORD IFramesSkipped;
  682. DWORD PFramesSkipped;
  683. DWORD BFramesSkipped;
  684. DWORD dwTotalFrames;
  685. DWORD dwTotalDecoded;
  686. DWORD dwSurface;
  687. int cFramesDropped;
  688. int cFramesDrawn;
  689. int iAvgFrameRate;
  690. int iAvgFrameRateFraction;
  691. int iAvgFrameRateWhole;
  692. int iJitter;
  693. int iSyncAvg;
  694. int iSyncDev;
  695. BOOL fClipped;
  696. BOOL fHalfWidth;
  697. if (pMpegMovie == NULL) {
  698. return FALSE;
  699. }
  700. GetAdjustedClientRect(&rc);
  701. hFont = (HFONT)SelectObject(hdc, GetStockObject(ANSI_FIXED_FONT));
  702. if (pMpegMovie->pMpegDecoder) {
  703. pMpegMovie->pMpegDecoder->get_OutputFormat(&dwSurface);
  704. pMpegMovie->pMpegDecoder->get_FrameStatistics(
  705. &IFramesDecoded, &PFramesDecoded,
  706. &BFramesDecoded, &IFramesSkipped,
  707. &PFramesSkipped, &BFramesSkipped);
  708. }
  709. else {
  710. IFramesDecoded = PFramesDecoded = BFramesDecoded = 0;
  711. IFramesSkipped = PFramesSkipped = BFramesSkipped = 0;
  712. dwSurface = MM_RGB8_DIB;
  713. }
  714. fClipped = ((dwSurface & MM_CLIPPED) == MM_CLIPPED);
  715. fHalfWidth = ((dwSurface & MM_HRESOLUTION) == MM_HRESOLUTION);
  716. dwSurface &= ~(MM_HRESOLUTION | MM_CLIPPED);
  717. switch (dwSurface) {
  718. case MM_NOCONV:
  719. lstrcpy(szSurface, TEXT("MM_NOCONV"));
  720. break;
  721. case MM_420PL:
  722. lstrcpy(szSurface, TEXT("MM_420PL"));
  723. break;
  724. case MM_420PL_:
  725. lstrcpy(szSurface, TEXT("MM_420PL_"));
  726. break;
  727. case MM_422PK:
  728. lstrcpy(szSurface, TEXT("MM_422PK"));
  729. break;
  730. case MM_422PK_:
  731. lstrcpy(szSurface, TEXT("MM_422PK_"));
  732. break;
  733. case MM_422SPK:
  734. lstrcpy(szSurface, TEXT("MM_422SPK"));
  735. break;
  736. case MM_422SPK_:
  737. lstrcpy(szSurface, TEXT("MM_422SPK_"));
  738. break;
  739. case MM_411PK:
  740. lstrcpy(szSurface, TEXT("MM_411PK"));
  741. break;
  742. case MM_410PL_:
  743. lstrcpy(szSurface, TEXT("MM_410PL_"));
  744. break;
  745. case MM_Y_DIB:
  746. lstrcpy(szSurface, TEXT("MM_Y_DIB"));
  747. break;
  748. case MM_RGB24_DIB:
  749. lstrcpy(szSurface, TEXT("MM_RGB24_DIB"));
  750. break;
  751. case MM_RGB32_DIB:
  752. lstrcpy(szSurface, TEXT("MM_RGB32_DIB"));
  753. break;
  754. case MM_RGB565_DIB:
  755. lstrcpy(szSurface, TEXT("MM_RGB565_DIB"));
  756. break;
  757. case MM_RGB555_DIB:
  758. lstrcpy(szSurface, TEXT("MM_RGB555_DIB"));
  759. break;
  760. case MM_RGB8_DIB:
  761. lstrcpy(szSurface, TEXT("MM_RGB8_DIB"));
  762. break;
  763. case MM_Y_DDB:
  764. lstrcpy(szSurface, TEXT("MM_Y_DDB"));
  765. break;
  766. case MM_RGB24_DDB:
  767. lstrcpy(szSurface, TEXT("MM_RGB24_DDB"));
  768. break;
  769. case MM_RGB32_DDB:
  770. lstrcpy(szSurface, TEXT("MM_RGB32_DDB"));
  771. break;
  772. case MM_RGB565_DDB:
  773. lstrcpy(szSurface, TEXT("MM_RGB565_DDB"));
  774. break;
  775. case MM_RGB555_DDB:
  776. lstrcpy(szSurface, TEXT("MM_RGB555_DDB"));
  777. break;
  778. case MM_RGB8_DDB:
  779. lstrcpy(szSurface, TEXT("MM_RGB8_DDB"));
  780. break;
  781. }
  782. if (fHalfWidth) {
  783. lstrcat(szSurface, TEXT(" Decimated"));
  784. }
  785. if (fClipped) {
  786. lstrcat(szSurface, TEXT(" Clipped"));
  787. }
  788. dwTotalDecoded = IFramesDecoded + PFramesDecoded + BFramesDecoded;
  789. dwTotalFrames = IFramesSkipped + PFramesSkipped + BFramesSkipped
  790. + dwTotalDecoded;
  791. if (pMpegMovie->pVideoRenderer) {
  792. pMpegMovie->pVideoRenderer->get_FramesDroppedInRenderer(&cFramesDropped);
  793. pMpegMovie->pVideoRenderer->get_FramesDrawn(&cFramesDrawn);
  794. pMpegMovie->pVideoRenderer->get_AvgFrameRate(&iAvgFrameRate);
  795. iAvgFrameRateWhole = iAvgFrameRate / 100;
  796. iAvgFrameRateFraction = iAvgFrameRate % 100;
  797. pMpegMovie->pVideoRenderer->get_Jitter(&iJitter);
  798. pMpegMovie->pVideoRenderer->get_AvgSyncOffset(&iSyncAvg);
  799. pMpegMovie->pVideoRenderer->get_DevSyncOffset(&iSyncDev);
  800. }
  801. else {
  802. cFramesDropped = 0;
  803. cFramesDrawn = 0;
  804. iAvgFrameRate = 0;
  805. iAvgFrameRateWhole = 0;
  806. iAvgFrameRateFraction = 0;
  807. iJitter = 0;
  808. iSyncAvg = 0;
  809. iSyncDev = 0;
  810. }
  811. wsprintf(Text,
  812. TEXT("Decoded %08.8ld out of %08.8ld frames\r\n")
  813. TEXT("Proportion decoded = %d%%\r\n")
  814. TEXT("Avg Frame Rate = %d.%02d fps\r\n")
  815. TEXT("Frames drawn by renderer = %d\r\n")
  816. TEXT("Frames dropped by renderer = %d\r\n")
  817. TEXT("Frame jitter = %4d mSec\r\n")
  818. TEXT("Avg Sync Offset (neg = early) = %4d mSec\r\n")
  819. TEXT("Std Dev Sync Offset = %4d mSec\r\n")
  820. TEXT("Surface type = %s\r\n")
  821. TEXT("I Frames: Decoded %8.8ld Skipped %8.8ld\r\n")
  822. TEXT("P Frames: Decoded %8.8ld Skipped %8.8ld\r\n")
  823. TEXT("B Frames: Decoded %8.8ld Skipped %8.8ld\r\n"),
  824. dwTotalDecoded, dwTotalFrames,
  825. (100 * dwTotalDecoded) / (dwTotalFrames ? dwTotalFrames : 1),
  826. iAvgFrameRateWhole, iAvgFrameRateFraction,
  827. cFramesDrawn, cFramesDropped,
  828. iJitter, iSyncAvg, iSyncDev,
  829. szSurface,
  830. IFramesDecoded, IFramesSkipped,
  831. PFramesDecoded, PFramesSkipped,
  832. BFramesDecoded, BFramesSkipped);
  833. COLORREF clr = SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
  834. ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
  835. DrawText(hdc, Text, -1, &rc, DT_LEFT | DT_BOTTOM);
  836. SetBkColor(hdc, clr);
  837. SelectObject(hdc, hFont);
  838. return TRUE;
  839. }
  840. /*****************************Private*Routine******************************\
  841. * VideoCd_OnPaint
  842. *
  843. *
  844. *
  845. * History:
  846. * 18-11-93 - StephenE - Created
  847. *
  848. \**************************************************************************/
  849. void
  850. VideoCd_OnPaint(
  851. HWND hwnd
  852. )
  853. {
  854. PAINTSTRUCT ps;
  855. HDC hdc;
  856. RECT rc;
  857. /*
  858. ** Draw a frame around the movie playback area.
  859. */
  860. hdc = BeginPaint( hwnd, &ps );
  861. if (!DrawStats(hdc)) {
  862. GetClientRect(hwnd, &rc);
  863. FillRect(hdc, &rc, (HBRUSH)(COLOR_BTNFACE + 1));
  864. }
  865. EndPaint( hwnd, &ps );
  866. }
  867. /*****************************Private*Routine******************************\
  868. * VideoCd_OnCommand
  869. *
  870. *
  871. *
  872. * History:
  873. * 18-11-93 - StephenE - Created
  874. *
  875. \**************************************************************************/
  876. void
  877. VideoCd_OnCommand(
  878. HWND hwnd,
  879. int id,
  880. HWND hwndCtl,
  881. UINT codeNotify
  882. )
  883. {
  884. switch (id) {
  885. case IDM_FILE_SET_LOG:
  886. VcdPlayerSetLog(); // set RenderFile log
  887. break;
  888. case IDM_FILE_SET_PERF_LOG:
  889. VcdPlayerSetPerfLogFile(); // set perf log
  890. break;
  891. case IDM_FILE_OPEN:
  892. VcdPlayerOpenCmd();
  893. break;
  894. case IDM_FILE_CLOSE:
  895. VcdPlayerCloseCmd();
  896. QzFreeUnusedLibraries();
  897. break;
  898. case IDM_FILE_EXIT:
  899. PostMessage( hwnd, WM_CLOSE, 0, 0L );
  900. break;
  901. case IDM_MOVIE_PLAY:
  902. VcdPlayerPlayCmd();
  903. break;
  904. case IDM_MOVIE_STOP:
  905. VcdPlayerStopCmd();
  906. break;
  907. case IDM_MOVIE_PAUSE:
  908. VcdPlayerPauseCmd();
  909. break;
  910. case IDM_MOVIE_SKIP_FORE:
  911. VcdPlayerSeekCmd(1.0);
  912. break;
  913. case IDM_MOVIE_SKIP_BACK:
  914. VcdPlayerSeekCmd(-1.0);
  915. break;
  916. case IDM_MOVIE_PREVTRACK:
  917. if (pMpegMovie) {
  918. VcdPlayerSeekCmd(-pMpegMovie->GetCurrentPosition());
  919. }
  920. break;
  921. case IDM_TIME:
  922. case IDM_FRAME:
  923. case IDM_FIELD:
  924. case IDM_SAMPLE:
  925. case IDM_BYTES:
  926. if (pMpegMovie) {
  927. g_TimeFormat = VcdPlayerChangeTimeFormat(id);
  928. }
  929. break;
  930. case IDM_MOVIE_NEXTTRACK:
  931. if (pMpegMovie) {
  932. REFTIME rtDur = pMpegMovie->GetDuration();
  933. REFTIME rtPos = pMpegMovie->GetCurrentPosition();
  934. VcdPlayerSeekCmd(rtDur - rtPos);
  935. }
  936. break;
  937. case IDM_PERF_NEW:
  938. if (lpControlProc) (*lpControlProc)(MSR_RESET_ALL);
  939. break;
  940. case IDM_PERF_DUMP:
  941. if (lpDumpProc) {
  942. HANDLE hFile;
  943. hFile = CreateFile(g_szPerfLog, GENERIC_WRITE, 0, NULL,
  944. CREATE_ALWAYS, 0, NULL);
  945. (*lpDumpProc)(hFile);
  946. CloseHandle(hFile);
  947. }
  948. break;
  949. case IDM_FULL_SCREEN:
  950. if (pMpegMovie) {
  951. BOOL bFullScreen = (BOOL) SendMessage( g_hwndToolbar, TB_ISBUTTONCHECKED, IDM_FULL_SCREEN, 0 );
  952. pMpegMovie->SetFullScreenMode(bFullScreen);
  953. }
  954. break;
  955. case IDM_VIDEO_DECODER:
  956. DoMpegVideoPropertyPage();
  957. break;
  958. case IDM_AUDIO_DECODER:
  959. DoMpegAudioPropertyPage();
  960. break;
  961. case IDM_FILTERS:
  962. if (pMpegMovie) {
  963. pMpegMovie->ConfigDialog(hwnd);
  964. }
  965. break;
  966. case IDM_MOVIE_ALIGN:
  967. {
  968. RECT rc, rcWnd;
  969. HWND hwndRenderer = FindWindow(TEXT("VideoRenderer"), NULL);
  970. if (hwndRenderer) {
  971. GetClientRect(hwndRenderer, &rc);
  972. GetWindowRect(hwndRenderer, &rcWnd);
  973. MapWindowPoints(hwndRenderer, HWND_DESKTOP, (LPPOINT)&rc, 2);
  974. rcWnd.left -= rc.left & 3;
  975. rcWnd.top -= rc.top & 3;
  976. SetWindowPos(hwndRenderer, NULL, rcWnd.left, rcWnd.top, 0, 0,
  977. SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER);
  978. }
  979. }
  980. break;
  981. case IDM_HELP_ABOUT:
  982. {
  983. TCHAR szApp[STR_MAX_STRING_LEN];
  984. TCHAR szOtherStuff[STR_MAX_STRING_LEN];
  985. lstrcpy( szApp, IdStr(STR_APP_TITLE) );
  986. lstrcat( szApp, TEXT("#") );
  987. if (g_IsNT)
  988. lstrcat( szApp, TEXT("Windows NT") );
  989. // for some reason ShellAbout prints OS uner Win95 but not NT
  990. // else
  991. // strcat( szApp, "Windows 95" );
  992. lstrcpy( szOtherStuff, IdStr(STR_APP_TITLE) );
  993. lstrcat( szOtherStuff, TEXT("\n") );
  994. lstrcat( szOtherStuff, g_szOtherStuff );
  995. ShellAbout( hwnd, szApp, szOtherStuff, hIconVideoCd );
  996. }
  997. break;
  998. default:
  999. if (id > ID_RECENT_FILE_BASE
  1000. && id <= (ID_RECENT_FILE_BASE + MAX_RECENT_FILES + 1)) {
  1001. ProcessOpen(aRecentFiles[id - ID_RECENT_FILE_BASE - 1]);
  1002. } else if (id >= 2000 && id <= 2050) {
  1003. pMpegMovie->SelectStream(id - 2000);
  1004. }
  1005. break;
  1006. }
  1007. SetPlayButtonsEnableState();
  1008. }
  1009. /******************************Public*Routine******************************\
  1010. * VideoCd_OnDestroy
  1011. *
  1012. *
  1013. *
  1014. * History:
  1015. * dd-mm-93 - StephenE - Created
  1016. *
  1017. \**************************************************************************/
  1018. void
  1019. VideoCd_OnDestroy(
  1020. HWND hwnd
  1021. )
  1022. {
  1023. PostQuitMessage( 0 );
  1024. }
  1025. /******************************Public*Routine******************************\
  1026. * VideoCd_OnClose
  1027. *
  1028. *
  1029. *
  1030. * History:
  1031. * dd-mm-93 - StephenE - Created
  1032. *
  1033. \**************************************************************************/
  1034. void
  1035. VideoCd_OnClose(
  1036. HWND hwnd
  1037. )
  1038. {
  1039. // stop accepting dropped filenames
  1040. DragAcceptFiles(hwnd, FALSE);
  1041. VcdPlayerCloseCmd();
  1042. ProfileIntOut(g_szMovieX, lMovieOrgX);
  1043. ProfileIntOut(g_szMovieY, lMovieOrgY);
  1044. SaveWindowPos( hwnd );
  1045. DestroyWindow( hwnd );
  1046. }
  1047. BOOL
  1048. VideoCd_OnQueryEndSession(
  1049. HWND hwnd
  1050. )
  1051. {
  1052. SaveWindowPos( hwnd );
  1053. return TRUE;
  1054. }
  1055. /******************************Public*Routine******************************\
  1056. * VideoCd_OnSize
  1057. *
  1058. *
  1059. *
  1060. * History:
  1061. * dd-mm-93 - StephenE - Created
  1062. *
  1063. \**************************************************************************/
  1064. void
  1065. VideoCd_OnSize(
  1066. HWND hwnd,
  1067. UINT state,
  1068. int dx,
  1069. int dy
  1070. )
  1071. {
  1072. if (IsWindow(g_hwndStatusbar)) {
  1073. int Pane[2] = {dx/2-8, -1};
  1074. SendMessage(g_hwndStatusbar, WM_SIZE, 0, 0L);
  1075. SendMessage(g_hwndStatusbar, SB_SETPARTS, 2, (LPARAM)Pane);
  1076. }
  1077. if (IsWindow(g_hwndTrackbar)) {
  1078. SetWindowPos(g_hwndTrackbar, HWND_TOP, LEFT_MARGIN, dyToolbar - 1,
  1079. dx - (2 * LEFT_MARGIN), dyTrackbar, SWP_NOZORDER );
  1080. }
  1081. if (IsWindow(g_hwndToolbar)) {
  1082. SendMessage( g_hwndToolbar, WM_SIZE, 0, 0L );
  1083. }
  1084. }
  1085. /*****************************Private*Routine******************************\
  1086. * VideoCd_OnSysColorChange
  1087. *
  1088. *
  1089. *
  1090. * History:
  1091. * 18-11-93 - StephenE - Created
  1092. *
  1093. \**************************************************************************/
  1094. void
  1095. VideoCd_OnSysColorChange(
  1096. HWND hwnd
  1097. )
  1098. {
  1099. FORWARD_WM_SYSCOLORCHANGE(g_hwndToolbar, SendMessage);
  1100. FORWARD_WM_SYSCOLORCHANGE(g_hwndStatusbar, SendMessage);
  1101. }
  1102. /*****************************Private*Routine******************************\
  1103. * VideoCd_OnInitMenuPopup
  1104. *
  1105. *
  1106. *
  1107. * History:
  1108. * dd-mm-94 - StephenE - Created
  1109. *
  1110. \**************************************************************************/
  1111. void
  1112. VideoCd_OnInitMenuPopup(
  1113. HWND hwnd,
  1114. HMENU hMenu,
  1115. UINT item,
  1116. BOOL fSystemMenu
  1117. )
  1118. {
  1119. UINT uFlags;
  1120. switch (item) {
  1121. case 0: // File menu
  1122. if (g_State & (VCD_IN_USE | VCD_NO_CD | VCD_DATA_CD_LOADED)) {
  1123. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1124. }
  1125. else {
  1126. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1127. }
  1128. EnableMenuItem(hMenu, IDM_FILE_CLOSE, uFlags );
  1129. if (lpControlProc == NULL) {
  1130. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1131. }
  1132. else {
  1133. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1134. }
  1135. EnableMenuItem(hMenu, IDM_FILE_SET_PERF_LOG, uFlags );
  1136. break;
  1137. case 1: // Properties menu
  1138. if (pMpegMovie && pMpegMovie->pMpegDecoder) {
  1139. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1140. }
  1141. else {
  1142. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1143. }
  1144. EnableMenuItem(hMenu, IDM_VIDEO_DECODER, uFlags );
  1145. if (pMpegMovie && pMpegMovie->pMpegAudioDecoder) {
  1146. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1147. }
  1148. else {
  1149. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1150. }
  1151. EnableMenuItem(hMenu, IDM_AUDIO_DECODER, uFlags );
  1152. if (pMpegMovie) {
  1153. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1154. }
  1155. else {
  1156. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1157. }
  1158. EnableMenuItem(hMenu, IDM_FILTERS, uFlags );
  1159. break;
  1160. case 2: // Time formats menu
  1161. // Can only change time format when stopped
  1162. {
  1163. EMpegMovieMode State = MOVIE_NOTOPENED;
  1164. if (pMpegMovie) {
  1165. State = pMpegMovie->StatusMovie();
  1166. }
  1167. if (State && pMpegMovie->IsTimeSupported()) {
  1168. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1169. }
  1170. else {
  1171. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1172. }
  1173. EnableMenuItem(hMenu, IDM_TIME, uFlags );
  1174. if (State && pMpegMovie->IsTimeFormatSupported(TIME_FORMAT_FRAME)) {
  1175. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1176. }
  1177. else {
  1178. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1179. }
  1180. EnableMenuItem(hMenu, IDM_FRAME, uFlags );
  1181. if (State && pMpegMovie->IsTimeFormatSupported(TIME_FORMAT_FIELD)) {
  1182. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1183. }
  1184. else {
  1185. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1186. }
  1187. EnableMenuItem(hMenu, IDM_FIELD, uFlags );
  1188. if (State && pMpegMovie->IsTimeFormatSupported(TIME_FORMAT_SAMPLE)) {
  1189. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1190. }
  1191. else {
  1192. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1193. }
  1194. EnableMenuItem(hMenu, IDM_SAMPLE, uFlags );
  1195. if (State && pMpegMovie->IsTimeFormatSupported(TIME_FORMAT_BYTE)) {
  1196. uFlags = (MF_BYCOMMAND | MF_ENABLED);
  1197. }
  1198. else {
  1199. uFlags = (MF_BYCOMMAND | MF_GRAYED);
  1200. }
  1201. EnableMenuItem(hMenu, IDM_BYTES, uFlags );
  1202. CheckMenuItem(hMenu, IDM_BYTES, MF_BYCOMMAND | MF_UNCHECKED);
  1203. CheckMenuItem(hMenu, IDM_SAMPLE, MF_BYCOMMAND | MF_UNCHECKED);
  1204. CheckMenuItem(hMenu, IDM_FRAME, MF_BYCOMMAND | MF_UNCHECKED);
  1205. CheckMenuItem(hMenu, IDM_FIELD, MF_BYCOMMAND | MF_UNCHECKED);
  1206. CheckMenuItem(hMenu, IDM_TIME, MF_BYCOMMAND | MF_UNCHECKED);
  1207. CheckMenuItem(hMenu, g_TimeFormat, MF_BYCOMMAND | MF_CHECKED);
  1208. }
  1209. break;
  1210. case 3: // streams menu
  1211. if (pMpegMovie && pMpegMovie->m_pStreamSelect) {
  1212. DWORD cStreams;
  1213. pMpegMovie->m_pStreamSelect->Count(&cStreams);
  1214. for (DWORD i = 0; i < cStreams; i++) {
  1215. DWORD dwFlags;
  1216. pMpegMovie->m_pStreamSelect->Info(i, NULL, &dwFlags, NULL, NULL, NULL, NULL, NULL);
  1217. CheckMenuItem(hMenu, 2000+i, MF_BYCOMMAND |
  1218. ((dwFlags & AMSTREAMSELECTINFO_ENABLED) ? MF_CHECKED : MF_UNCHECKED));
  1219. }
  1220. }
  1221. break;
  1222. }
  1223. }
  1224. /*****************************Private*Routine******************************\
  1225. * VideoCd_OnGraphNotify
  1226. *
  1227. * This is where we get any notifications from the filter graph.
  1228. *
  1229. * History:
  1230. * dd-mm-94 - StephenE - Created
  1231. *
  1232. \**************************************************************************/
  1233. void
  1234. VideoCd_OnGraphNotify(
  1235. void
  1236. )
  1237. {
  1238. long lEventCode;
  1239. HDC hdc;
  1240. lEventCode = pMpegMovie->GetMovieEventCode();
  1241. switch (lEventCode) {
  1242. case EC_FULLSCREEN_LOST:
  1243. pMpegMovie->SetFullScreenMode(FALSE);
  1244. SetPlayButtonsEnableState();
  1245. break;
  1246. case EC_COMPLETE:
  1247. case EC_USERABORT:
  1248. case EC_ERRORABORT:
  1249. VcdPlayerStopCmd();
  1250. SetPlayButtonsEnableState();
  1251. hdc = GetDC(hwndApp);
  1252. DrawStats(hdc);
  1253. ReleaseDC(hwndApp, hdc);
  1254. break;
  1255. default:
  1256. break;
  1257. }
  1258. }
  1259. /*****************************Private*Routine******************************\
  1260. * VideoCd_OnNotify
  1261. *
  1262. * This is where we get the text for the little tooltips
  1263. *
  1264. * History:
  1265. * dd-mm-94 - StephenE - Created
  1266. *
  1267. \**************************************************************************/
  1268. LRESULT
  1269. VideoCd_OnNotify(
  1270. HWND hwnd,
  1271. int idFrom,
  1272. NMHDR FAR* pnmhdr
  1273. )
  1274. {
  1275. switch (pnmhdr->code) {
  1276. case TTN_NEEDTEXT:
  1277. {
  1278. LPTOOLTIPTEXT lpTt;
  1279. lpTt = (LPTOOLTIPTEXT)pnmhdr;
  1280. LoadString( hInst, (UINT) lpTt->hdr.idFrom, lpTt->szText,
  1281. sizeof(lpTt->szText) );
  1282. }
  1283. break;
  1284. }
  1285. return 0;
  1286. }
  1287. /*****************************Private*Routine******************************\
  1288. * VideoCd_OnMenuSelect
  1289. *
  1290. *
  1291. *
  1292. * History:
  1293. * dd-mm-94 - StephenE - Created
  1294. *
  1295. \**************************************************************************/
  1296. void
  1297. VideoCd_OnMenuSelect(
  1298. HWND hwnd,
  1299. HMENU hmenu,
  1300. int item,
  1301. HMENU hmenuPopup,
  1302. UINT flags
  1303. )
  1304. {
  1305. TCHAR szString[STR_MAX_STRING_LEN + 1];
  1306. /*
  1307. ** Is it time to end the menu help ?
  1308. */
  1309. if ( (flags == 0xFFFFFFFF) && (hmenu == NULL) ) {
  1310. SendMessage(g_hwndStatusbar, SB_SIMPLE, 0, 0L);
  1311. }
  1312. /*
  1313. ** Do we have a separator, popup or the system menu ?
  1314. */
  1315. else if ( flags & MF_POPUP ) {
  1316. SendMessage(g_hwndStatusbar, SB_SIMPLE, 0, 0L);
  1317. }
  1318. else if (flags & MF_SYSMENU) {
  1319. switch (item) {
  1320. case SC_RESTORE:
  1321. lstrcpy( szString, IdStr(STR_SYSMENU_RESTORE) );
  1322. break;
  1323. case SC_MOVE:
  1324. lstrcpy( szString, IdStr(STR_SYSMENU_MOVE) );
  1325. break;
  1326. case SC_MINIMIZE:
  1327. lstrcpy( szString, IdStr(STR_SYSMENU_MINIMIZE) );
  1328. break;
  1329. case SC_MAXIMIZE:
  1330. lstrcpy( szString, IdStr(STR_SYSMENU_MAXIMIZE) );
  1331. break;
  1332. case SC_TASKLIST:
  1333. lstrcpy( szString, IdStr(STR_SYSMENU_TASK_LIST) );
  1334. break;
  1335. case SC_CLOSE:
  1336. lstrcpy( szString, IdStr(STR_SYSMENU_CLOSE) );
  1337. break;
  1338. }
  1339. SendMessage( g_hwndStatusbar, SB_SETTEXT, SBT_NOBORDERS|255,
  1340. (LPARAM)(LPTSTR)szString );
  1341. SendMessage( g_hwndStatusbar, SB_SIMPLE, 1, 0L );
  1342. UpdateWindow(g_hwndStatusbar);
  1343. }
  1344. /*
  1345. ** Hopefully its one of ours
  1346. */
  1347. else {
  1348. if ((flags & MF_SEPARATOR)) {
  1349. szString[0] = g_chNULL;
  1350. }
  1351. else {
  1352. lstrcpy( szString, IdStr(item + MENU_STRING_BASE) );
  1353. }
  1354. SendMessage( g_hwndStatusbar, SB_SETTEXT, SBT_NOBORDERS|255,
  1355. (LPARAM)(LPTSTR)szString );
  1356. SendMessage( g_hwndStatusbar, SB_SIMPLE, 1, 0L );
  1357. UpdateWindow(g_hwndStatusbar);
  1358. }
  1359. }
  1360. /*****************************Private*Routine******************************\
  1361. * VideoCd_OnDropFiles
  1362. *
  1363. * -- handle a file-manager drop of a filename to indicate a movie we should
  1364. * open.
  1365. *
  1366. *
  1367. * History:
  1368. * 22-01-96 - GeraintD - Created
  1369. *
  1370. \**************************************************************************/
  1371. void
  1372. VideoCd_OnDropFiles(
  1373. HWND hwnd,
  1374. HDROP hdrop)
  1375. {
  1376. // if there is more than one file, simply open the first one
  1377. // find the length of the path (plus the null
  1378. int cch = DragQueryFile(hdrop, 0, NULL, 0) + 1;
  1379. TCHAR * pName = new TCHAR[cch];
  1380. DragQueryFile(hdrop, 0, pName, cch);
  1381. // open the file
  1382. ProcessOpen(pName);
  1383. // update the toolbar state
  1384. SetPlayButtonsEnableState();
  1385. // free up used resources
  1386. delete [] pName;
  1387. DragFinish(hdrop);
  1388. }
  1389. /******************************Public*Routine******************************\
  1390. * SetPlayButtonsEnableState
  1391. *
  1392. * Sets the play buttons enable state to match the state of the current
  1393. * cdrom device. See below...
  1394. *
  1395. *
  1396. * VCD Player buttons enable state table
  1397. * Ŀ
  1398. * E=Enabled D=Disabled Play Pause Eject Stop Other
  1399. * Ĵ
  1400. * Disk in use D D D D D
  1401. * Ĵ
  1402. * No video cd or data cdrom D D E D D
  1403. * Ĵ
  1404. * Video cd (playing) D E E E E
  1405. * Ĵ
  1406. * Video cd (paused) E D E E E
  1407. * Ĵ
  1408. * Video cd (stopped) E D E D E
  1409. *
  1410. *
  1411. *
  1412. * History:
  1413. * 18-11-93 - StephenE - Created
  1414. *
  1415. \**************************************************************************/
  1416. void
  1417. SetPlayButtonsEnableState(
  1418. void
  1419. )
  1420. {
  1421. BOOL fEnable, fPress;
  1422. BOOL fVideoCdLoaded;
  1423. /*
  1424. ** Do we have a video cd loaded.
  1425. */
  1426. if (g_State & (VCD_NO_CD | VCD_DATA_CD_LOADED | VCD_IN_USE)) {
  1427. fVideoCdLoaded = FALSE;
  1428. }
  1429. else {
  1430. fVideoCdLoaded = TRUE;
  1431. }
  1432. /*
  1433. ** Do the play button
  1434. */
  1435. if ( fVideoCdLoaded
  1436. && ((g_State & VCD_STOPPED) || (g_State & VCD_PAUSED))) {
  1437. fEnable = TRUE;
  1438. }
  1439. else {
  1440. fEnable = FALSE;
  1441. }
  1442. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PLAY, fEnable );
  1443. /*
  1444. ** Do the stop button
  1445. */
  1446. if ( fVideoCdLoaded
  1447. && ((g_State & VCD_PLAYING) || (g_State & VCD_PAUSED))) {
  1448. fEnable = TRUE;
  1449. }
  1450. else {
  1451. fEnable = FALSE;
  1452. }
  1453. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_STOP, fEnable );
  1454. /*
  1455. ** Do the pause button
  1456. */
  1457. if ( fVideoCdLoaded && (g_State & VCD_PLAYING) ) {
  1458. fEnable = TRUE;
  1459. }
  1460. else {
  1461. fEnable = FALSE;
  1462. }
  1463. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON, IDM_MOVIE_PAUSE, fEnable );
  1464. /*
  1465. ** Do the remaining buttons
  1466. */
  1467. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON,
  1468. IDM_MOVIE_SKIP_FORE, fVideoCdLoaded );
  1469. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON,
  1470. IDM_MOVIE_SKIP_BACK, fVideoCdLoaded );
  1471. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON,
  1472. IDM_MOVIE_NEXTTRACK, fVideoCdLoaded );
  1473. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON,
  1474. IDM_MOVIE_PREVTRACK, fVideoCdLoaded );
  1475. /*
  1476. ** Do the fullscreen button
  1477. */
  1478. if ( fVideoCdLoaded && pMpegMovie->IsFullScreenMode() ) {
  1479. fPress = TRUE;
  1480. }
  1481. else {
  1482. fPress = FALSE;
  1483. }
  1484. SendMessage( g_hwndToolbar, TB_CHECKBUTTON, IDM_FULL_SCREEN, MAKELONG(fPress,0) );
  1485. SendMessage( g_hwndToolbar, TB_ENABLEBUTTON, IDM_FULL_SCREEN, fVideoCdLoaded );
  1486. //
  1487. // do "new log" and "dump log" buttons
  1488. //
  1489. SendMessage( g_hwndToolbar, TB_HIDEBUTTON,
  1490. IDM_PERF_NEW, lpControlProc == NULL);
  1491. SendMessage( g_hwndToolbar, TB_HIDEBUTTON,
  1492. IDM_PERF_DUMP, lpDumpProc == NULL);
  1493. }
  1494. /*****************************Private*Routine******************************\
  1495. * GetAdjustedClientRect
  1496. *
  1497. * Calculate the size of the client rect and then adjusts it to take into
  1498. * account the space taken by the toolbar and status bar.
  1499. *
  1500. * History:
  1501. * dd-mm-95 - StephenE - Created
  1502. *
  1503. \**************************************************************************/
  1504. void
  1505. GetAdjustedClientRect(
  1506. RECT *prc
  1507. )
  1508. {
  1509. RECT rcTool;
  1510. GetClientRect(hwndApp, prc);
  1511. GetWindowRect(g_hwndToolbar, &rcTool);
  1512. prc->top += (rcTool.bottom - rcTool.top);
  1513. GetWindowRect(g_hwndTrackbar, &rcTool);
  1514. prc->top += (rcTool.bottom - rcTool.top);
  1515. GetWindowRect(g_hwndStatusbar, &rcTool);
  1516. prc->bottom -= (rcTool.bottom - rcTool.top);
  1517. }
  1518. /******************************Public*Routine******************************\
  1519. * IdStr
  1520. *
  1521. * Loads the given string resource ID into the passed storage.
  1522. *
  1523. * History:
  1524. * 18-11-93 - StephenE - Created
  1525. *
  1526. \**************************************************************************/
  1527. LPCTSTR
  1528. IdStr(
  1529. int idResource
  1530. )
  1531. {
  1532. static TCHAR chBuffer[ STR_MAX_STRING_LEN ];
  1533. if (LoadString(hInst, idResource, chBuffer, STR_MAX_STRING_LEN) == 0) {
  1534. return g_szEmpty;
  1535. }
  1536. return chBuffer;
  1537. }
  1538. /*+ GetAppKey
  1539. *
  1540. *-=================================================================*/
  1541. static TCHAR cszWindow[] = TEXT("Window");
  1542. static TCHAR cszAppKey[] = TEXT("Software\\Microsoft\\Multimedia Tools\\VCDPlayer");
  1543. HKEY
  1544. GetAppKey(
  1545. BOOL fCreate
  1546. )
  1547. {
  1548. HKEY hKey = 0;
  1549. if (fCreate) {
  1550. if (RegCreateKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
  1551. return hKey;
  1552. }
  1553. else {
  1554. if (RegOpenKey(HKEY_CURRENT_USER, cszAppKey, &hKey) == ERROR_SUCCESS)
  1555. return hKey;
  1556. }
  1557. return NULL;
  1558. }
  1559. /*+ ProfileIntIn
  1560. *
  1561. *-=================================================================*/
  1562. int
  1563. ProfileIntIn(
  1564. const TCHAR *szKey,
  1565. int iDefault
  1566. )
  1567. {
  1568. DWORD dwType;
  1569. int iValue;
  1570. BYTE aData[20];
  1571. DWORD cb;
  1572. HKEY hKey;
  1573. if (!(hKey = GetAppKey(TRUE))) {
  1574. return iDefault;
  1575. }
  1576. *(UINT *)&aData = 0;
  1577. cb = sizeof(aData);
  1578. if (RegQueryValueEx (hKey, szKey, NULL, &dwType, aData, &cb)) {
  1579. iValue = iDefault;
  1580. }
  1581. else {
  1582. if (dwType == REG_DWORD || dwType == REG_BINARY) {
  1583. iValue = *(int *)&aData;
  1584. }
  1585. else if (dwType == REG_SZ) {
  1586. iValue = _ttoi((LPTSTR)aData);
  1587. }
  1588. }
  1589. RegCloseKey (hKey);
  1590. return iValue;
  1591. }
  1592. /*+ ProfileIntOut
  1593. *
  1594. *-=================================================================*/
  1595. BOOL
  1596. ProfileIntOut (
  1597. const TCHAR *szKey,
  1598. int iVal
  1599. )
  1600. {
  1601. HKEY hKey;
  1602. BOOL bRet = FALSE;
  1603. hKey = GetAppKey(TRUE);
  1604. if (hKey) {
  1605. RegSetValueEx(hKey, szKey, 0, REG_DWORD, (LPBYTE)&iVal, sizeof(DWORD));
  1606. RegCloseKey (hKey);
  1607. bRet = TRUE;
  1608. }
  1609. return bRet;
  1610. }
  1611. /*+ ProfileString
  1612. *
  1613. *-=================================================================*/
  1614. UINT
  1615. ProfileStringIn (
  1616. LPTSTR szKey,
  1617. LPTSTR szDef,
  1618. LPTSTR sz,
  1619. DWORD cb
  1620. )
  1621. {
  1622. HKEY hKey;
  1623. DWORD dwType;
  1624. if (!(hKey = GetAppKey (FALSE)))
  1625. {
  1626. lstrcpy (sz, szDef);
  1627. return lstrlen (sz);
  1628. }
  1629. if (RegQueryValueEx(hKey, szKey, NULL, &dwType, (LPBYTE)sz, &cb) || dwType != REG_SZ)
  1630. {
  1631. lstrcpy (sz, szDef);
  1632. cb = lstrlen (sz);
  1633. }
  1634. RegCloseKey (hKey);
  1635. return cb;
  1636. }
  1637. void
  1638. ProfileStringOut (
  1639. LPTSTR szKey,
  1640. LPTSTR sz
  1641. )
  1642. {
  1643. HKEY hKey;
  1644. hKey = GetAppKey(TRUE);
  1645. if (hKey)
  1646. RegSetValueEx(hKey, szKey, 0, REG_SZ, (LPBYTE)sz, lstrlen(sz)+1);
  1647. RegCloseKey (hKey);
  1648. }
  1649. /*+ LoadWindowPos
  1650. *
  1651. * retrieve the window position information from dragn.ini
  1652. *
  1653. *-=================================================================*/
  1654. #ifndef SPI_GETWORKAREA
  1655. #define SPI_GETWORKAREA 48 // because NT doesnt have this define yet
  1656. #endif
  1657. BOOL
  1658. LoadWindowPos(
  1659. LPRECT lprc
  1660. )
  1661. {
  1662. static RECT rcDefault = {0,0,CX_DEFAULT,CY_DEFAULT};
  1663. RECT rcScreen;
  1664. RECT rc;
  1665. HKEY hKey = GetAppKey(FALSE);
  1666. // read window placement from the registry.
  1667. //
  1668. *lprc = rcDefault;
  1669. if (hKey)
  1670. {
  1671. DWORD cb;
  1672. DWORD dwType;
  1673. cb = sizeof(rc);
  1674. if ( ! RegQueryValueEx(hKey, cszWindow, NULL, &dwType, (LPBYTE)&rc, &cb)
  1675. && dwType == REG_BINARY && cb == sizeof(RECT))
  1676. {
  1677. *lprc = rc;
  1678. }
  1679. RegCloseKey (hKey);
  1680. }
  1681. // if we fail to get the working area (screen-tray), then assume
  1682. // the screen is 640x480
  1683. //
  1684. if ( ! SystemParametersInfo(SPI_GETWORKAREA, 0, &rcScreen, FALSE))
  1685. {
  1686. rcScreen.top = rcScreen.left = 0;
  1687. rcScreen.right = 640;
  1688. rcScreen.bottom = 480;
  1689. }
  1690. // if the proposed window position is outside the screen,
  1691. // use the default placement
  1692. //
  1693. if ( ! IntersectRect(&rc, &rcScreen, lprc)) {
  1694. *lprc = rcDefault;
  1695. }
  1696. return ! IsRectEmpty (lprc);
  1697. }
  1698. /*+ SaveWindowPos
  1699. *
  1700. * store the window position information in dragn.ini
  1701. *
  1702. *-=================================================================*/
  1703. BOOL
  1704. SaveWindowPos(
  1705. HWND hwnd
  1706. )
  1707. {
  1708. WINDOWPLACEMENT wpl;
  1709. HKEY hKey = GetAppKey(TRUE);
  1710. if (!hKey) {
  1711. return FALSE;
  1712. }
  1713. // save the current size and position of the window to the registry
  1714. //
  1715. ZeroMemory (&wpl, sizeof(wpl));
  1716. wpl.length = sizeof(wpl);
  1717. GetWindowPlacement (hwnd, &wpl);
  1718. RegSetValueEx( hKey, cszWindow, 0, REG_BINARY,
  1719. (LPBYTE)&wpl.rcNormalPosition,
  1720. sizeof(wpl.rcNormalPosition));
  1721. RegCloseKey (hKey);
  1722. return TRUE;
  1723. }
  1724. /*****************************Private*Routine******************************\
  1725. * GetRecentFiles
  1726. *
  1727. * Reads at most MAX_RECENT_FILES from vcdplyer.ini. Returns the number
  1728. * of files actually read. Updates the File menu to show the "recent" files.
  1729. *
  1730. * History:
  1731. * 26-10-95 - StephenE - Created
  1732. *
  1733. \**************************************************************************/
  1734. int
  1735. GetRecentFiles(
  1736. int iLastCount
  1737. )
  1738. {
  1739. int i;
  1740. TCHAR FileName[MAX_PATH];
  1741. TCHAR szKey[32];
  1742. HMENU hSubMenu;
  1743. //
  1744. // Delete the files from the menu
  1745. //
  1746. hSubMenu = GetSubMenu(GetMenu(hwndApp), 0);
  1747. // Delete the separator at slot 2 and all the other recent file entries
  1748. if (iLastCount != 0) {
  1749. DeleteMenu(hSubMenu, 2, MF_BYPOSITION);
  1750. for (i = 1; i <= iLastCount; i++) {
  1751. DeleteMenu(hSubMenu, ID_RECENT_FILE_BASE + i, MF_BYCOMMAND);
  1752. }
  1753. }
  1754. for (i = 1; i <= MAX_RECENT_FILES; i++) {
  1755. DWORD len;
  1756. TCHAR szMenuName[MAX_PATH + 3];
  1757. wsprintf(szKey, TEXT("File %d"), i);
  1758. len = ProfileStringIn(szKey, TEXT(""), FileName, MAX_PATH);
  1759. if (len == 0) {
  1760. i = i - 1;
  1761. break;
  1762. }
  1763. lstrcpy(aRecentFiles[i - 1], FileName);
  1764. wsprintf(szMenuName, TEXT("&%d %s"), i, FileName);
  1765. if (i == 1) {
  1766. InsertMenu(hSubMenu, 2, MF_SEPARATOR | MF_BYPOSITION, (UINT)-1, NULL );
  1767. }
  1768. InsertMenu(hSubMenu, 2 + i, MF_STRING | MF_BYPOSITION,
  1769. ID_RECENT_FILE_BASE + i, szMenuName );
  1770. }
  1771. //
  1772. // i is the number of recent files in the array.
  1773. //
  1774. return i;
  1775. }
  1776. /*****************************Private*Routine******************************\
  1777. * SetRecentFiles
  1778. *
  1779. * Writes the most recent files to the vcdplyer.ini file. Purges the oldest
  1780. * file if necessary.
  1781. *
  1782. * History:
  1783. * 26-10-95 - StephenE - Created
  1784. *
  1785. \**************************************************************************/
  1786. int
  1787. SetRecentFiles(
  1788. TCHAR *FileName, // File name to add
  1789. int iCount // Current count of files
  1790. )
  1791. {
  1792. TCHAR FullPathFileName[MAX_PATH];
  1793. TCHAR *lpFile;
  1794. TCHAR szKey[32];
  1795. int iCountNew;
  1796. int i;
  1797. //
  1798. // Check for dupes - we don't allow them !
  1799. //
  1800. for (i = 0; i < iCount; i++) {
  1801. if (0 == lstrcmpi(FileName, aRecentFiles[i])) {
  1802. return iCount;
  1803. }
  1804. }
  1805. //
  1806. // Throw away the oldest entry
  1807. //
  1808. MoveMemory(&aRecentFiles[1], &aRecentFiles[0],
  1809. sizeof(aRecentFiles) - sizeof(aRecentFiles[1]));
  1810. //
  1811. // Copy in the full path of the new file.
  1812. //
  1813. GetFullPathName(FileName, MAX_PATH, FullPathFileName, &lpFile);
  1814. lstrcpy(aRecentFiles[0], FullPathFileName);
  1815. //
  1816. // Update the count of files, saturate to MAX_RECENT_FILES.
  1817. //
  1818. iCountNew = min(iCount + 1, MAX_RECENT_FILES);
  1819. //
  1820. // Clear the old stuff and the write out the recent files to disk
  1821. //
  1822. for (i = 1; i <= iCountNew; i++) {
  1823. wsprintf(szKey, TEXT("File %d"), i);
  1824. ProfileStringOut(szKey, aRecentFiles[i - 1]);
  1825. }
  1826. //
  1827. // Update the file menu
  1828. //
  1829. GetRecentFiles(iCount);
  1830. return iCountNew; // the updated count of files.
  1831. }
  1832. /*****************************Private*Routine******************************\
  1833. * SetDurationLength
  1834. *
  1835. * Updates pane 0 on the status bar
  1836. *
  1837. * History:
  1838. * 30-10-95 - StephenE - Created
  1839. *
  1840. \**************************************************************************/
  1841. void
  1842. SetDurationLength(
  1843. REFTIME rt
  1844. )
  1845. {
  1846. TCHAR szFmt[64];
  1847. TCHAR sz[64];
  1848. g_TrackBarScale = 1.0;
  1849. while (rt / g_TrackBarScale > 30000) {
  1850. g_TrackBarScale *= 10;
  1851. }
  1852. SendMessage(g_hwndTrackbar, TBM_SETRANGE, TRUE,
  1853. MAKELONG(0, (WORD)(rt / g_TrackBarScale)));
  1854. SendMessage(g_hwndTrackbar, TBM_SETTICFREQ, (WPARAM)((int)(rt / g_TrackBarScale) / 9), 0);
  1855. SendMessage(g_hwndTrackbar, TBM_SETPAGESIZE, 0, (LPARAM)((int)(rt / g_TrackBarScale) / 9));
  1856. wsprintf(sz, TEXT("Length: %s"), FormatRefTime(szFmt, rt));
  1857. SendMessage(g_hwndStatusbar, SB_SETTEXT, 0, (LPARAM)sz);
  1858. }
  1859. /*****************************Private*Routine******************************\
  1860. * SetCurrentPosition
  1861. *
  1862. * Updates pane 1 on the status bar
  1863. *
  1864. * History:
  1865. * 30-10-95 - StephenE - Created
  1866. *
  1867. \**************************************************************************/
  1868. void
  1869. SetCurrentPosition(
  1870. REFTIME rt
  1871. )
  1872. {
  1873. TCHAR szFmt[64];
  1874. TCHAR sz[64];
  1875. SendMessage(g_hwndTrackbar, TBM_SETPOS, TRUE, (LPARAM)(rt / g_TrackBarScale));
  1876. wsprintf(sz, TEXT("Elapsed: %s"), FormatRefTime(szFmt, rt));
  1877. SendMessage(g_hwndStatusbar, SB_SETTEXT, 1, (LPARAM)sz);
  1878. }
  1879. /*****************************Private*Routine******************************\
  1880. * FormatRefTime
  1881. *
  1882. * Formats the given RefTime into the passed in character buffer,
  1883. * returns a pointer to the character buffer.
  1884. *
  1885. * History:
  1886. * dd-mm-95 - StephenE - Created
  1887. *
  1888. \**************************************************************************/
  1889. TCHAR *
  1890. FormatRefTime(
  1891. TCHAR *sz,
  1892. REFTIME rt
  1893. )
  1894. {
  1895. // If we are not seeking in time then format differently
  1896. if (pMpegMovie && pMpegMovie->GetTimeFormat() != TIME_FORMAT_MEDIA_TIME) {
  1897. wsprintf(sz,TEXT("%s"),(LPCTSTR) CDisp ((LONGLONG) rt,CDISP_DEC));
  1898. return sz;
  1899. }
  1900. int hrs, mins, secs;
  1901. rt += 0.49;
  1902. hrs = (int)rt / 3600;
  1903. mins = ((int)rt % 3600) / 60;
  1904. secs = ((int)rt % 3600) % 60;
  1905. #ifdef UNICODE
  1906. swprintf(sz, L"%02d:%02d:%02d h:m:s", rt);
  1907. #else
  1908. sprintf(sz, "%02d:%02d:%02d h:m:s", hrs, mins, secs);
  1909. #endif
  1910. return sz;
  1911. }