Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1372 lines
33 KiB

/*****************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 2000
*
* TITLE: VideoProc.cpp
*
* VERSION: 1.0
*
* DATE: 2000/11/14
*
* DESCRIPTION: Manages WiaVideo object.
*
*****************************************************************************/
#include <stdafx.h>
#include <mmsystem.h>
#include <streams.h>
#include <mmreg.h>
#include "wiavideotest.h"
///////////////////////////////
// LOCAL_GVAR
//
static struct
{
IWiaVideo *pWiaVideo;
BOOL bPreviewVisible;
INT iNumThreads;
UINT uiNumImagesPerThread;
UINT uiTakePictureInterval;
BOOL bExitThreads;
BOOL bVideoStretched;
} LOCAL_GVAR =
{
NULL,
TRUE,
0,
0,
0,
FALSE,
FALSE
};
///////////////////////////////
// ThreadArgs_t
//
typedef struct ThreadArgs_t
{
UINT uiNumPicturesToTake;
UINT uiThreadSleepTime; // if 0, calc'd as a random number.
} ThreadArgs_t;
/****************************Local Function Prototypes********************/
HRESULT CreateWiaVideoObject();
HRESULT CreateVideoEnumPos();
HRESULT CreateVideoFriendlyName();
HRESULT CreateVideoWia();
HRESULT DestroyVideo();
HRESULT Play();
HRESULT Pause();
HRESULT TakePicture(BOOL bTakePictureThroughDriver);
HRESULT ShowVideo();
HRESULT ResizeVideo(BOOL bStretchToFitWindow);
HRESULT ShowCurrentState();
HRESULT TakePictureMultiple();
HRESULT TakePictureStress();
DWORD WINAPI TakePictureThreadProc(void *pArgs);
LRESULT CALLBACK MultipleDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam);
LRESULT CALLBACK StressDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam);
BOOL GetDeviceProperty(IPropertyBag *pPropertyBag,
LPCWSTR pwszProperty,
TCHAR *pszProperty,
DWORD cchProperty);
///////////////////////////////
// VideoProc_Init
//
HRESULT VideoProc_Init()
{
HRESULT hr = S_OK;
hr = CreateWiaVideoObject();
return hr;
}
///////////////////////////////
// VideoProc_Term
//
HRESULT VideoProc_Term()
{
HRESULT hr = S_OK;
LOCAL_GVAR.bExitThreads = TRUE;
//
// Crude, but for a test app, it is easier than creating an
// array of thread handles and waiting for each one to finish.
//
INT iLoops = 0;
while ((LOCAL_GVAR.iNumThreads > 0) && (iLoops < 50))
{
++iLoops;
Sleep(100);
}
DestroyVideo();
if (LOCAL_GVAR.pWiaVideo)
{
LOCAL_GVAR.pWiaVideo->Release();
LOCAL_GVAR.pWiaVideo = NULL;
}
return hr;
}
///////////////////////////////
// VideoProc_DShowListInit
//
HRESULT VideoProc_DShowListInit()
{
HRESULT hr = S_OK;
LONG lPosNum = 0;
ICreateDevEnum *pCreateDevEnum = NULL;
IEnumMoniker *pEnumMoniker = NULL;
//
// Empty the list
//
SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_RESETCONTENT,
0,
0);
if (hr == S_OK)
{
//
// Create the device enumerator
//
hr = CoCreateInstance(CLSID_SystemDeviceEnum,
NULL,
CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,
(void**)&pCreateDevEnum);
}
if (hr == S_OK)
{
hr = pCreateDevEnum->CreateClassEnumerator(
CLSID_VideoInputDeviceCategory,
&pEnumMoniker,
0);
}
//
// Loop through all the devices
//
while (hr == S_OK)
{
TCHAR szFriendlyName[255 + 1] = {0};
IMoniker *pMoniker = NULL;
IPropertyBag *pPropertyBag = NULL;
hr = pEnumMoniker->Next(1, &pMoniker, NULL);
if (hr == S_OK)
{
//
// Get property storage for this DS device so we can get it's
// device id...
//
hr = pMoniker->BindToStorage(0,
0,
IID_IPropertyBag,
(void **)&pPropertyBag);
}
if (hr == S_OK)
{
hr = GetDeviceProperty(pPropertyBag,
L"FriendlyName",
szFriendlyName,
sizeof(szFriendlyName) / sizeof(TCHAR));
}
if (hr == S_OK)
{
SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_ADDSTRING,
0,
(LPARAM) szFriendlyName);
}
if (pMoniker)
{
pMoniker->Release();
pMoniker = NULL;
}
if (pPropertyBag)
{
pPropertyBag->Release();
pPropertyBag = NULL;
}
}
SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_SETCURSEL,
0,
0);
if (pEnumMoniker)
{
pEnumMoniker->Release();
pEnumMoniker = NULL;
}
if (pCreateDevEnum)
{
pCreateDevEnum->Release();
pCreateDevEnum = NULL;
}
return hr;
}
///////////////////////////////
// VideoProc_DShowListTerm
//
HRESULT VideoProc_DShowListTerm()
{
HRESULT hr = S_OK;
//
// Empty the list
//
SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_RESETCONTENT,
0,
0);
return hr;
}
///////////////////////////////
// VideoProc_TakePicture
//
HRESULT VideoProc_TakePicture()
{
HRESULT hr = S_OK;
hr = TakePicture(FALSE);
return hr;
}
///////////////////////////////
// VideoProc_ProcessMsg
//
UINT_PTR VideoProc_ProcessMsg(UINT uiControlID)
{
HRESULT hr = S_OK;
UINT_PTR uiReturn = 0;
switch (uiControlID)
{
case IDC_BUTTON_CREATE_VIDEO_WIA:
hr = CreateVideoWia();
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), FALSE);
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), FALSE);
break;
case IDC_BUTTON_CREATE_VIDEO_ENUM_POS:
hr = CreateVideoEnumPos();
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), FALSE);
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), FALSE);
break;
case IDC_BUTTON_CREATE_VIDEO_FRIENDLY_NAME:
hr = CreateVideoFriendlyName();
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), FALSE);
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), FALSE);
break;
case IDC_BUTTON_TAKE_PICTURE_STRESS:
TakePictureStress();
break;
case IDC_BUTTON_TAKE_PICTURE_MULTIPLE:
TakePictureMultiple();
break;
case IDC_BUTTON_DESTROY_VIDEO:
SetCursor( LoadCursor(NULL, IDC_WAIT));
DestroyVideo();
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), TRUE);
EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), TRUE);
SetCursor( LoadCursor(NULL, IDC_ARROW));
break;
case IDC_BUTTON_PLAY:
Play();
break;
case IDC_BUTTON_PAUSE:
Pause();
break;
case IDC_BUTTON_TAKE_PICTURE:
TakePicture(FALSE);
break;
case IDC_BUTTON_TAKE_PICTURE_DRIVER:
TakePicture(TRUE);
break;
case IDC_BUTTON_SHOW_VIDEO_TOGGLE:
ShowVideo();
break;
case IDC_BUTTON_RESIZE_TOGGLE:
LOCAL_GVAR.bVideoStretched = (LOCAL_GVAR.bVideoStretched ? FALSE : TRUE);
ResizeVideo(LOCAL_GVAR.bVideoStretched);
break;
default:
break;
}
ShowCurrentState();
return uiReturn;
}
///////////////////////////////
// CreateVideoWia
//
HRESULT CreateVideoWia()
{
HRESULT hr = S_OK;
TCHAR szDeviceID[MAX_PATH] = {0};
TCHAR szImagesDirectory[MAX_PATH] = {0};
BSTR bstrImagesDir = NULL;
BSTR bstrDeviceID = NULL;
WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
DWORD dwStartTime = 0;
DWORD dwEndTime = 0;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
if (VideoState != WIAVIDEO_NO_VIDEO)
{
AppUtil_MsgBox(IDS_ERROR,
IDS_VIDEO_STILL_ACTIVE,
MB_OK | MB_ICONSTOP);
return hr;
}
SetCursor( LoadCursor(NULL, IDC_WAIT));
//
// We need to do this first, otherwise the driver is not loaded yet,
// and therefore the images directory property will have not been set
//
if (hr == S_OK)
{
hr = WiaProc_CreateSelectedDevice(szDeviceID,
sizeof(szDeviceID) / sizeof(TCHAR));
}
dwStartTime = timeGetTime();
//
// Get the images directory stored in the driver. We don't have to do this
// we can come up with our own, but the driver will generate a default temp
// location, which is good enough for our purposes.
//
if (hr == S_OK)
{
hr = WiaProc_GetImageDirectory(szImagesDirectory,
sizeof(szImagesDirectory) / sizeof(TCHAR));
}
if (hr == S_OK)
{
WCHAR wszDeviceID[MAX_PATH] = {0};
AppUtil_ConvertToWideString(szDeviceID, wszDeviceID,
sizeof(wszDeviceID) / sizeof(WCHAR));
bstrDeviceID = ::SysAllocString(wszDeviceID);
}
//
// Set the images directory on the WiaVideo object
//
if (hr == S_OK)
{
WCHAR wszImagesDir[MAX_PATH] = {0};
AppUtil_ConvertToWideString(szImagesDirectory, wszImagesDir,
sizeof(wszImagesDir) / sizeof(WCHAR));
bstrImagesDir = ::SysAllocString(wszImagesDir);
hr = LOCAL_GVAR.pWiaVideo->put_ImagesDirectory(bstrImagesDir);
}
//
// Create Video.
//
if (hr == S_OK)
{
hr = LOCAL_GVAR.pWiaVideo->CreateVideoByWiaDevID(bstrDeviceID,
GetDlgItem(APP_GVAR.hwndMainDlg,
IDC_VIDEO_PREVIEW_WINDOW),
FALSE,
TRUE);
}
dwEndTime = timeGetTime();
SetDlgItemInt(APP_GVAR.hwndMainDlg,
IDC_EDIT_GRAPH_BUILD_TIME,
(UINT) abs(dwEndTime - dwStartTime),
FALSE);
if (hr == S_OK)
{
SetDlgItemText(APP_GVAR.hwndMainDlg,
IDC_EDIT_IMAGES_DIR,
szImagesDirectory);
}
//
// Populate our list of items for this device
//
if (hr == S_OK)
{
hr = WiaProc_PopulateItemList();
}
if (bstrImagesDir)
{
::SysFreeString(bstrImagesDir);
bstrImagesDir = NULL;
}
if (bstrDeviceID)
{
::SysFreeString(bstrDeviceID);
bstrDeviceID = NULL;
}
SetCursor( LoadCursor(NULL, IDC_ARROW));
if (hr != S_OK)
{
AppUtil_MsgBox(IDS_ERROR,
IDS_FAILED_TO_CREATE_VIDEO,
MB_OK | MB_ICONSTOP,
hr);
}
return hr;
}
///////////////////////////////
// CreateVideoEnumPos
//
HRESULT CreateVideoEnumPos()
{
HRESULT hr = S_OK;
TCHAR szImagesDirectory[MAX_PATH] = {0};
TCHAR szFriendlyName[255 + 1] = {0};
BSTR bstrImagesDir = NULL;
WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
DWORD dwStartTime = 0;
DWORD dwEndTime = 0;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
if (VideoState != WIAVIDEO_NO_VIDEO)
{
AppUtil_MsgBox(IDS_ERROR,
IDS_VIDEO_STILL_ACTIVE,
MB_OK | MB_ICONSTOP);
return hr;
}
SetCursor( LoadCursor(NULL, IDC_WAIT));
LRESULT lResult = 0;
lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETCURSEL,
0,
0);
WPARAM Index = (WPARAM) lResult;
lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETTEXT,
Index,
(LPARAM) szFriendlyName);
dwStartTime = timeGetTime();
//
// Get the images directory stored in the driver. We don't have to do this
// we can come up with our own, but the driver will generate a default temp
// location, which is good enough for our purposes.
//
TCHAR szTempPath[MAX_PATH] = {0};
if (hr == S_OK)
{
GetTempPath(MAX_PATH, szTempPath);
_sntprintf(szImagesDirectory, sizeof(szImagesDirectory) / sizeof(TCHAR),
TEXT("%s\\WiaVideoTest\\%s"), szTempPath, szFriendlyName);
}
//
// Set the images directory on the WiaVideo object
//
if (hr == S_OK)
{
WCHAR wszImagesDir[MAX_PATH] = {0};
AppUtil_ConvertToWideString(szImagesDirectory, wszImagesDir,
sizeof(wszImagesDir) / sizeof(WCHAR));
bstrImagesDir = ::SysAllocString(wszImagesDir);
hr = LOCAL_GVAR.pWiaVideo->put_ImagesDirectory(bstrImagesDir);
}
//
// Create Video.
//
if (hr == S_OK)
{
UINT uiDeviceNumber = (UINT) Index;
hr = LOCAL_GVAR.pWiaVideo->CreateVideoByDevNum(uiDeviceNumber,
GetDlgItem(APP_GVAR.hwndMainDlg,
IDC_VIDEO_PREVIEW_WINDOW),
FALSE,
TRUE);
}
dwEndTime = timeGetTime();
SetDlgItemInt(APP_GVAR.hwndMainDlg,
IDC_EDIT_GRAPH_BUILD_TIME,
(UINT) abs(dwEndTime - dwStartTime),
FALSE);
if (hr == S_OK)
{
SetDlgItemText(APP_GVAR.hwndMainDlg,
IDC_EDIT_IMAGES_DIR,
szImagesDirectory);
}
//
// Populate our list of items for this device
//
if (hr == S_OK)
{
hr = ImageLst_PopulateDShowItemList(szImagesDirectory);
}
if (bstrImagesDir)
{
::SysFreeString(bstrImagesDir);
bstrImagesDir = NULL;
}
SetCursor( LoadCursor(NULL, IDC_ARROW));
if (hr != S_OK)
{
AppUtil_MsgBox(IDS_ERROR,
IDS_FAILED_TO_CREATE_VIDEO,
MB_OK | MB_ICONSTOP,
hr);
}
return hr;
}
///////////////////////////////
// CreateVideoFriendlyName
//
HRESULT CreateVideoFriendlyName()
{
HRESULT hr = S_OK;
TCHAR szImagesDirectory[MAX_PATH] = {0};
TCHAR szFriendlyName[255 + 1] = {0};
BSTR bstrFriendlyName = NULL;
BSTR bstrImagesDir = NULL;
WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
DWORD dwStartTime = 0;
DWORD dwEndTime = 0;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
if (VideoState != WIAVIDEO_NO_VIDEO)
{
AppUtil_MsgBox(IDS_ERROR,
IDS_VIDEO_STILL_ACTIVE,
MB_OK | MB_ICONSTOP);
return hr;
}
SetCursor( LoadCursor(NULL, IDC_WAIT));
LRESULT lResult = 0;
lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETCURSEL,
0,
0);
WPARAM Index = (WPARAM) lResult;
lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
IDC_LIST_WIA_DEVICES,
LB_GETTEXT,
Index,
(LPARAM) szFriendlyName);
dwStartTime = timeGetTime();
//
// Get the images directory stored in the driver. We don't have to do this
// we can come up with our own, but the driver will generate a default temp
// location, which is good enough for our purposes.
//
TCHAR szTempPath[MAX_PATH] = {0};
if (hr == S_OK)
{
GetTempPath(MAX_PATH, szTempPath);
_sntprintf(szImagesDirectory, sizeof(szImagesDirectory) / sizeof(TCHAR),
TEXT("%s\\WiaVideoTest\\%s"), szTempPath, szFriendlyName);
}
//
// Set the images directory on the WiaVideo object
//
if (hr == S_OK)
{
WCHAR wszImagesDir[MAX_PATH] = {0};
AppUtil_ConvertToWideString(szImagesDirectory, wszImagesDir,
sizeof(wszImagesDir) / sizeof(WCHAR));
bstrImagesDir = ::SysAllocString(wszImagesDir);
hr = LOCAL_GVAR.pWiaVideo->put_ImagesDirectory(bstrImagesDir);
}
//
// Set the images directory on the WiaVideo object
//
if (hr == S_OK)
{
WCHAR wszFriendlyName[255 + 1] = {0};
AppUtil_ConvertToWideString(szFriendlyName, wszFriendlyName,
sizeof(wszFriendlyName) / sizeof(WCHAR));
bstrFriendlyName = ::SysAllocString(wszFriendlyName);
}
//
// Create Video.
//
if (hr == S_OK)
{
UINT uiDeviceNumber = (UINT) lResult;
hr = LOCAL_GVAR.pWiaVideo->CreateVideoByName(bstrFriendlyName,
GetDlgItem(APP_GVAR.hwndMainDlg,
IDC_VIDEO_PREVIEW_WINDOW),
FALSE,
TRUE);
}
dwEndTime = timeGetTime();
SetDlgItemInt(APP_GVAR.hwndMainDlg,
IDC_EDIT_GRAPH_BUILD_TIME,
(UINT) abs(dwEndTime - dwStartTime),
FALSE);
if (hr == S_OK)
{
SetDlgItemText(APP_GVAR.hwndMainDlg,
IDC_EDIT_IMAGES_DIR,
szImagesDirectory);
}
//
// Populate our list of items for this device
//
if (hr == S_OK)
{
hr = ImageLst_PopulateDShowItemList(szImagesDirectory);
}
if (bstrImagesDir)
{
::SysFreeString(bstrImagesDir);
bstrImagesDir = NULL;
}
if (bstrFriendlyName)
{
::SysFreeString(bstrFriendlyName);
bstrFriendlyName = NULL;
}
SetCursor( LoadCursor(NULL, IDC_ARROW));
if (hr != S_OK)
{
AppUtil_MsgBox(IDS_ERROR,
IDS_FAILED_TO_CREATE_VIDEO,
MB_OK | MB_ICONSTOP,
hr);
}
return hr;
}
///////////////////////////////
// DestroyVideo
//
HRESULT DestroyVideo()
{
HRESULT hr = S_OK;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
hr = LOCAL_GVAR.pWiaVideo->DestroyVideo();
if (APP_GVAR.bWiaDeviceListMode)
{
hr = WiaProc_DestroySelectedDevice();
ImageLst_Clear();
}
else
{
ImageLst_Clear();
}
SetDlgItemInt(APP_GVAR.hwndMainDlg,
IDC_EDIT_GRAPH_BUILD_TIME,
0,
FALSE);
SetDlgItemInt(APP_GVAR.hwndMainDlg,
IDC_EDIT_LIST_LOAD_TIME,
0,
FALSE);
return hr;
}
///////////////////////////////
// Play
//
HRESULT Play()
{
HRESULT hr = S_OK;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
LOCAL_GVAR.pWiaVideo->Play();
return hr;
}
///////////////////////////////
// Pause
//
HRESULT Pause()
{
HRESULT hr = S_OK;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
LOCAL_GVAR.pWiaVideo->Pause();
return hr;
}
///////////////////////////////
// TakePicture
//
HRESULT TakePicture(BOOL bTakePictureThroughDriver)
{
HRESULT hr = S_OK;
if (APP_GVAR.bWiaDeviceListMode)
{
if (bTakePictureThroughDriver)
{
//
// send DeviceCommand to driver. This is an async call for
// the Wia Video Driver which means we will NOT receive a
// WiaItem object back.
//
hr = WiaProc_DeviceTakePicture();
}
else
{
if (LOCAL_GVAR.pWiaVideo)
{
BSTR bstrNewImage = NULL;
hr = LOCAL_GVAR.pWiaVideo->TakePicture(&bstrNewImage);
if (hr == S_OK)
{
WiaProc_SetLastSavedImage(bstrNewImage);
}
if (bstrNewImage)
{
::SysFreeString(bstrNewImage);
bstrNewImage = NULL;
}
}
else
{
hr = E_POINTER;
}
}
}
else
{
if (LOCAL_GVAR.pWiaVideo)
{
BSTR bstrNewImage = NULL;
hr = LOCAL_GVAR.pWiaVideo->TakePicture(&bstrNewImage);
if (hr == S_OK)
{
ImageLst_PostAddImageRequest(bstrNewImage);
if (bstrNewImage)
{
::SysFreeString(bstrNewImage);
bstrNewImage = NULL;
}
}
}
}
return hr;
}
///////////////////////////////
// ShowVideo
//
HRESULT ShowVideo()
{
HRESULT hr = S_OK;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
if (LOCAL_GVAR.bPreviewVisible)
{
LOCAL_GVAR.bPreviewVisible = FALSE;
}
else
{
LOCAL_GVAR.bPreviewVisible = TRUE;
}
hr = LOCAL_GVAR.pWiaVideo->put_PreviewVisible(LOCAL_GVAR.bPreviewVisible);
return hr;
}
///////////////////////////////
// ResizeVideo
//
HRESULT ResizeVideo(BOOL bStretchToFitWindow)
{
HRESULT hr = S_OK;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
hr = LOCAL_GVAR.pWiaVideo->ResizeVideo(bStretchToFitWindow);
return hr;
}
///////////////////////////////
// ShowCurrentState
//
HRESULT ShowCurrentState()
{
HRESULT hr = S_OK;
WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
if (LOCAL_GVAR.pWiaVideo == NULL)
{
return E_POINTER;
}
hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
if (hr == S_OK)
{
UINT uiResID = 0;
TCHAR szState[63 + 1] = {0};
switch (VideoState)
{
case WIAVIDEO_NO_VIDEO:
uiResID = IDS_NO_VIDEO;
break;
case WIAVIDEO_CREATING_VIDEO:
uiResID = IDS_CREATING_VIDEO;
break;
case WIAVIDEO_VIDEO_CREATED:
uiResID = IDS_VIDEO_CREATED;
break;
case WIAVIDEO_VIDEO_PLAYING:
uiResID = IDS_PLAYING_VIDEO;
break;
case WIAVIDEO_VIDEO_PAUSED:
uiResID = IDS_VIDEO_PAUSED;
break;
case WIAVIDEO_DESTROYING_VIDEO:
uiResID = IDS_DESTROYING_VIDEO;
break;
default:
uiResID = IDS_STATE_UNKNOWN;
break;
}
LoadString(APP_GVAR.hInstance,
uiResID,
szState,
sizeof(szState) / sizeof(TCHAR));
if (szState[0] != 0)
{
SetDlgItemText(APP_GVAR.hwndMainDlg,
IDC_EDIT_CURRENT_STATE,
szState);
}
}
return hr;
}
///////////////////////////////
// CreateWiaVideoObject
//
HRESULT CreateWiaVideoObject()
{
HRESULT hr = S_OK;
if (hr == S_OK)
{
// Create the WiaVideo object
hr = CoCreateInstance(CLSID_WiaVideo, NULL, CLSCTX_INPROC_SERVER,
IID_IWiaVideo, (LPVOID *)&LOCAL_GVAR.pWiaVideo);
}
return hr;
}
///////////////////////////////
// TakePictureStress
//
HRESULT TakePictureStress()
{
HRESULT hr = S_OK;
INT_PTR iReturn = 0;
//
// Ask user how many threads to use and how many
// pictures each thread should take.
//
LOCAL_GVAR.iNumThreads = 0;
LOCAL_GVAR.uiNumImagesPerThread = 0;
iReturn = DialogBox(APP_GVAR.hInstance,
MAKEINTRESOURCE(IDD_STRESSDLG),
APP_GVAR.hwndMainDlg,
(DLGPROC) StressDlgProc);
if (iReturn == IDOK)
{
SetDlgItemInt(APP_GVAR.hwndMainDlg, IDC_EDIT_NUM_STRESS_THREADS,
LOCAL_GVAR.iNumThreads, FALSE);
UINT uiNumThreads = (UINT) LOCAL_GVAR.iNumThreads;
for (UINT i = 0; (i < uiNumThreads) && (hr == S_OK); i++)
{
ThreadArgs_t *pArgs = new ThreadArgs_t;
if (pArgs)
{
DWORD dwThreadID = 0;
ZeroMemory(pArgs, sizeof(ThreadArgs_t));
pArgs->uiNumPicturesToTake = LOCAL_GVAR.uiNumImagesPerThread;
pArgs->uiThreadSleepTime = (rand() % 100) + 25; // 25 - 125 ms sleeptime.
CreateThread(NULL,
0,
TakePictureThreadProc,
(void*) pArgs,
0,
&dwThreadID);
}
else
{
hr = E_OUTOFMEMORY;
}
}
}
return hr;
}
///////////////////////////////
// StressDlgProc
//
// Mesage handler for Stress Dialog Box
//
LRESULT CALLBACK StressDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
break;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
BOOL bTranslated = TRUE;
LOCAL_GVAR.iNumThreads = GetDlgItemInt(hDlg,
IDC_EDIT_NUM_THREADS,
&bTranslated,
FALSE);
LOCAL_GVAR.uiNumImagesPerThread = GetDlgItemInt(hDlg,
IDC_EDIT_NUM_IMAGES_PER_THREAD,
&bTranslated,
FALSE);
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
else if (LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
///////////////////////////////
// TakePictureMultiple
//
HRESULT TakePictureMultiple()
{
HRESULT hr = S_OK;
INT_PTR iReturn = 0;
//
// Ask user how many threads to use and how many
// pictures each thread should take.
//
LOCAL_GVAR.iNumThreads = 0;
LOCAL_GVAR.uiNumImagesPerThread = 0;
iReturn = DialogBox(APP_GVAR.hInstance,
MAKEINTRESOURCE(IDD_DIALOG_TAKE_PICTURE_MULTIPLE),
APP_GVAR.hwndMainDlg,
(DLGPROC) MultipleDlgProc);
if (iReturn == IDOK)
{
SetDlgItemInt(APP_GVAR.hwndMainDlg, IDC_EDIT_NUM_STRESS_THREADS,
1, FALSE);
//
// uiNumThreads should be 1.
//
UINT uiNumThreads = 1;
for (UINT i = 0; i < uiNumThreads; i++)
{
ThreadArgs_t *pArgs = new ThreadArgs_t;
if (pArgs)
{
ZeroMemory(pArgs, sizeof(ThreadArgs_t));
pArgs->uiNumPicturesToTake = LOCAL_GVAR.uiNumImagesPerThread;
pArgs->uiThreadSleepTime = LOCAL_GVAR.uiTakePictureInterval;
DWORD dwThreadID = 0;
CreateThread(NULL,
0,
TakePictureThreadProc,
(void*) pArgs,
0,
&dwThreadID);
}
}
}
return hr;
}
///////////////////////////////
// MultipleDlgProc
//
// Mesage handler for Stress Dialog Box
//
LRESULT CALLBACK MultipleDlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
break;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
BOOL bTranslated = TRUE;
LOCAL_GVAR.iNumThreads = 1;
LOCAL_GVAR.uiNumImagesPerThread = GetDlgItemInt(hDlg,
IDC_EDIT_NUM_PICTURES_TO_TAKE,
&bTranslated,
FALSE);
LOCAL_GVAR.uiTakePictureInterval = GetDlgItemInt(hDlg,
IDC_EDIT_TAKE_PICTURE_FREQUENCY,
&bTranslated,
FALSE);
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
else if (LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
///////////////////////////////
// TakePictureThreadProc
//
DWORD WINAPI TakePictureThreadProc(void *pArgs)
{
HRESULT hr = S_OK;
BOOL bDone = FALSE;
ThreadArgs_t *pThreadArgs = (ThreadArgs_t*) pArgs;
if (pThreadArgs == NULL)
{
return E_POINTER;
}
UINT uiNumPicturesToTake = pThreadArgs->uiNumPicturesToTake;
UINT uiSleepTime = pThreadArgs->uiThreadSleepTime;
UINT uiNumPicturesTaken = 0;
delete pThreadArgs;
pThreadArgs = NULL;
while (!bDone)
{
if ((LOCAL_GVAR.pWiaVideo == NULL) ||
(LOCAL_GVAR.bExitThreads == TRUE))
{
bDone = TRUE;
}
if (!bDone)
{
hr = TakePicture(FALSE);
if (hr != S_OK)
{
bDone = TRUE;
}
Sleep(uiSleepTime);
++uiNumPicturesTaken;
if (uiNumPicturesTaken >= uiNumPicturesToTake)
{
bDone = TRUE;
}
}
}
InterlockedDecrement((LONG*) &LOCAL_GVAR.iNumThreads);
SetDlgItemInt(APP_GVAR.hwndMainDlg, IDC_EDIT_NUM_STRESS_THREADS,
LOCAL_GVAR.iNumThreads, FALSE);
return 0;
}
///////////////////////////////
// GetDeviceProperty
//
// Static Fn
//
BOOL GetDeviceProperty(IPropertyBag *pPropertyBag,
LPCWSTR pwszProperty,
TCHAR *pszProperty,
DWORD cchProperty)
{
HRESULT hr = S_OK;
VARIANT VarName;
if ((pPropertyBag == NULL) ||
(pwszProperty == NULL) ||
(pszProperty == NULL))
{
hr = E_POINTER;
}
if (SUCCEEDED(hr))
{
VariantInit(&VarName);
VarName.vt = VT_BSTR;
hr = pPropertyBag->Read(pwszProperty, &VarName, 0);
}
if (SUCCEEDED(hr))
{
hr = AppUtil_ConvertToTCHAR(VarName.bstrVal,
pszProperty,
cchProperty);
VariantClear(&VarName);
}
return hr;
}