The following code demonstrates a simple media player application. It utilizes most of the functions available in the ltmfPlay object.
#define MAKE_MEDIA_PATH(pFileName) (TEXT("C:\\LEADTOOLS\\Media\\")TEXT(pFileName))#include "StdAfx.h"// include the LEAD Media Foundation TOOLKIT header#include "ltmf.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 windowIltmfPlay* 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 windowg_pPlay->get_VideoWindowFrame ((long*) &hwnd);// get the video dimensionsg_pPlay->get_VideoWidth (&cx);g_pPlay->get_VideoHeight (&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;g_pPlay->get_SourceType (&type);if(type == ltmfPlay_Source_Array){g_pPlay->get_SourceArray (&var);g_pPlay->ResetSource ();VariantClear(&var);}else if(type == ltmfPlay_Source_HGlobal){g_pPlay->get_SourceHGlobal ((long*) &hglobal);g_pPlay->ResetSource ();GlobalFree(hglobal);}else{g_pPlay->ResetSource ();}}//// 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(_T("c:\\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 = g_pPlay->put_SourceArray (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(_T("c:\\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 = g_pPlay->put_SourceHGlobal ((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;ltmfSizeMode sm;long x, y, cx, cy;RECT rc;POINT pt;switch (message){case WM_CREATE:g_hwndPlay = hwnd;// window is the video window frameg_pPlay->put_VideoWindowFrame ((long) hwnd);// want notification messages as wellg_pPlay->SetNotifyWindow ((long) hwnd, WM_PLAYNOTIFY);// make sure we start playing immediatelyg_pPlay->put_AutoStart (VARIANT_TRUE);// set the source filebstr = SysAllocString(L"c:\\source.avi");g_pPlay->put_SourceFile(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 stateg_pPlay->get_State (&l);EnableMenuItem((HMENU) wParam, ID_CONTROL_PLAY, (l == ltmfPlay_State_Paused || l == ltmfPlay_State_Stopped) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_PAUSE, (l == ltmfPlay_State_Running) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_STOP, (l == ltmfPlay_State_Running || l == ltmfPlay_State_Paused) ? MF_ENABLED : MF_GRAYED);// enable menu items based on seeking capabilitiesg_pPlay->CheckSeekingCapabilities (ltmfPlay_Seeking_Forward | ltmfPlay_Seeking_Backward | ltmfPlay_Seeking_FrameForward | ltmfPlay_Seeking_FrameBackward, &l);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKSTART, (l & ltmfPlay_Seeking_Backward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKEND, (l & ltmfPlay_Seeking_Forward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_NEXTFRAME, (l & ltmfPlay_Seeking_FrameForward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_PREVIOUSFRAME, (l & ltmfPlay_Seeking_FrameBackward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKSELECTIONSTART, (l & (ltmfPlay_Seeking_Forward | ltmfPlay_Seeking_Backward)) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_SEEKSELECTIONEND, (l & (ltmfPlay_Seeking_Forward | ltmfPlay_Seeking_Backward)) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_LASTFRAME, (l & ltmfPlay_Seeking_FrameForward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_FIRSTFRAME, (l & ltmfPlay_Seeking_FrameBackward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_STEPFORWARD1SEC, (l & ltmfPlay_Seeking_Forward) ? MF_ENABLED : MF_GRAYED);EnableMenuItem((HMENU) wParam, ID_CONTROL_STEPFORWARD10, (l & ltmfPlay_Seeking_Forward) ? MF_ENABLED : MF_GRAYED);// check the current speedg_pPlay->get_Rate (&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 modeg_pPlay->get_VideoWindowSizeMode(&sm);CheckMenuItem((HMENU) wParam, ID_CONTROL_FITTOWINDOW, (sm == ltmfFit) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_STRETCHTOWINDOW, (sm == ltmfStretch) ? MF_CHECKED : MF_UNCHECKED);// enable volume menu itemsg_pPlay->get_Volume (&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 itemsg_pPlay->get_Balance (&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 muteg_pPlay->get_Mute(&f);CheckMenuItem((HMENU) wParam, ID_CONTROL_MUTE, f ? MF_CHECKED : MF_UNCHECKED);// check auto rewindg_pPlay->get_AutoRewind (&f);CheckMenuItem((HMENU) wParam, ID_CONTROL_AUTOREWIND, f ? MF_CHECKED : MF_UNCHECKED);// check loopg_pPlay->get_PlayCount (&l);CheckMenuItem((HMENU) wParam, ID_CONTROL_LOOP, (l == 0) ? MF_CHECKED : MF_UNCHECKED);// enable processorsg_pPlay->HasDialog (ltmfPlay_Dlg_VideoProcessors, &f);EnableMenuItem((HMENU) wParam, ID_CONTROL_PROCESSORS_VIDEO, f ? MF_ENABLED : MF_GRAYED);g_pPlay->HasDialog (ltmfPlay_Dlg_AudioProcessors, &f);EnableMenuItem((HMENU) wParam, ID_CONTROL_PROCESSORS_AUDIO, f ? MF_ENABLED : MF_GRAYED);// check sourceg_pPlay->get_SourceType (&l);CheckMenuItem((HMENU) wParam, ID_CONTROL_SOURCE_FILE, (l == ltmfPlay_Source_File) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_SOURCE_ARRAY, (l == ltmfPlay_Source_Array) ? MF_CHECKED : MF_UNCHECKED);CheckMenuItem((HMENU) wParam, ID_CONTROL_SOURCE_HGLOBAL, (l == ltmfPlay_Source_HGlobal) ? MF_CHECKED : MF_UNCHECKED);g_pPlay->get_AutoStart (&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 ltmfPlay_Notify_TrackingSelectionChanged:break;case ltmfPlay_Notify_TrackingPositionChanged:p = sz;*p = _T('\0');if(g_nPositionView == POSITIONVIEW_TRACKING) // tracking position based{// display current tracking positionhr = g_pPlay->get_CurrentTrackingPosition (&l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Trk. Pos.: %d"), l);}// display current tracking selection starthr = g_pPlay->get_TrackingSelectionStart(&l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Trk. Start: %d"), l);}// display current tracking selection endhr= g_pPlay->get_TrackingSelectionEnd(&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 = g_pPlay->get_CurrentFramePosition (&l);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Frame: %d"), l + 1);}// display total number of frameshr = g_pPlay->get_FrameDuration (&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 = g_pPlay->get_CurrentPosition (&d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Position: %f"), d);}// display the total durationhr = g_pPlay->get_Duration(&d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Duration: %f"), d);}// display current selection starthr = g_pPlay->get_SelectionStart (&d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("Start: %f"), d);}// display current selection endhr = g_pPlay->get_SelectionEnd (&d);if(SUCCEEDED(hr)){if(p != sz)p += _stprintf(p, _T(", "));p += _stprintf(p, _T("End: %f"), d);}}SetWindowText(hwnd, sz);break;case ltmfPlay_Notify_StateChanged:switch(LOWORD(lParam)){case ltmfPlay_State_NotReady:_stprintf(sz, _T("Not Ready"));SetWindowText(hwnd, sz);break;case ltmfPlay_State_Stopped:g_pPlay->get_SourceType (&l);if(l == ltmfPlay_Source_Array){_stprintf(sz, _T("Stopped - [array]"));}else if(l == ltmfPlay_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 ltmfPlay_State_Paused:g_pPlay->get_SourceType (&l);if(l == ltmfPlay_Source_Array){_stprintf(sz, _T("Paused - [array]"));}else if(l == ltmfPlay_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 ltmfPlay_State_Running:_stprintf(sz, _T("Playing"));SetWindowText(hwnd, sz);break;}break;case ltmfPlay_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 itg_pPlay->get_FullScreenMode(&f);if(f){g_pPlay->put_FullScreenMode(VARIANT_FALSE);return 0;}} break;case WM_DESTROY:FreeSource();// no more notificationsg_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 startg_pPlay->get_AutoStart(&f);g_pPlay->put_AutoStart(f ? VARIANT_FALSE : VARIANT_TRUE);return 0;break;case ID_CONTROL_PLAY:// play fileg_pPlay->Run();return 0;break;case ID_CONTROL_PAUSE:// pause playbackg_pPlay->Pause();return 0;break;case ID_CONTROL_STOP:// stop playbackg_pPlay->Stop();return 0;break;case ID_CONTROL_HALFSPEED:// set to half the normal playback speedg_pPlay->put_Rate(0.5);return 0;break;case ID_CONTROL_NORMALSPEED:// set to normal speedg_pPlay->put_Rate(1.0);return 0;break;case ID_CONTROL_SEEKSTART:// seek to file startg_pPlay->SeekStart();return 0;break;case ID_CONTROL_SEEKEND:// seek to file endg_pPlay->SeekEnd();return 0;break;case ID_CONTROL_SEEKSELECTIONSTART:// seek to the start of the current selectiong_pPlay->SeekSelectionStart();return 0;break;case ID_CONTROL_SEEKSELECTIONEND:// seek to the end of the current selectiong_pPlay->SeekSelectionEnd();return 0;break;case ID_CONTROL_SETSELECTIONSTART:// set the start of the selection to the current positiong_pPlay->MarkSelectionStart();return 0;break;case ID_CONTROL_SETSELECTIONEND:// set the end of the selection to the current positiong_pPlay->MarkSelectionEnd();return 0;break;case ID_CONTROL_CLEARSELECTION:// clear the current selectiong_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 frameg_pPlay->NextFrame();return 0;break;case ID_CONTROL_PREVIOUSFRAME:// goto the previous frameg_pPlay->PreviousFrame();return 0;break;case ID_CONTROL_FIRSTFRAME:// go to the first frameg_pPlay->put_CurrentFramePosition(0);return 0;break;case ID_CONTROL_LASTFRAME:// go to the last frameg_pPlay->get_FrameDuration(&l);g_pPlay->put_CurrentFramePosition(l - 1);return 0;break;case ID_CONTROL_STEPFORWARD1SEC:// step forward 1 secondg_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 windowg_pPlay->put_VideoWindowSizeMode(ltmfFit);return 0;break;case ID_CONTROL_STRETCHTOWINDOW:// stretch the video to the windowg_pPlay->put_VideoWindowSizeMode(ltmfStretch);return 0;break;case ID_CONTROL_MUTE:// toggle muteg_pPlay->get_Mute(&f);g_pPlay->put_Mute(f ? VARIANT_FALSE : VARIANT_TRUE);return 0;break;case ID_CONTROL_INCREASEVOLUME:// increase the volumeg_pPlay->get_Volume(&l);g_pPlay->put_Volume(min(0, l + 300));return 0;break;case ID_CONTROL_DECREASEVOLUME:// decrease the volumeg_pPlay->get_Volume(&l);g_pPlay->put_Volume(max(-10000, l - 300));return 0;break;case ID_CONTROL_PANRIGHT:// pan balance to the rightg_pPlay->get_Balance(&l);g_pPlay->put_Balance(min(10000, l + 300));return 0;break;case ID_CONTROL_PANLEFT:// pan balance to the leftg_pPlay->get_Balance(&l);g_pPlay->put_Balance(max(-10000, l - 300));return 0;break;case ID_CONTROL_LOOP:// toggle loopingg_pPlay->get_PlayCount(&l);g_pPlay->put_PlayCount(l ? 0 : 1);return 0;break;case ID_CONTROL_FULLSCREEN:// toggle fullscreen modeg_pPlay->ToggleFullScreenMode();return 0;break;case ID_CONTROL_AUTOREWIND:// toggle auto rewindg_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 boxg_pPlay->ShowDialog(ltmfPlay_Dlg_VideoProcessors, (long) hwnd);return 0;break;case ID_CONTROL_PROCESSORS_AUDIO:// invoke audio processor dialog boxg_pPlay->ShowDialog(ltmfPlay_Dlg_AudioProcessors, (long) hwnd);return 0;break;case ID_CONTROL_SOURCE_FILE:// set the source fileFreeSource();bstr = SysAllocString(MAKE_MEDIA_PATH("source.avi"));g_pPlay->put_SourceFile(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;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 windowg_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 == ltmfPlay_State_Stopped || l == ltmfPlay_State_Paused)g_pPlay->Run();else if(l == ltmfPlay_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 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 = (LPCWSTR)IDR_MENU;wcex.lpszClassName = SZ_WNDCLASS_PLAY;wcex.hIconSm = NULL;if(!RegisterClassEx(&wcex))goto error;// create the play objecthr = CoCreateInstance(CLSID_ltmfPlay, NULL, CLSCTX_INPROC_SERVER, IID_IltmfPlay, (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)g_pPlay->Release();CoUninitialize();return 0;}