Advanced Capture Application for C

The following code demonstrates an advanced capture application. It utilizes most of the functions available in the ltmmCapture object.

#define MAKE_MEDIA_PATH(pFileName) (TEXT("C:\\LEADTOOLS 17.5\\Media\\")TEXT(pFileName))


// define helper macros for using interfaces under C
#ifndef COBJMACROS
   #define COBJMACROS
#endif

#define UNUSED_PARAMETER(x) (void) (x)

// include the LEAD Multimedia TOOLKIT header
#include "ltmm.h"

#include "resource.h"
#include <tchar.h>
#include <stdio.h>
#include <olectl.h>
#include <math.h>
#include <assert.h>

#define SZ_WNDCLASS_CAPTURE _T("CAPTURE WNDCLASS")
#define WM_CAPTURENOTIFY (WM_USER + 1000) 


HINSTANCE g_hInstance;    // application instance handle
HWND g_hwndCapture;      // video frame window
IltmmCapture* g_pCapture;   // capture object interface pointer

//
// FreeTarget
// resets target and free asssociated resources
//
void FreeTarget(void) 
{
   long type; 
   VARIANT var; 

   IltmmCapture_get_TargetType(g_pCapture, &type); 
   if(type == ltmmCapture_Target_Array) 
   {
      IltmmCapture_get_TargetArray(g_pCapture, &var); 
      IltmmCapture_ResetTarget(g_pCapture); 
      VariantClear(&var); 
   }
   else
   {
      IltmmCapture_ResetTarget (g_pCapture); 
   }
}

//
// 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 window
   IltmmCapture_get_VideoWindowFrame(g_pCapture, (long*) &hwnd); 

   // get the video dimensions
   IltmmCapture_get_VideoWidth(g_pCapture, &cx); 
   IltmmCapture_get_VideoHeight(g_pCapture, &cy); 

   // adjust by the border dimensions
   GetWindowRect(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 window
   SetWindowPos(hwnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER); 
}

