The following code demonstrates a simple media player application. It utilizes most of the functions available in the ltmmPlay object.
// define helper macros for using interfaces under C#ifndef COBJMACROS#define COBJMACROS#endif// include the LEAD Multimedia TOOLKIT header#include "ltmm.h"#include "resource.h"#include <tchar.h>#include <stdio.h>#include <math.h>#define SZ_WNDCLASS_PLAY _T("PLAY WNDCLASS")#define WM_PLAYNOTIFY (WM_USER + 1000)HINSTANCE g_hInstance; // application instance handleHWND g_hwndPlay; // video frame windowIltmmPlay* g_pPlay; // play object interface pointerint g_nPositionView; // current position indicator view modeenum{POSITIONVIEW_TIME,POSITIONVIEW_FRAME,POSITIONVIEW_TRACKING};//// SnapFrameToVideo// resizes the frame window to match the video width and height//void SnapFrameToVideo(void){HWND hwnd;RECT rcWindow, rcClient;long cx, cy;// get the frame windowIltmmPlay_get_VideoWindowFrame (g_pPlay, (long*) &hwnd);// get the video dimensionsIltmmPlay_get_VideoWidth (g_pPlay, &cx);IltmmPlay_get_VideoHeight (g_pPlay, &cy);// adjust by the border dimensionsGetWindowRect(hwnd, &rcWindow);GetClientRect(hwnd, &rcClient);cx += ((rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left));cy += ((rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top));// resize the windowSetWindowPos(hwnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER);}//// FreeSource// resets source and frees associated resources//void FreeSource(void){long type;VARIANT var;HGLOBAL hglobal;IltmmPlay_get_SourceType (g_pPlay, &type);if(type == ltmmPlay_Source_Array){IltmmPlay_get_SourceArray(g_pPlay, &var);IltmmPlay_ResetSource(g_pPlay);VariantClear(&var);}else if(type == ltmmPlay_Source_HGlobal){IltmmPlay_get_SourceHGlobal (g_pPlay, (long*) &hglobal);IltmmPlay_ResetSource(g_pPlay);GlobalFree(hglobal);}else{IltmmPlay_ResetSource(g_pPlay);}}//// SetSourceArray// preloads a SAFEARRAY with media data and assigns it to the play object//void SetSourceArray(void){HRESULT hr;HANDLE hfile;DWORD size, cb;void* buffer;VARIANT var;SAFEARRAY* psaSource;// open the source filehfile = CreateFile(MAKE_MEDIA_PATH("source.avi"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);if(hfile == INVALID_HANDLE_VALUE)return;// allocate same-sized SAFEARRAYsize = GetFileSize(hfile, NULL);psaSource = SafeArrayCreateVector(VT_UI1, 0, size);if(!psaSource){CloseHandle(hfile);return;}// read entire source into arraySafeArrayAccessData(psaSource, (void**) &buffer);if(!ReadFile(hfile, buffer, size, &cb, NULL) || cb != size){SafeArrayUnaccessData(psaSource);CloseHandle(hfile);SafeArrayDestroy(psaSource);return;}SafeArrayUnaccessData(psaSource);// close fileCloseHandle(hfile);// assign the source arrayVariantInit(&var);V_VT(&var) = (VT_ARRAY | VT_UI1);V_ARRAY(&var) = psaSource;hr = IltmmPlay_put_SourceArray (g_pPlay, var);if(FAILED(hr)){SafeArrayDestroy(psaSource);return;}}//// SetSourceArray// preloads global memory with media data and assigns it to the play object//void SetSourceHGlobal(void){HRESULT hr;HANDLE hfile;DWORD size, cb;void* buffer;HGLOBAL hglobal;// open the source filehfile = CreateFile(MAKE_MEDIA_PATH("source.avi"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);if(hfile == INVALID_HANDLE_VALUE)return;// allocate same-sized global memorysize = GetFileSize(hfile, NULL);hglobal = GlobalAlloc(GMEM_MOVEABLE, size);if(!hglobal){CloseHandle(hfile);return;}// read entire source into memorybuffer = GlobalLock(hglobal);if(!ReadFile(hfile, buffer, size, &cb, NULL) || cb != size){GlobalUnlock(hglobal);CloseHandle(hfile);GlobalFree(hglobal);return;}GlobalUnlock(hglobal);// close fileCloseHandle(hfile);hr = IltmmPlay_put_SourceHGlobal(g_pPlay, (long) hglobal);if(FAILED(hr)){GlobalFree(hglobal);return;}}//// PlayWndProc// video frame window procedure//LRESULT CALLBACK PlayWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){BSTR bstr;VARIANT_BOOL f;long l;TCHAR sz[2048];LPTSTR p;double d;HRESULT hr;ltmmSizeMode sm;long x, y, cx, cy;RECT rc;POINT pt;switch (message){case WM_CREATE:g_hwndPlay = hwnd;// window is the video window frameIltmmPlay_put_VideoWindowFrame (g_pPlay, (long) hwnd);// want notification messages as wellIltmmPlay_SetNotifyWindow (g_pPlay, (long) hwnd, WM_PLAYNOTIFY);// make sure we start playing immediatelyIltmmPlay_put_AutoStart (g_pPlay, VARIANT_TRUE);// set the source filebstr = SysAllocString((OLECHAR*)MAKE_MEDIA_PATH("source.avi"));IltmmPlay_put_SourceFile (g_pPlay, bstr);SysFreeString(bstr);SnapFrameToVideo();return 0;break;case WM_INITMENUPOPUP:if(GetSubMenu(GetMenu(hwnd), 0) == (HMENU)wParam){// enable menu items based on the play object stateIltmmPlay_get_State (g_pPlay, &l);EnableMenuItem((HMENU) wParam, ID_CONTROL_PLAY, (l == ltmmPlay_State_Paused || l == ltmmPlay_State_Stopped) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_PAUSE, (l == ltmmPlay_State_Running) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_STOP, (l == ltmmPlay_State_Running || l == ltmmPlay_State_Paused) ? MF_ENABLED : MF_GRAYED);// enable menu items based on seeking capabilitiesIltmmPlay_CheckSeekingCapabilities (g_pPlay, ltmmPlay_Seeking_Forward | ltmmPlay_Seeking_Backward | ltmmPlay_Seeking_FrameForward | ltmmPlay_Seeking_FrameBackward, &l);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKSTART, (l & ltmmPlay_Seeking_Backward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKEND, (l & ltmmPlay_Seeking_Forward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_NEXTFRAME, (l & ltmmPlay_Seeking_FrameForward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_PREVIOUSFRAME, (l & ltmmPlay_Seeking_FrameBackward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKSELECTIONSTART, (l & (ltmmPlay_Seeking_Forward | ltmmPlay_Seeking_Backward)) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKSELECTIONEND, (l & (ltmmPlay_Seeking_Forward | ltmmPlay_Seeking_Backward)) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_LASTFRAME, (l & ltmmPlay_Seeking_FrameForward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_FIRSTFRAME, (l & ltmmPlay_Seeking_FrameBackward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_STEPFORWARD1SEC, (l & ltmmPlay_Seeking_Forward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_STEPFORWARD10, (l & ltmmPlay_Seeking_Forward) ? MF_ENABLED : MF_GRAYED);// check the current speedIltmmPlay_get_Rate (g_pPlay, &d);CheckMenuItem((HMENU) wParam, ID_CONTROL_HALFSPEED, (fabs(d - 0.5) < 0.1) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_NORMALSPEED, (fabs(d - 1.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED);// check the current video size modeIltmmPlay_get_VideoWindowSizeMode (g_pPlay, &sm);CheckMenuItem((HMENU) wParam, ID_CONTROL_FITTOWINDOW, (sm == ltmmFit) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_STRETCHTOWINDOW, (sm == ltmmStretch) ? MF_CHECKED : MF_UNCHECKED);// enable volume menu itemsIltmmPlay_get_Volume (g_pPlay, &l);EnableMenuItem((HMENU) wParam, ID_CONTROL_INCREASEVOLUME, (l < 0) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_DECREASEVOLUME, (l > -10000) ? MF_ENABLED : MF_GRAYED);// enable balance menu itemsIltmmPlay_get_Balance (g_pPlay, &l);EnableMenuItem((HMENU) wParam, ID_CONTROL_PANRIGHT, (l < 10000) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_PANLEFT, (l > -10000) ? MF_ENABLED : MF_GRAYED);// check muteIltmmPlay_get_Mute (g_pPlay, &f);CheckMenuItem((HMENU) wParam, ID_CONTROL_MUTE, f ? MF_CHECKED : MF_UNCHECKED);// check auto rewindIltmmPlay_get_AutoRewind (g_pPlay, &f);CheckMenuItem((HMENU) wParam, ID_CONTROL_AUTOREWIND, f ? MF_CHECKED : MF_UNCHECKED);// check loopIltmmPlay_get_PlayCount (g_pPlay, &l);CheckMenuItem((HMENU) wParam, ID_CONTROL_LOOP, (l == 0) ? MF_CHECKED : MF_UNCHECKED);// enable processorsIltmmPlay_HasDialog(g_pPlay, ltmmPlay_Dlg_VideoProcessors, &f);EnableMenuItem((HMENU) wParam, ID_CONTROL_PROCESSORS_VIDEO, f ? MF_ENABLED : MF_GRAYED);IltmmPlay_HasDialog(g_pPlay, ltmmPlay_Dlg_AudioProcessors, &f);EnableMenuItem((HMENU) wParam, ID_CONTROL_PROCESSORS_AUDIO, f ? MF_ENABLED : MF_GRAYED);// check sourceIltmmPlay_get_SourceType (g_pPlay, &l);CheckMenuItem((HMENU) wParam, ID_CONTROL_SOURCE_FILE, (l == ltmmPlay_Source_File) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_SOURCE_ARRAY, (l == ltmmPlay_Source_Array) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_SOURCE_HGLOBAL, (l == ltmmPlay_Source_HGlobal) ? MF_CHECKED : MF_UNCHECKED);IltmmPlay_get_AutoStart (g_pPlay, &f);CheckMenuItem((HMENU) wParam, ID_CONTROL_AUTOSTART, f ? MF_CHECKED : MF_UNCHECKED);// check position viewCheckMenuItem((HMENU) wParam, ID_CONTROL_POSITIONVIEW_FRAME, (g_nPositionView == POSITIONVIEW_FRAME) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_POSITIONVIEW_TIME, (g_nPositionView == POSITIONVIEW_TIME) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_POSITIONVIEW_TRACKING, (g_nPositionView == POSITIONVIEW_TRACKING) ? MF_CHECKED : MF_UNCHECKED);}break;case WM_PLAYNOTIFY:switch(wParam){case ltmmPlay_Notify_TrackingSelectionChanged:break;case ltmmPlay_Notify_TrackingPositionChanged:p = sz;*p = _T('\0');if(g_nPositionView == POSITIONVIEW_TRACKING) // tracking position based{// display current tracking positionhr = IltmmPlay_get_CurrentTrackingPosition (g_pPlay, &l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Trk. Pos.: %d"), l);}// display current tracking selection starthr = IltmmPlay_get_TrackingSelectionStart(g_pPlay, &l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Trk. Start: %d"), l);}// display current tracking selection endhr= IltmmPlay_get_TrackingSelectionEnd (g_pPlay, &l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Trk. End: %d"), l);}}else if(g_nPositionView == POSITIONVIEW_FRAME) // frame based{// display current frame positionhr = IltmmPlay_get_CurrentFramePosition (g_pPlay, &l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Frame: %d"), l + 1);}// display total number of frameshr = IltmmPlay_get_FrameDuration (g_pPlay, &l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Total Frames: %d"), l);}}else // time based{// display the current positionhr = IltmmPlay_get_CurrentPosition (g_pPlay, &d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Position: %f"), d);}// display the total durationhr = IltmmPlay_get_Duration (g_pPlay, &d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Duration: %f"), d);}// display current selection starthr = IltmmPlay_get_SelectionStart (g_pPlay, &d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Start: %f"), d);}// display current selection endhr = IltmmPlay_get_SelectionEnd (g_pPlay, &d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("End: %f"), d);}}SetWindowText(hwnd, sz);break;case ltmmPlay_Notify_StateChanged:switch(LOWORD(lParam)){case ltmmPlay_State_NotReady:_stprintf(sz, _T("Not Ready"));SetWindowText(hwnd, sz);break;case ltmmPlay_State_Stopped:// uncomment the following line to view the graph in DirectShow GraphEdit// IltmmPlay_EditGraph(g_pPlay);IltmmPlay_get_SourceType (g_pPlay, &l);if(l == ltmmPlay_Source_Array){_stprintf(sz, _T("Stopped - [array]"));}else if(l == ltmmPlay_Source_HGlobal){_stprintf(sz, _T("Stopped - [hglobal]"));}else{IltmmPlay_get_SourceFile(g_pPlay, &bstr);_stprintf(sz, _T("Stopped - [%ls]"), bstr);SysFreeString(bstr);}SetWindowText(hwnd, sz);break;case ltmmPlay_State_Paused:IltmmPlay_get_SourceType (g_pPlay, &l);if(l == ltmmPlay_Source_Array){_stprintf(sz, _T("Paused - [array]"));}else if(l == ltmmPlay_Source_HGlobal){_stprintf(sz, _T("Paused - [hglobal]"));}else{IltmmPlay_get_SourceFile (g_pPlay, &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 itIltmmPlay_get_FullScreenMode (g_pPlay, &f);if(f){IltmmPlay_put_FullScreenMode (g_pPlay, VARIANT_FALSE);return 0;}}break;case WM_DESTROY:FreeSource();// no more notificationsIltmmPlay_SetNotifyWindow (g_pPlay, (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 startIltmmPlay_get_AutoStart (g_pPlay, &f);IltmmPlay_put_AutoStart (g_pPlay, f ? VARIANT_FALSE : VARIANT_TRUE);return 0;break;case ID_CONTROL_PLAY:// play fileIltmmPlay_Run (g_pPlay);return 0;break;case ID_CONTROL_PAUSE:// pause playbackIltmmPlay_Pause (g_pPlay);return 0;break;case ID_CONTROL_STOP:// stop playbackIltmmPlay_Stop (g_pPlay);return 0;break;case ID_CONTROL_HALFSPEED:// set to half the normal playback speedIltmmPlay_put_Rate (g_pPlay, 0.5);return 0;break;case ID_CONTROL_NORMALSPEED:// set to normal speedIltmmPlay_put_Rate (g_pPlay, 1.0);return 0;break;case ID_CONTROL_SEEKSTART:// seek to file startIltmmPlay_SeekStart(g_pPlay);return 0;break;case ID_CONTROL_SEEKEND:// seek to file endIltmmPlay_SeekEnd (g_pPlay);return 0;break;case ID_CONTROL_SEEKSELECTIONSTART:// seek to the start of the current selectionIltmmPlay_SeekSelectionStart (g_pPlay);return 0;break;case ID_CONTROL_SEEKSELECTIONEND:// seek to the end of the current selectionIltmmPlay_SeekSelectionEnd (g_pPlay);return 0;break;case ID_CONTROL_SETSELECTIONSTART:// set the start of the selection to the current positionIltmmPlay_MarkSelectionStart (g_pPlay);return 0;break;case ID_CONTROL_SETSELECTIONEND:// set the end of the selection to the current positionIltmmPlay_MarkSelectionEnd (g_pPlay);return 0;break;case ID_CONTROL_CLEARSELECTION:// clear the current selectionIltmmPlay_get_Duration(g_pPlay, &d);IltmmPlay_put_SelectionStart (g_pPlay, 0.0);IltmmPlay_put_SelectionEnd (g_pPlay, d);return 0;break;case ID_CONTROL_NEXTFRAME:// goto the next frameIltmmPlay_NextFrame (g_pPlay);return 0;break;case ID_CONTROL_PREVIOUSFRAME:// goto the previous frameIltmmPlay_PreviousFrame (g_pPlay);return 0;break;case ID_CONTROL_FIRSTFRAME:// goto to the first frameIltmmPlay_put_CurrentFramePosition (g_pPlay, 0);return 0;break;case ID_CONTROL_LASTFRAME:// goto to the last frameIltmmPlay_get_FrameDuration (g_pPlay, &l);IltmmPlay_put_CurrentFramePosition (g_pPlay, l - 1);return 0;break;case ID_CONTROL_STEPFORWARD1SEC:// step forward 1 secondIltmmPlay_get_CurrentPosition (g_pPlay, &d);IltmmPlay_put_CurrentPosition (g_pPlay, d + 1.0);return 0;break;case ID_CONTROL_STEPFORWARD10:// step forward 10%IltmmPlay_get_CurrentTrackingPosition (g_pPlay, &l);IltmmPlay_put_CurrentTrackingPosition(g_pPlay, l + 1000);return 0;break;case ID_CONTROL_FITTOWINDOW:// fit the video to the windowIltmmPlay_put_VideoWindowSizeMode (g_pPlay, ltmmFit);return 0;break;case ID_CONTROL_STRETCHTOWINDOW:// stretch the video to the windowIltmmPlay_put_VideoWindowSizeMode (g_pPlay, ltmmStretch);return 0;break;case ID_CONTROL_MUTE:// toggle muteIltmmPlay_get_Mute (g_pPlay, &f);IltmmPlay_put_Mute (g_pPlay, f ? VARIANT_FALSE : VARIANT_TRUE);return 0;break;case ID_CONTROL_INCREASEVOLUME:// increase the volumeIltmmPlay_get_Volume (g_pPlay, &l);IltmmPlay_put_Volume (g_pPlay, min(0, l + 300));return 0;break;case ID_CONTROL_DECREASEVOLUME:// decrease the volumeIltmmPlay_get_Volume (g_pPlay, &l);IltmmPlay_put_Volume (g_pPlay, max(-10000, l - 300));return 0;break;case ID_CONTROL_PANRIGHT:// pan balance to the rightIltmmPlay_get_Balance (g_pPlay, &l);IltmmPlay_put_Balance(g_pPlay, min(10000, l + 300));return 0;break;case ID_CONTROL_PANLEFT:// pan balance to the leftIltmmPlay_get_Balance (g_pPlay, &l);IltmmPlay_put_Balance (g_pPlay, max(-10000, l - 300));return 0;break;case ID_CONTROL_LOOP:// toggle loopingIltmmPlay_get_PlayCount(g_pPlay, &l);IltmmPlay_put_PlayCount (g_pPlay, l ? 0 : 1);return 0;break;case ID_CONTROL_FULLSCREEN:// toggle fullscreen modeIltmmPlay_ToggleFullScreenMode (g_pPlay);return 0;break;case ID_CONTROL_AUTOREWIND:// toggle auto rewindIltmmPlay_get_AutoRewind (g_pPlay, &f);IltmmPlay_put_AutoRewind (g_pPlay, f ? VARIANT_FALSE : VARIANT_TRUE);return 0;break;case ID_CONTROL_PROCESSORS_VIDEO:// invoke video processor dialog boxIltmmPlay_ShowDialog (g_pPlay, ltmmPlay_Dlg_VideoProcessors, (long) hwnd);return 0;break;case ID_CONTROL_PROCESSORS_AUDIO:// invoke audio processor dialog boxIltmmPlay_ShowDialog (g_pPlay, ltmmPlay_Dlg_AudioProcessors, (long) hwnd);return 0;break;case ID_CONTROL_SOURCE_FILE:// set the source fileFreeSource();bstr = SysAllocString((OLECHAR*)MAKE_MEDIA_PATH("source.avi"));IltmmPlay_put_SourceFile (g_pPlay, bstr);SysFreeString(bstr);SnapFrameToVideo();return 0;break;case ID_CONTROL_SOURCE_ARRAY:// set the source arrayFreeSource();SetSourceArray();SnapFrameToVideo();return 0;break;case ID_CONTROL_SOURCE_HGLOBAL:// set the source hglobalFreeSource();SetSourceHGlobal();SnapFrameToVideo();return 0;break;case ID_CONTROL_MEDIAINFORMATION:// display available media informationp = sz;IltmmPlay_get_Title (g_pPlay, &bstr);p += _stprintf(p, _T("Title = '%ls'"), bstr ? bstr : L"");SysFreeString(bstr);IltmmPlay_get_Author (g_pPlay, &bstr);p += _stprintf(p, _T(", Author = '%ls'"), bstr ? bstr : L"");SysFreeString(bstr);IltmmPlay_get_Copyright (g_pPlay, &bstr);p += _stprintf(p, _T(", Copyright = '%ls'"), bstr ? bstr : L"");SysFreeString(bstr);IltmmPlay_get_Description (g_pPlay, &bstr);p += _stprintf(p, _T(", Description = '%ls'"), bstr ? bstr : L"");SysFreeString(bstr);IltmmPlay_get_Rating (g_pPlay, &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 windowIltmmPlay_get_VideoWindowLeft (g_pPlay, &x);IltmmPlay_get_VideoWindowTop (g_pPlay, &y);IltmmPlay_get_VideoWindowWidth (g_pPlay, &cx);IltmmPlay_get_VideoWindowHeight (g_pPlay, &cy);SetRect(&rc, x, y, x + cx, y + cy);pt.x = (short) LOWORD(lParam);pt.y = (short) HIWORD(lParam);if(PtInRect(&rc, pt)){IltmmPlay_get_State (g_pPlay, &l);if(l == ltmmPlay_State_Stopped || l == ltmmPlay_State_Paused)IltmmPlay_Run (g_pPlay);else if(l == ltmmPlay_State_Running)IltmmPlay_Pause (g_pPlay);}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;hPrevInstance = hPrevInstance ;lpCmdLine = lpCmdLine ;nCmdShow = nCmdShow ;g_hInstance = hInstance;// initialize COM libraryhr = CoInitialize(NULL);if(FAILED(hr))goto error;// register the video frame window classwcex.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 objecthr = CoCreateInstance(&CLSID_ltmmPlay, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmPlay, (void**) &g_pPlay);if(FAILED(hr))goto error;// create the video frame windowif(!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 donewhile (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}error:if(g_pPlay)IUnknown_Release(g_pPlay);CoUninitialize();return 0;}