|
|
/*****************************************************************************
* * (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); INT_PTR CALLBACK MultipleDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); INT_PTR 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, 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
//
INT_PTR 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, 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
//
INT_PTR 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; }
|