//
// CaptureWndProc
// video frame window procedure
//
LRESULT CALLBACK CaptureWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{
   VARIANT_BOOL f; 
   HRESULT hr; 
   HGLOBAL hDIB; 
   IPictureDisp* pPictureDisp; 
   BSTR bstr; 
   IltmmDevices* pDevices; 
   IltmmTargetDevices* pTargetDevices; 
   long index; 
   IltmmCompressors* pCompressors; 
   long l; 
   long l2; 
   BOOL fActive; 
   ltmmSizeMode sm; 
   TCHAR sz[2048]; 
   LPTSTR p; 
   double d; 
   VARIANT var; 
   long x, y, cx, cy; 
   RECT rc; 
   POINT pt; 
   IltmmVCRControl* pVCR; 


   switch (message) 
   {
   case WM_CREATE: 
      g_hwndCapture = hwnd; 

      // window is the video window frame
      IltmmCapture_put_VideoWindowFrame(g_pCapture, (long) hwnd); 


      // want notification messages as well
      IltmmCapture_SetNotifyWindow(g_pCapture, (long) hwnd, WM_CAPTURENOTIFY); 

      // set preview source video only
      IltmmCapture_put_PreviewSource(g_pCapture, ltmmCapture_Preview_Video); 

      // enable preview
      IltmmCapture_put_Preview(g_pCapture, VARIANT_TRUE); 

      // set preferred renderer
      IltmmCapture_put_PreferredVideoRenderer(g_pCapture, ltmmVideoRenderer_VMR9); 

      // disable close captioning
      IltmmCapture_put_CloseCaptioning(g_pCapture, VARIANT_FALSE); 

      // assign initial frame delay
      IltmmCapture_put_FrameDelay(g_pCapture, 1.0); 

      // assign a target file
      bstr = SysAllocString(MAKE_MEDIA_PATH("target.avi"));
      IltmmCapture_put_TargetFile(g_pCapture, bstr); 
      SysFreeString(bstr); 

      // select the LEAD video compressor
      IltmmCapture_get_VideoCompressors(g_pCapture, &pCompressors); 
      bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MCMP/MJPEG Codec (2.0)");
      IltmmCompressors_Find(pCompressors, bstr, &index); 
      SysFreeString(bstr); 
      if(index >= 0) 
         IltmmCompressors_put_Selection(pCompressors, index); 
      IUnknown_Release(pCompressors); 


      // select the MP3 audio video compressor
      IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); 
      bstr = SysAllocString(L"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\85MPEG Layer-3");
      IltmmCompressors_Find(pCompressors, bstr, &index); 
      SysFreeString(bstr); 
      if(index >= 0) 
         IltmmCompressors_put_Selection(pCompressors, index); 
      IUnknown_Release(pCompressors); 

      // target format is AVI
      IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); 

      // preallocate file to 10 MB
      IltmmCapture_AllocTarget(g_pCapture, 10); 

      // select the first audio device available
      IltmmCapture_get_AudioDevices(g_pCapture, &pDevices); 
      IltmmDevices_put_Selection(pDevices, 0); 
      IUnknown_Release(pDevices); 

      // select the first video device available
      IltmmCapture_get_VideoDevices(g_pCapture, &pDevices); 
      IltmmDevices_put_Selection(pDevices, 0); 
      IUnknown_Release(pDevices); 

      SnapFrameToVideo();

      return 0; 
      break; 
   case WM_CAPTURENOTIFY: 
      switch(wParam) 
      {
      case ltmmCapture_Notify_Started: 
         _stprintf(sz, _T("Started"));
         SetWindowText(hwnd, sz); 
         break; 
      case ltmmCapture_Notify_Complete: 
         // stop recording, if vcr output
         IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_Stop(pVCR); 
         IUnknown_Release(pVCR); 

         IltmmCapture_get_Mode(g_pCapture, &l); 
         if(l == ltmmCapture_Mode_Still) 
         {
            _stprintf(sz, _T("Complete - [still]")); 
         }
         else
         {
            IltmmCapture_get_TargetType(g_pCapture, &l); 
            if(l == ltmmCapture_Target_Array) 
            {
               _stprintf(sz, _T("Complete - [array]")); 
            }
            else if(l == ltmmCapture_Target_Device) 
            {
               _stprintf(sz, _T("Complete - [device]")); 
            }
            else
            {
               IltmmCapture_get_TargetFile(g_pCapture, &bstr); 
               _stprintf(sz, _T("Complete - [%ls]"), bstr); 
               SysFreeString(bstr); 
            }
         }
         SetWindowText(hwnd, sz); 

         break; 
      case ltmmCapture_Notify_ErrorAbort: 
         // stop recording, if vcr output
         IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_Stop (pVCR); 
         IUnknown_Release(pVCR); 

         _stprintf(sz, _T("Error 0x%.8X. Capture stopped."), lParam); 

         MessageBox(hwnd, sz, _T("Play"), MB_ICONEXCLAMATION | MB_OK); 
         break; 
      case ltmmCapture_Notify_Progress: 
         p = sz; 

         *p = _T('\0'); 

         hr = IltmmCapture_get_NumDropped(g_pCapture, &l); 
         if(SUCCEEDED(hr)) 
         {
            if(p != sz) 
               p += _stprintf(p, _T(", "));
            p += _stprintf(p, _T("Dropped: %d"), l); 
         }

         hr = IltmmCapture_get_NumNotDropped(g_pCapture, &l); 
         if(SUCCEEDED(hr)) 
         {
            if(p != sz) 
               p += _stprintf(p, _T(", "));
            p += _stprintf(p, _T("Not Dropped: %d"), l); 
         }

         hr = IltmmCapture_get_AverageFrameSize(g_pCapture, &l); 
         if(SUCCEEDED(hr)) 
         {
            if(p != sz) 
               p += _stprintf(p, _T(", "));
            p += _stprintf(p, _T("Frame Size: %d"), l); 
         }

         IltmmCapture_get_Mode(g_pCapture, &l); 
         if(l != ltmmCapture_Mode_Still || l != ltmmCapture_Mode_ManualFrames) 
         {
            // only display the capture time for free running captures
            hr = IltmmCapture_get_CaptureTime(g_pCapture, &d); 
            if(SUCCEEDED(hr)) 
            {
               if(p != sz) 
                  p += _stprintf(p, _T(", "));
               p += _stprintf(p, _T("Time: %f"), d); 

            }
         }
         SetWindowText(hwnd, sz); 
         break; 
      }
      return 0; 
      break; 
   case WM_KEYDOWN: 
      if(wParam == VK_ESCAPE) 
      {
         // if fullscreen mode then exit it
         IltmmCapture_get_FullScreenMode(g_pCapture, &f); 
         if(f) 
         {
            IltmmCapture_put_FullScreenMode(g_pCapture, VARIANT_FALSE); 
            return 0; 
         }
      }
      break; 
   case WM_DESTROY: 
      // no more notifications
      FreeTarget();
      IltmmCapture_SetNotifyWindow(g_pCapture, (long) NULL, 0); 
      PostQuitMessage(0); 
      break; 
   case WM_INITMENUPOPUP: 
      if(GetSubMenu(GetMenu(hwnd), 0) == (HMENU)wParam) 
      {
         // determine whether the object is active
         IltmmCapture_get_State(g_pCapture, &l); 
         fActive = (l == ltmmCapture_State_Pending || l == ltmmCapture_State_Running || l == ltmmCapture_State_Paused); 

         // enable stop if active
         EnableMenuItem((HMENU) wParam, ID_CONTROL_STOPCAPTURE, fActive ? MF_ENABLED : MF_GRAYED); 

         // enable run if paused
         EnableMenuItem((HMENU) wParam, ID_CONTROL_RUN, (l == ltmmCapture_State_Paused) ? MF_ENABLED : MF_GRAYED); 

         // enable pause if running or pending
         EnableMenuItem((HMENU) wParam, ID_CONTROL_PAUSE, (l == ltmmCapture_State_Paused || l == ltmmCapture_State_Pending) ? MF_ENABLED : MF_GRAYED); 

         // determine if capture properties are available
         IltmmCapture_HasDialog(g_pCapture, ltmmCapture_Dlg_Capture, &f); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREPROPERTIES, (!fActive && f) ? MF_ENABLED : MF_GRAYED); 

         // can perform normal capture? 
         IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_VideoOrAudio, &f); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_STARTCAPTURE, f ? MF_ENABLED : MF_GRAYED); 

         // can perform auto frame capture? 
         IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_AutoFrames, &f); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREAUTOFRAMES, f ? MF_ENABLED : MF_GRAYED); 

         // can perform manual frame capture? 
         IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_ManualFrames, &f); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREMANUALFRAMES, f ? MF_ENABLED : MF_GRAYED); 

         // can perform still image capture? 
         IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_Still, &f); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREDIB, f ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREPICTURE, f ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_GETSTILLDIB, f ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_GETSTILLPICTURE, f ? MF_ENABLED : MF_GRAYED); 

         // check the current video size mode
         IltmmCapture_get_VideoWindowSizeMode(g_pCapture, &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); 

         // check preview
         IltmmCapture_get_Preview(g_pCapture, &f); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_PREVIEW, f ? MF_CHECKED : MF_UNCHECKED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_PREVIEW, !fActive ? MF_ENABLED : MF_GRAYED); 

         // check preview audio
         IltmmCapture_get_PreviewSource(g_pCapture, &l); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_PREVIEWVIDEOANDAUDIO, (l == ltmmCapture_Preview_VideoAndAudio) ? MF_CHECKED : MF_UNCHECKED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_PREVIEWVIDEOANDAUDIO, !fActive ? MF_ENABLED : MF_GRAYED); 

         // check close captioning
         IltmmCapture_get_CloseCaptioning(g_pCapture, &f); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_CLOSECAPTIONING, f ? MF_CHECKED : MF_UNCHECKED); 

         IltmmCapture_get_CloseCaptionAvailable(g_pCapture, &f); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_CLOSECAPTIONING, (!fActive && f) ? MF_ENABLED : MF_GRAYED); 


         // check master stream
         IltmmCapture_get_MasterStream(g_pCapture, &l); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_NONE, (l == ltmmCapture_MasterStream_None) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_AUDIO, (l == ltmmCapture_MasterStream_Audio) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_VIDEO, (l == ltmmCapture_MasterStream_Video) ? MF_CHECKED : MF_UNCHECKED); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_NONE, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_AUDIO, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_MASTERSTREAM_VIDEO, (!fActive) ? MF_ENABLED : MF_GRAYED); 

         // check frame rate
         IltmmCapture_get_UseFrameRate(g_pCapture, &f); 
         IltmmCapture_get_FrameRate(g_pCapture, &d); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_DEFAULT, (!f) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_15FPS, (f && fabs(d - 15.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_30FPS, (f && fabs(d - 30.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_DEFAULT, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_15FPS, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMERATE_30FPS, (!fActive) ? MF_ENABLED : MF_GRAYED); 

         // check time limit
         IltmmCapture_get_UseTimeLimit(g_pCapture, &f); 
         IltmmCapture_get_TimeLimit(g_pCapture, &d); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_NONE, (!f) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_15SEC, (f && fabs(d - 15.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_30SEC, (f && fabs(d - 30.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_NONE, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_15SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_TIMELIMIT_30SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); 

         // check frame delay
         IltmmCapture_get_FrameDelay(g_pCapture, &d); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_1SEC, (fabs(d - 1.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_5SEC, (fabs(d - 5.0) < 0.1) ? MF_CHECKED : MF_UNCHECKED); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_1SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_FRAMEDELAY_5SEC, (!fActive) ? MF_ENABLED : MF_GRAYED); 

         // check target
         IltmmCapture_get_TargetType(g_pCapture, &l); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGET_FILE, (l == ltmmCapture_Target_File) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGET_ARRAY, (l == ltmmCapture_Target_Array) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGET_DEVICE, (l == ltmmCapture_Target_Device) ? MF_CHECKED : MF_UNCHECKED); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGET_FILE, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGET_ARRAY, (!fActive) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGET_DEVICE, (!fActive) ? MF_ENABLED : MF_GRAYED); 

         IltmmCapture_get_TargetFormat(g_pCapture, &l); 
         IltmmCapture_get_TargetType(g_pCapture, &l2); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_AVI, (l == ltmmCapture_TargetFormat_Avi) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_WAVE, (l == ltmmCapture_TargetFormat_WAVE) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_MPEG1AUDIO, (l == ltmmCapture_TargetFormat_MPEG1Audio) ? MF_CHECKED : MF_UNCHECKED); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_AVI, (!fActive && l2 != ltmmCapture_Target_Device) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_WAVE, (!fActive && l2 != ltmmCapture_Target_Device) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_TARGETFORMAT_MPEG1AUDIO, (!fActive && l2 != ltmmCapture_Target_Device) ? MF_ENABLED : MF_GRAYED); 

         // check processor preview
         IltmmCapture_get_PreviewTap(g_pCapture, &l); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_PREVIEWPROCESSORS, (l == ltmmCapture_PreviewTap_Processors) ? MF_CHECKED : MF_UNCHECKED); 

         // check properties preview
         IltmmCapture_get_ShowDialogPreview(g_pCapture, &f); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_PROPERTIESPREVIEW, (f) ? MF_CHECKED : MF_UNCHECKED); 

         // enable vcr controls
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_get_DeviceType(pVCR, &l); 

         // if no tape is loaded, then disallow vcr control
         IltmmVCRControl_get_MediaType(pVCR, &l2); 
         if(l2 == ltmmVCRControl_MediaType_NotPresent) 
            l = ltmmVCRControl_DeviceType_NotPresent; 

         // get the current vcr mode
         IltmmVCRControl_get_Mode(pVCR, &l2); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_PLAY, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Play) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_STOP, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Stop) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_PAUSE, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Pause) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_REWIND, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_Rewind) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_FASTFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_FastForward) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_STEPFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_StepForward) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_STEPBACKWARD, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_StepBackward) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_FASTESTFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_FastestForward) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_FASTESTREVERSE, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_FastestReverse) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_SLOWESTFORWARD, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_SlowestForward) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_SLOWESTREVERSE, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != ltmmVCRControl_Mode_SlowestReverse) ? MF_ENABLED : MF_GRAYED); 

         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_RECORD, (l != ltmmVCRControl_DeviceType_NotPresent && l2 != ltmmVCRControl_Mode_Record) ? MF_ENABLED : MF_GRAYED); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_PAUSERECORDING, (l != ltmmVCRControl_DeviceType_NotPresent && l2 != ltmmVCRControl_Mode_PauseRecording) ? MF_ENABLED : MF_GRAYED); 

         IltmmVCRControl_ReadTimecode(pVCR, &l2); 
         EnableMenuItem((HMENU) wParam, ID_CONTROL_VCR_SEEKSTART, (l != ltmmVCRControl_DeviceType_NotPresent  && l != ltmmVCRControl_DeviceType_Camera && l2 != 0) ? MF_ENABLED : MF_GRAYED); 

         IUnknown_Release(pVCR); 

         // check audio buffer size
         IltmmCapture_get_AudioBufferSize(g_pCapture, &d); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_AUDIOBUFFERING_05SECONDS, (fabs(d - 0.5) < 0.01) ? MF_CHECKED : MF_UNCHECKED); 
         CheckMenuItem((HMENU) wParam, ID_CONTROL_AUDIOBUFFERING_005SECONDS, (fabs(d - 0.05) < 0.01) ? MF_CHECKED : MF_UNCHECKED); 

      }
      break; 
   case WM_COMMAND: 
      switch(LOWORD(wParam)) 
      {
      case ID_CONTROL_FITTOWINDOW: 
         // fit the video to the window
         IltmmCapture_put_VideoWindowSizeMode(g_pCapture, ltmmFit); 
         return 0; 
         break; 
      case ID_CONTROL_STRETCHTOWINDOW: 
         // stretch the video to the window
         IltmmCapture_put_VideoWindowSizeMode(g_pCapture, ltmmStretch); 
         return 0; 
         break; 
      case ID_CONTROL_FULLSCREEN: 
         // toggle fullscreen mode
         IltmmCapture_ToggleFullScreenMode(g_pCapture); 
         return 0; 
         break; 
      case ID_CONTROL_PREVIEW: 
         // toggle preview
         IltmmCapture_TogglePreview(g_pCapture); 
         return 0; 
         break; 
      case ID_CONTROL_PREVIEWVIDEOANDAUDIO: 
         // toggle audio preview
         IltmmCapture_get_PreviewSource(g_pCapture, &l); 
         if(l == ltmmCapture_Preview_VideoAndAudio) 
            IltmmCapture_put_PreviewSource(g_pCapture, ltmmCapture_Preview_Video); 
         else
            IltmmCapture_put_PreviewSource(g_pCapture, ltmmCapture_Preview_VideoAndAudio); 

         return 0; 
         break; 
      case ID_CONTROL_CLOSECAPTIONING: 
         // toggle close captioning
         IltmmCapture_ToggleCloseCaptioning(g_pCapture); 
         return 0; 
         break; 
      case ID_CONTROL_STOPCAPTURE: 
         // stop capturing
         IltmmCapture_StopCapture(g_pCapture); 
         return 0; 
         break; 
      case ID_CONTROL_CAPTUREPROPERTIES: 
         // set capture properties
         IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_Capture, (long) hwnd); 
         return 0; 
         break; 
      case ID_CONTROL_STARTCAPTURE: 

         // ready capture to eliminate start delays
         hr = IltmmCapture_ReadyCapture(g_pCapture, ltmmCapture_Mode_VideoOrAudio); 

         if(SUCCEEDED(hr)) 
         {
            // start recording, if vcr output
            IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); 
            hr = IltmmVCRControl_Record(pVCR); 
            IUnknown_Release(pVCR); 

            // uncomment the following line to view the the graph in DirectShow GraphEdit
            // IltmmCapture_EditGraph(g_pCapture); 
            if(MessageBox(hwnd, _T("Ready to capture. Click 'ok' to start."), _T("Capture"), MB_OKCANCEL) == IDOK) 
            {
               // start capturing
               IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_VideoOrAudio); 
            }
            else
            {
               // cancel capture
               IltmmCapture_StopCapture(g_pCapture); 

               // stop recording, if vcr output
               IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); 
               IltmmVCRControl_Stop (pVCR); 
               IUnknown_Release(pVCR); 

            }
         }
         return 0; 
         break; 
      case ID_CONTROL_RUN: 
         // run the capture graph
         IltmmCapture_RunCapture(g_pCapture); 
         return 0; 
         break; 
      case ID_CONTROL_PAUSE: 
         // pause the capture graph
         IltmmCapture_PauseCapture(g_pCapture); 
         return 0; 
         break; 

      case ID_CONTROL_CAPTUREAUTOFRAMES: 
         hr = IltmmCapture_ReadyCapture(g_pCapture, ltmmCapture_Mode_AutoFrames); 
         if(SUCCEEDED(hr)) 
         {
            // start recording, if vcr output
            IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); 
            hr = IltmmVCRControl_Record(pVCR); 
            IUnknown_Release(pVCR); 
            if(SUCCEEDED(hr)) 
               Sleep(2000); 

            // start capturing automatic frame sequence
            IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_AutoFrames); 
         }
         return 0; 
         break; 
      case ID_CONTROL_CAPTUREMANUALFRAMES: 
         hr = IltmmCapture_ReadyCapture(g_pCapture, ltmmCapture_Mode_ManualFrames); 
         if(SUCCEEDED(hr)) 
         {
            // start recording, if vcr output
            IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); 
            hr = IltmmVCRControl_Record(pVCR); 
            IUnknown_Release(pVCR); 
            if(SUCCEEDED(hr)) 
               Sleep(2000); 

            // start capturing automatic frame sequence
            hr = IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_ManualFrames); 

            if(SUCCEEDED(hr)) 
            {

               while(MessageBox(hwnd, _T("Press 'ok' to capture frame."), _T("Capture Manual Frames"), MB_OKCANCEL) == IDOK) 
                  IltmmCapture_CaptureFrame(g_pCapture); 

               IltmmCapture_StopCapture(g_pCapture); 
            }

            // stop recording, if vcr output
            IltmmCapture_get_TargetVCRControl(g_pCapture, &pVCR); 
            IltmmVCRControl_Stop(pVCR); 
            IUnknown_Release(pVCR); 
         }
         return 0; 
         break; 

      case ID_CONTROL_CAPTUREDIB: 
         // capture device independent bitmap
         hr = IltmmCapture_CaptureDIB(g_pCapture, (long*) &hDIB); 
         if(SUCCEEDED(hr)) 
         {
            // copy to the clipboard
            OpenClipboard(hwnd); 
            EmptyClipboard();
            SetClipboardData(CF_DIB, hDIB); 
            CloseClipboard();
         }
         return 0; 
         break; 
      case ID_CONTROL_CAPTUREPICTURE: 
         // capture ole picture object
         hr = IltmmCapture_CapturePicture(g_pCapture, &pPictureDisp); 
         if(SUCCEEDED(hr)) 
         {
            // save the picture
            bstr = SysAllocString(MAKE_MEDIA_PATH("still.bmp"));
            OleSavePictureFile((IDispatch*) pPictureDisp, bstr); 
            SysFreeString(bstr); 
            IUnknown_Release(pPictureDisp); 
         }
         return 0; 
         break; 
      case ID_CONTROL_GETSTILLDIB: 
         // alternate method of capturing a device independent bitmap
         hr = IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_Still); 
         if(SUCCEEDED(hr)) 
         {
            hr = IltmmCapture_GetStillDIB(g_pCapture, INFINITE, (long*) &hDIB); 
            IltmmCapture_StopCapture(g_pCapture); 
            if(SUCCEEDED(hr)) 
            {
               // copy to the clipboard
               OpenClipboard(hwnd); 
               EmptyClipboard();
               SetClipboardData(CF_DIB, hDIB); 
               CloseClipboard();
            }
         }
         return 0; 
         break; 
      case ID_CONTROL_GETSTILLPICTURE: 
         // alternate method of capturing an ole picture object
         hr = IltmmCapture_StartCapture(g_pCapture, ltmmCapture_Mode_Still); 
         if(SUCCEEDED(hr)) 
         {
            hr = IltmmCapture_GetStillPicture(g_pCapture, INFINITE, &pPictureDisp); 
            IltmmCapture_StopCapture(g_pCapture); 
            if(SUCCEEDED(hr)) 
            {
               // save the picture
               bstr = SysAllocString(MAKE_MEDIA_PATH("still.bmp"));
               OleSavePictureFile((IDispatch*) pPictureDisp, bstr); 
               SysFreeString(bstr); 
               IUnknown_Release(pPictureDisp); 
            }
         }
         return 0; 
         break; 
      case ID_CONTROL_COPYTARGET: 
         // copy target file
         bstr = SysAllocString(MAKE_MEDIA_PATH("targetcopy.avi"));
         IltmmCapture_CopyTarget(g_pCapture, bstr, VARIANT_FALSE); 
         SysFreeString(bstr); 
         return 0; 
         break; 
      case ID_CONTROL_MASTERSTREAM_NONE: 
         // no master stream
         IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_None); 
         return 0; 
         break; 
      case ID_CONTROL_MASTERSTREAM_AUDIO: 
         // set audio master
         IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_Audio); 
         return 0; 
         break; 
      case ID_CONTROL_MASTERSTREAM_VIDEO: 
         // set video master
         IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_Video); 
         return 0; 
         break; 
      case ID_CONTROL_FRAMERATE_DEFAULT: 
         // set rate to default
         IltmmCapture_put_UseFrameRate(g_pCapture, VARIANT_FALSE); 
         return 0; 
         break; 
      case ID_CONTROL_FRAMERATE_15FPS: 
         // set rate to 15 fps
         IltmmCapture_put_FrameRate(g_pCapture, 15.0); 
         IltmmCapture_put_UseFrameRate(g_pCapture, VARIANT_TRUE); 
         return 0; 
         break; 
      case ID_CONTROL_FRAMERATE_30FPS: 
         // set rate to 30 fps
         IltmmCapture_put_FrameRate(g_pCapture, 30.0); 
         IltmmCapture_put_UseFrameRate(g_pCapture, VARIANT_TRUE); 
         return 0; 
         break; 
      case ID_CONTROL_TIMELIMIT_NONE: 
         // no time limit
         IltmmCapture_put_UseTimeLimit(g_pCapture, VARIANT_FALSE); 
         return 0; 
         break; 
      case ID_CONTROL_TIMELIMIT_15SEC: 
         // 15 sec time limit
         IltmmCapture_put_TimeLimit(g_pCapture, 15.0); 
         IltmmCapture_put_UseTimeLimit(g_pCapture, VARIANT_TRUE); 
         return 0; 
         break; 
      case ID_CONTROL_TIMELIMIT_30SEC: 
         // 30 sec time limit
         IltmmCapture_put_TimeLimit(g_pCapture, 30.0); 
         IltmmCapture_put_UseTimeLimit(g_pCapture, VARIANT_TRUE); 
         return 0; 
         break; 
      case ID_CONTROL_FRAMEDELAY_1SEC: 
         // 1 sec frame delay
         IltmmCapture_put_FrameDelay(g_pCapture, 1.0); 
         return 0; 
         break; 
      case ID_CONTROL_FRAMEDELAY_5SEC: 
         // 5 sec frame delay
         IltmmCapture_put_FrameDelay(g_pCapture, 5.0); 
         return 0; 
         break; 
      case ID_CONTROL_TARGET_FILE: 
         // assign a target file
         FreeTarget();

         // select the LEAD video compressor
         IltmmCapture_get_VideoCompressors(g_pCapture, &pCompressors); 
         bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MCMP/MJPEG Codec (2.0)");
         IltmmCompressors_Find(pCompressors, bstr, &index); 
         SysFreeString(bstr); 
         if(index >= 0) 
            IltmmCompressors_put_Selection(pCompressors, index); 
         IUnknown_Release(pCompressors); 


         // select the MP3 audio video compressor
         IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); 
         bstr = SysAllocString(L"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\85MPEG Layer-3");
         IltmmCompressors_Find(pCompressors, bstr, &index); 
         SysFreeString(bstr); 
         if(index >= 0) 
            IltmmCompressors_put_Selection(pCompressors, index); 
         IUnknown_Release(pCompressors); 

         IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); 


         bstr = SysAllocString(MAKE_MEDIA_PATH("target.avi"));
         IltmmCapture_put_TargetFile(g_pCapture, bstr); 
         SysFreeString(bstr); 
         return 0; 
         break; 
      case ID_CONTROL_TARGET_ARRAY: 
         // assign a target array
         FreeTarget();

         // select the LEAD video compressor
         IltmmCapture_get_VideoCompressors(g_pCapture, &pCompressors); 
         bstr = SysAllocString(L"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\\LEAD MCMP/MJPEG Codec (2.0)");         IltmmCompressors_Find(pCompressors, bstr, &index); 
         SysFreeString(bstr); 
         if(index >= 0) 
            IltmmCompressors_put_Selection(pCompressors, index); 
         IUnknown_Release(pCompressors); 


         // select the MP3 audio video compressor
         IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); 
         bstr = SysAllocString(L"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\\85MPEG Layer-3");
         IltmmCompressors_Find(pCompressors, bstr, &index); 
         SysFreeString(bstr); 
         if(index >= 0) 
            IltmmCompressors_put_Selection(pCompressors, index); 
         IUnknown_Release(pCompressors); 


         IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); 

         VariantInit(&var); 
         V_VT(&var) = (VT_ARRAY | VT_UI1); 
         V_ARRAY(&var) = SafeArrayCreateVector(VT_UI1, 0, 0); 
         IltmmCapture_put_TargetArray(g_pCapture, var); 
         return 0; 
         break; 
      case ID_CONTROL_TARGET_DEVICE: 
         // assign a target device
         FreeTarget();

         // deselect video compressor
         IltmmCapture_get_VideoCompressors(g_pCapture, &pCompressors); 
         IltmmCompressors_put_Selection(pCompressors, -1); 
         IUnknown_Release(pCompressors); 


         // deselect audio compressor
         IltmmCapture_get_AudioCompressors(g_pCapture, &pCompressors); 
         IltmmCompressors_put_Selection(pCompressors, -1); 
         IUnknown_Release(pCompressors); 

         IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_dvsd); 

         // select the first output device
         IltmmCapture_get_TargetDevices(g_pCapture, &pTargetDevices); 
         IltmmTargetDevices_put_Selection(pTargetDevices, 0); 
         IUnknown_Release(pTargetDevices); 

         return 0; 
         break; 
      case ID_CONTROL_TARGETFORMAT_AVI: 
         // is target a file? 
         IltmmCapture_get_TargetType(g_pCapture, &l); 
         if(l == ltmmCapture_Target_File) 
         {
            // rename it
            bstr = SysAllocString(MAKE_MEDIA_PATH("target.avi"));
            IltmmCapture_put_TargetFile(g_pCapture, bstr); 
            SysFreeString(bstr); 
         }
         IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_Avi); 
         return 0; 
         break; 
      case ID_CONTROL_TARGETFORMAT_WAVE: 
         // is target a file? 
         IltmmCapture_get_TargetType(g_pCapture, &l); 
         if(l == ltmmCapture_Target_File) 
         {
            // rename it
            bstr = SysAllocString(MAKE_MEDIA_PATH("target.wav"));
            IltmmCapture_put_TargetFile(g_pCapture, bstr); 
            SysFreeString(bstr); 
         }
         IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_WAVE); 
         return 0; 
         break; 
      case ID_CONTROL_TARGETFORMAT_MPEG1AUDIO: 
         // is target a file? 
         IltmmCapture_get_TargetType(g_pCapture, &l); 
         if(l == ltmmCapture_Target_File) 
         {
            // rename it
            bstr = SysAllocString(MAKE_MEDIA_PATH("target.mp3"));
            IltmmCapture_put_TargetFile(g_pCapture, bstr); 
            SysFreeString(bstr); 
         }
         // we have already selected the MP3 compressor
         IltmmCapture_put_TargetFormat(g_pCapture, ltmmCapture_TargetFormat_MPEG1Audio); 
         return 0; 
         break; 
      case ID_CONTROL_AUDIOPROCESSORS: 
         // edit audio processors
         IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_AudioProcessors, (long) hwnd); 
         return 0; 
         break; 
      case ID_CONTROL_VIDEOPROCESSORS: 
         // edit video processors
         IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_VideoProcessors, (long) hwnd); 
         return 0; 
         break; 
      case ID_CONTROL_PREVIEWPROCESSORS: 
         // toggle processor preview
         IltmmCapture_get_PreviewTap(g_pCapture, &l); 
         IltmmCapture_put_PreviewTap(g_pCapture, (l == ltmmCapture_PreviewTap_Processors) ? ltmmCapture_PreviewTap_Source : ltmmCapture_PreviewTap_Processors); 
         return 0; 
         break; 
      case ID_CONTROL_PROPERTIESPREVIEW: 
         // toggle preview while editing properties
         IltmmCapture_get_ShowDialogPreview(g_pCapture, &f); 
         IltmmCapture_put_ShowDialogPreview(g_pCapture, f ? VARIANT_FALSE : VARIANT_TRUE); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_PLAY: 
         // vcr play
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_Play(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_STOP: 
         // vcr stop
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_Stop (pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_PAUSE: 
         // vcr pause
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_Pause(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_FASTFORWARD: 
         // vcr fast forward
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_FastForward(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_REWIND: 
         // vcr rewind
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_Rewind(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_RECORD: 
         // vcr record
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_Record(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_PAUSERECORDING: 
         // vcr pause recording
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_PauseRecording(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_STEPFORWARD: 
         // vcr step forward
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_StepForward(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_STEPBACKWARD: 
         // vcr step backward
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_StepBackward(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_FASTESTFORWARD: 
         // vcr fastest forward
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_FastestForward(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_FASTESTREVERSE: 
         // vcr fastest reverse
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_FastestReverse(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_SLOWESTFORWARD: 
         // vcr slowest forward
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_SlowestForward(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_SLOWESTREVERSE: 
         // vcr slowest reverse
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_SlowestReverse(pVCR); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_VCR_SEEKSTART: 
         // vcr seek start
         IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR); 
         IltmmVCRControl_SeekTimecode(pVCR, 0); 
         IUnknown_Release(pVCR); 
         return 0; 
         break; 
      case ID_CONTROL_AUDIOBUFFERING_05SECONDS: 
         // set 0.5 second audio buffer
         IltmmCapture_put_AudioBufferSize(g_pCapture, 0.5); 
         return 0; 
         break; 
      case ID_CONTROL_AUDIOBUFFERING_005SECONDS: 
         // set 0.05 second audio buffer
         IltmmCapture_put_AudioBufferSize(g_pCapture, 0.05); 
         return 0; 
         break; 
      }
      break; 
   case WM_LBUTTONDOWN: 
      IltmmCapture_get_State(g_pCapture, &l); 
      if(l != ltmmCapture_State_Pending || l != ltmmCapture_State_Running) 
      {
         IltmmCapture_get_VideoWindowLeft(g_pCapture, &x); 
         IltmmCapture_get_VideoWindowTop(g_pCapture, &y); 
         IltmmCapture_get_VideoWindowWidth(g_pCapture, &cx); 
         IltmmCapture_get_VideoWindowHeight(g_pCapture, &cy); 
         SetRect(&rc, x, y, x + cx, y + cy); 
         pt.x = (short) LOWORD(lParam); 
         pt.y = (short) HIWORD(lParam); 
         if(PtInRect(&rc, pt)) 
         {
            // set capture properties
            IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_Capture, (long) hwnd); 
         }
      }
      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; 


   UNUSED_PARAMETER (hPrevInstance);
   UNUSED_PARAMETER (lpCmdLine);   

   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   = CaptureWndProc; 
   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_CAPTURE; 
   wcex.hIconSm       = NULL; 

   if(!RegisterClassEx(&wcex)) 
      goto error; 

   // create the capture object
   hr = CoCreateInstance(&CLSID_ltmmCapture, NULL, CLSCTX_INPROC_SERVER, &IID_IltmmCapture, (void**) &g_pCapture); 
   if(FAILED(hr)) 
      goto error; 

   // create the video frame window
   if(!CreateWindow(SZ_WNDCLASS_CAPTURE, _T("Capture"), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, g_hInstance, NULL)) 
      goto error; 

   ShowWindow(g_hwndCapture, nCmdShow); 

   UpdateWindow(g_hwndCapture); 

   // process until done
   while (GetMessage(&msg, NULL, 0, 0)) 
   {
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
   }

error: 
   if(g_pCapture) 
      IUnknown_Release(g_pCapture); 

   CoUninitialize();

   return 0;   
}