The following code demonstrates an advanced capture application. It utilizes most of the functions available in the ltmmCapture object.
// 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);
// preview is visible
IltmmCapture_put_PreviewVisible(g_pCapture, VARIANT_TRUE);
// 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 the control perform normal capture?
IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_VideoOrAudio, &f);
EnableMenuItem((HMENU) wParam, ID_CONTROL_STARTCAPTURE, f ? MF_ENABLED : MF_GRAYED);
// can the control perform auto frame capture?
IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_AutoFrames, &f);
EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREAUTOFRAMES, f ? MF_ENABLED : MF_GRAYED);
// can the control perform manual frame capture?
IltmmCapture_IsModeAvailable(g_pCapture, ltmmCapture_Mode_ManualFrames, &f);
EnableMenuItem((HMENU) wParam, ID_CONTROL_CAPTUREMANUALFRAMES, f ? MF_ENABLED : MF_GRAYED);
// can the control 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 which video size mode is being used
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 the preview status
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 the audio preview status
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 the 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 the 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 the 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 the 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 the 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 the processor preview
IltmmCapture_get_PreviewTap(g_pCapture, &l);
CheckMenuItem((HMENU) wParam, ID_CONTROL_PREVIEWPROCESSORS, (l == ltmmCapture_PreviewTap_Processors) ? MF_CHECKED : MF_UNCHECKED);
// check the properties preview
IltmmCapture_get_ShowDialogPreview(g_pCapture, &f);
CheckMenuItem((HMENU) wParam, ID_CONTROL_PROPERTIESPREVIEW, (f) ? MF_CHECKED : MF_UNCHECKED);
// enable the vcr controls
IltmmCapture_get_CaptureVCRControl(g_pCapture, &pVCR);
IltmmVCRControl_get_DeviceType(pVCR, &l);
// if no tape is loaded, then disable 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 the 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 the 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 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 the 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 the 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 an 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 for 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 the 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 the audio master
IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_Audio);
return 0;
break;
case ID_CONTROL_MASTERSTREAM_VIDEO:
// set the video master
IltmmCapture_put_MasterStream(g_pCapture, ltmmCapture_MasterStream_Video);
return 0;
break;
case ID_CONTROL_FRAMERATE_DEFAULT:
// set the rate to default
IltmmCapture_put_UseFrameRate(g_pCapture, VARIANT_FALSE);
return 0;
break;
case ID_CONTROL_FRAMERATE_15FPS:
// set the 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 the video compressor
IltmmCapture_get_VideoCompressors(g_pCapture, &pCompressors);
IltmmCompressors_put_Selection(pCompressors, -1);
IUnknown_Release(pCompressors);
// deselect the 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 the 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 the 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 the 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 the audio processors
IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_AudioProcessors, (long) hwnd);
return 0;
break;
case ID_CONTROL_VIDEOPROCESSORS:
// edit the video processors
IltmmCapture_ShowDialog(g_pCapture, ltmmCapture_Dlg_VideoProcessors, (long) hwnd);
return 0;
break;
case ID_CONTROL_PREVIEWPROCESSORS:
// toggle the 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 the 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 the 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 the 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;
}