Simple Media Player for C++

The following code demonstrates a simple media player application. It utilizes most of the functions available in the ltmmPlay object.

g_pPlay->get_SourceType (&l);
if(l == ltmmPlay_Source_Array)
{
   _stprintf(sz, _T("Stopped - [array]"));
}
else if(l == ltmmPlay_Source_HGlobal)
{
   _stprintf(sz, _T("Stopped - [hglobal]"));
}
else
{
   g_pPlay->get_SourceFile (&bstr);
   _stprintf(sz, _T("Stopped - [%ls]"), bstr);
   SysFreeString(bstr);
}
SetWindowText(hwnd, sz);
break;
case ltmmPlay_State_Paused:
   g_pPlay->get_SourceType (&l);
   if(l == ltmmPlay_Source_Array)
   {
      _stprintf(sz, _T("Paused - [array]"));
   }
   else if(l == ltmmPlay_Source_HGlobal)
   {
      _stprintf(sz, _T("Paused - [hglobal]"));
   }
   else
   {
      g_pPlay->get_SourceFile (&bstr);
      _stprintf(sz, _T("Paused - [%ls]"), bstr);
      SysFreeString(bstr);
   }
   SetWindowText(hwnd, sz);
   break;
case ltmmPlay_State_Running:
   _stprintf(sz, _T("Playing"));
   SetWindowText(hwnd, sz);
   break;
          }
          break;
       case ltmmPlay_Notify_Error:
          _stprintf(sz, _T("Error 0x%.8X. Playback stopped."), lParam);
          MessageBox(hwnd, sz, _T("Play"), MB_ICONEXCLAMATION | MB_OK);
          break;
       }
       return 0;
       break;
    case WM_KEYDOWN:
       if(wParam == VK_ESCAPE)
       {
          // if fullscreen mode then exit it
          g_pPlay->get_FullScreenMode (&f);
          if(f)
          {
             g_pPlay->put_FullScreenMode(VARIANT_FALSE);
             return 0;
          }
       }      break;
    case WM_DESTROY:
       FreeSource();
       // no more notifications
       g_pPlay->SetNotifyWindow ((long) NULL, 0);
       PostQuitMessage(0);
       break;
    case WM_COMMAND:
       switch(LOWORD(wParam))
       {
       case ID_CONTROL_POSITIONVIEW_TIME:
          g_nPositionView = POSITIONVIEW_TIME;
          break;
       case ID_CONTROL_POSITIONVIEW_FRAME:
          g_nPositionView = POSITIONVIEW_FRAME;
          break;
       case ID_CONTROL_POSITIONVIEW_TRACKING:
          g_nPositionView = POSITIONVIEW_TRACKING;
          break;
       case ID_CONTROL_AUTOSTART:
          // toggle auto start
          g_pPlay->get_AutoStart (&f);
          g_pPlay->put_AutoStart (f ? VARIANT_FALSE : VARIANT_TRUE);
          return 0;
          break;
       case ID_CONTROL_PLAY:
          // play file
          g_pPlay->Run ();
          return 0;
          break;
       case ID_CONTROL_PAUSE:
          // pause playback
          g_pPlay->Pause ();
          return 0;
          break;
       case ID_CONTROL_STOP:
          // stop playback
          g_pPlay->Stop ();
          return 0;
          break;
       case ID_CONTROL_HALFSPEED:
          // set to half the normal playback speed
          g_pPlay->put_Rate (0.5);
          return 0;
          break;
       case ID_CONTROL_NORMALSPEED:
          // set to normal speed
          g_pPlay->put_Rate (1.0);
          return 0;
          break;
       case ID_CONTROL_SEEKSTART:
          // seek to file start
          g_pPlay->SeekStart ();
          return 0;
          break;
       case ID_CONTROL_SEEKEND:
          // seek to file end
          g_pPlay->SeekEnd ();
          return 0;
          break;
       case ID_CONTROL_SEEKSELECTIONSTART:
          // seek to the start of the current selection
          g_pPlay->SeekSelectionStart ();
          return 0;
          break;
       case ID_CONTROL_SEEKSELECTIONEND:
          // seek to the end of the current selection
          g_pPlay->SeekSelectionEnd ();
          return 0;
          break;
       case ID_CONTROL_SETSELECTIONSTART:
          // set the start of the selection to the current position
          g_pPlay->MarkSelectionStart ();
          return 0;
          break;
       case ID_CONTROL_SETSELECTIONEND:
          // set the end of the selection to the current position
          g_pPlay->MarkSelectionEnd ();
          return 0;
          break;
       case ID_CONTROL_CLEARSELECTION:
          // clear the current selection
          g_pPlay->get_Duration(&d);
          g_pPlay->put_SelectionStart (0.0);
          g_pPlay->put_SelectionEnd (d);
          return 0;
          break;
       case ID_CONTROL_NEXTFRAME:
          // goto the next frame
          g_pPlay->NextFrame ();
          return 0;
          break;
       case ID_CONTROL_PREVIOUSFRAME:
          // goto the previous frame
          g_pPlay->PreviousFrame ();
          return 0;
          break;
       case ID_CONTROL_FIRSTFRAME:
          // go to the first frame
          g_pPlay->put_CurrentFramePosition (0);
          return 0;
          break;
       case ID_CONTROL_LASTFRAME:
          // go to the last frame
          g_pPlay->get_FrameDuration (&l);
          g_pPlay->put_CurrentFramePosition (l - 1);
          return 0;
          break;
       case ID_CONTROL_STEPFORWARD1SEC:
          // step forward 1 second
          g_pPlay->get_CurrentPosition (&d);
          g_pPlay->put_CurrentPosition (d + 1.0);
          return 0;
          break;
       case ID_CONTROL_STEPFORWARD10:
          // step forward 10%
          g_pPlay->get_CurrentTrackingPosition (&l);
          g_pPlay->put_CurrentTrackingPosition (l + 1000);
          return 0;
          break;
       case ID_CONTROL_FITTOWINDOW:
          // fit the video to the window
          g_pPlay->put_VideoWindowSizeMode (ltmmFit);
          return 0;
          break;
       case ID_CONTROL_STRETCHTOWINDOW:
          // stretch the video to the window
          g_pPlay->put_VideoWindowSizeMode (ltmmStretch);
          return 0;
          break;
       case ID_CONTROL_MUTE:
          // toggle mute
          g_pPlay->get_Mute(&f);
          g_pPlay->put_Mute (f ? VARIANT_FALSE : VARIANT_TRUE);
          return 0;
          break;
       case ID_CONTROL_INCREASEVOLUME:
          // increase the volume
          g_pPlay->get_Volume (&l);
          g_pPlay->put_Volume (min(0, l + 300));
          return 0;
          break;
       case ID_CONTROL_DECREASEVOLUME:
          // decrease the volume
          g_pPlay->get_Volume (&l);
          g_pPlay->put_Volume (max(-10000, l - 300));
          return 0;
          break;
       case ID_CONTROL_PANRIGHT:
          // pan balance to the right
          g_pPlay->get_Balance (&l);
          g_pPlay->put_Balance (min(10000, l + 300));
          return 0;
          break;
       case ID_CONTROL_PANLEFT:
          // pan balance to the left
          g_pPlay->get_Balance (&l);
          g_pPlay->put_Balance (max(-10000, l - 300));
          return 0;
          break;
       case ID_CONTROL_LOOP:
          // toggle looping
          g_pPlay->get_PlayCount (&l);
          g_pPlay->put_PlayCount (l ? 0 : 1);
          return 0;
          break;
       case ID_CONTROL_FULLSCREEN:
          // toggle fullscreen mode
          g_pPlay->ToggleFullScreenMode ();
          return 0;
          break;
       case ID_CONTROL_AUTOREWIND:
          // toggle auto rewind
          g_pPlay->get_AutoRewind (&f);
          g_pPlay->put_AutoRewind (f ? VARIANT_FALSE : VARIANT_TRUE);
          return 0;
          break;
       case ID_CONTROL_PROCESSORS_VIDEO:
          // invoke video processor dialog box
          g_pPlay->ShowDialog(ltmmPlay_Dlg_VideoProcessors, (long) hwnd);
          return 0;
          break;
       case ID_CONTROL_PROCESSORS_AUDIO:
          // invoke audio processor dialog box
          g_pPlay->ShowDialog(ltmmPlay_Dlg_AudioProcessors, (long) hwnd);
          return 0;
          break;
       case ID_CONTROL_SOURCE_FILE:
          // set the source file
          FreeSource();
          bstr = SysAllocString(L"c:\\source.avi");
          g_pPlay->put_SourceFile (bstr);
          SysFreeString(bstr);
          SnapFrameToVideo();
          return 0;
          break;
       case ID_CONTROL_SOURCE_ARRAY:
          // set the source array
          FreeSource();
          SetSourceArray();
          SnapFrameToVideo();
          return 0;
          break;
       case ID_CONTROL_SOURCE_HGLOBAL:
          // set the source hglobal
          FreeSource();
          SetSourceHGlobal();
          SnapFrameToVideo();
          return 0;
          break;
       case ID_CONTROL_MEDIAINFORMATION:
          // display available media information
          p = sz;
          g_pPlay->get_Title (&bstr);
          p += _stprintf(p, _T("Title = '%ls'"), bstr ? bstr : L"");
          SysFreeString(bstr);
          g_pPlay->get_Author (&bstr);
          p += _stprintf(p, _T(", Author = '%ls'"), bstr ? bstr : L"");
          SysFreeString(bstr);
          g_pPlay->get_Copyright (&bstr);
          p += _stprintf(p, _T(", Copyright = '%ls'"), bstr ? bstr : L"");
          SysFreeString(bstr);
          g_pPlay->get_Description (&bstr);
          p += _stprintf(p, _T(", Description = '%ls'"), bstr ? bstr : L"");
          SysFreeString(bstr);
          g_pPlay->get_Rating (&bstr);
          p += _stprintf(p, _T(", Rating = '%ls'"), bstr ? bstr : L"");
          SysFreeString(bstr);
          MessageBox(hwnd, sz, _T("Media Information"), MB_OK);
          return 0;
          break;
       }
       break;
    case WM_LBUTTONDOWN:
       // perform play/pause if the user clicks in the video window
       g_pPlay->get_VideoWindowLeft (&x);
       g_pPlay->get_VideoWindowTop (&y);
       g_pPlay->get_VideoWindowWidth (&cx);
       g_pPlay->get_VideoWindowHeight (&cy);
       SetRect(&rc, x, y, x + cx, y + cy);
       pt.x = (short) LOWORD(lParam);
       pt.y = (short) HIWORD(lParam);
       if(PtInRect(&rc, pt))
       {
          g_pPlay->get_State (&l);
          if(l == ltmmPlay_State_Stopped || l == ltmmPlay_State_Paused)
             g_pPlay->Run ();
          else if(l == ltmmPlay_State_Running)
             g_pPlay->Pause ();
       }      return 0;
       break;
    }
    return DefWindowProc(hwnd, message, wParam, lParam); }int APIENTRY WinMain(HINSTANCE hInstance,
       HINSTANCE hPrevInstance,
       LPSTR     lpCmdLine,
       int       nCmdShow)
    {
       MSG msg;
       HRESULT hr;
       WNDCLASSEX wcex;
       g_hInstance = hInstance;
       // initialize COM library
       hr = CoInitialize(NULL);
       if(FAILED(hr))
          goto error;
       // register the video frame window class
       wcex.cbSize = sizeof(WNDCLASSEX);
       wcex.style = CS_HREDRAW | CS_VREDRAW;
       wcex.lpfnWndProc = PlayWndProc;
       wcex.cbClsExtra = 0;
       wcex.cbWndExtra = 0;
       wcex.hInstance = g_hInstance;
       wcex.hIcon = NULL;
       wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
       wcex.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1);
       wcex.lpszMenuName = (LPCSTR)IDR_MENU;
       wcex.lpszClassName = SZ_WNDCLASS_PLAY;
       wcex.hIconSm = NULL;
       if(!RegisterClassEx(&wcex))
          goto error;
       // create the play object
       hr = CoCreateInstance(CLSID_ltmmPlay, NULL, CLSCTX_INPROC_SERVER, IID_IltmmPlay, (void**) &g_pPlay);
       if(FAILED(hr))
          goto error;
       // create the video frame window
       if(!CreateWindow(SZ_WNDCLASS_PLAY, _T("Play"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_hInstance, NULL))
          goto error;
       ShowWindow(g_hwndPlay, nCmdShow);
       UpdateWindow(g_hwndPlay);
       // process until done
       while (GetMessage(&msg, NULL, 0, 0))
       {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
       }   error:
       if(g_pPlay)
          g_pPlay->Release();
       CoUninitialize();
       return 0;
    }