Leaked source code of windows server 2003
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
34 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: VideoProc.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * DATE: 2000/11/14
  10. *
  11. * DESCRIPTION: Manages WiaVideo object.
  12. *
  13. *****************************************************************************/
  14. #include <stdafx.h>
  15. #include <mmsystem.h>
  16. #include <streams.h>
  17. #include <mmreg.h>
  18. #include "wiavideotest.h"
  19. ///////////////////////////////
  20. // LOCAL_GVAR
  21. //
  22. static struct
  23. {
  24. IWiaVideo *pWiaVideo;
  25. BOOL bPreviewVisible;
  26. INT iNumThreads;
  27. UINT uiNumImagesPerThread;
  28. UINT uiTakePictureInterval;
  29. BOOL bExitThreads;
  30. BOOL bVideoStretched;
  31. } LOCAL_GVAR =
  32. {
  33. NULL,
  34. TRUE,
  35. 0,
  36. 0,
  37. 0,
  38. FALSE,
  39. FALSE
  40. };
  41. ///////////////////////////////
  42. // ThreadArgs_t
  43. //
  44. typedef struct ThreadArgs_t
  45. {
  46. UINT uiNumPicturesToTake;
  47. UINT uiThreadSleepTime; // if 0, calc'd as a random number.
  48. } ThreadArgs_t;
  49. /****************************Local Function Prototypes********************/
  50. HRESULT CreateWiaVideoObject();
  51. HRESULT CreateVideoEnumPos();
  52. HRESULT CreateVideoFriendlyName();
  53. HRESULT CreateVideoWia();
  54. HRESULT DestroyVideo();
  55. HRESULT Play();
  56. HRESULT Pause();
  57. HRESULT TakePicture(BOOL bTakePictureThroughDriver);
  58. HRESULT ShowVideo();
  59. HRESULT ResizeVideo(BOOL bStretchToFitWindow);
  60. HRESULT ShowCurrentState();
  61. HRESULT TakePictureMultiple();
  62. HRESULT TakePictureStress();
  63. DWORD WINAPI TakePictureThreadProc(void *pArgs);
  64. INT_PTR CALLBACK MultipleDlgProc(HWND hDlg,
  65. UINT message,
  66. WPARAM wParam,
  67. LPARAM lParam);
  68. INT_PTR CALLBACK StressDlgProc(HWND hDlg,
  69. UINT message,
  70. WPARAM wParam,
  71. LPARAM lParam);
  72. BOOL GetDeviceProperty(IPropertyBag *pPropertyBag,
  73. LPCWSTR pwszProperty,
  74. TCHAR *pszProperty,
  75. DWORD cchProperty);
  76. ///////////////////////////////
  77. // VideoProc_Init
  78. //
  79. HRESULT VideoProc_Init()
  80. {
  81. HRESULT hr = S_OK;
  82. hr = CreateWiaVideoObject();
  83. return hr;
  84. }
  85. ///////////////////////////////
  86. // VideoProc_Term
  87. //
  88. HRESULT VideoProc_Term()
  89. {
  90. HRESULT hr = S_OK;
  91. LOCAL_GVAR.bExitThreads = TRUE;
  92. //
  93. // Crude, but for a test app, it is easier than creating an
  94. // array of thread handles and waiting for each one to finish.
  95. //
  96. INT iLoops = 0;
  97. while ((LOCAL_GVAR.iNumThreads > 0) && (iLoops < 50))
  98. {
  99. ++iLoops;
  100. Sleep(100);
  101. }
  102. DestroyVideo();
  103. if (LOCAL_GVAR.pWiaVideo)
  104. {
  105. LOCAL_GVAR.pWiaVideo->Release();
  106. LOCAL_GVAR.pWiaVideo = NULL;
  107. }
  108. return hr;
  109. }
  110. ///////////////////////////////
  111. // VideoProc_DShowListInit
  112. //
  113. HRESULT VideoProc_DShowListInit()
  114. {
  115. HRESULT hr = S_OK;
  116. LONG lPosNum = 0;
  117. ICreateDevEnum *pCreateDevEnum = NULL;
  118. IEnumMoniker *pEnumMoniker = NULL;
  119. //
  120. // Empty the list
  121. //
  122. SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  123. IDC_LIST_WIA_DEVICES,
  124. LB_RESETCONTENT,
  125. 0,
  126. 0);
  127. if (hr == S_OK)
  128. {
  129. //
  130. // Create the device enumerator
  131. //
  132. hr = CoCreateInstance(CLSID_SystemDeviceEnum,
  133. NULL,
  134. CLSCTX_INPROC_SERVER,
  135. IID_ICreateDevEnum,
  136. (void**)&pCreateDevEnum);
  137. }
  138. if (hr == S_OK)
  139. {
  140. hr = pCreateDevEnum->CreateClassEnumerator(
  141. CLSID_VideoInputDeviceCategory,
  142. &pEnumMoniker,
  143. 0);
  144. }
  145. //
  146. // Loop through all the devices
  147. //
  148. while (hr == S_OK)
  149. {
  150. TCHAR szFriendlyName[255 + 1] = {0};
  151. IMoniker *pMoniker = NULL;
  152. IPropertyBag *pPropertyBag = NULL;
  153. hr = pEnumMoniker->Next(1, &pMoniker, NULL);
  154. if (hr == S_OK)
  155. {
  156. //
  157. // Get property storage for this DS device so we can get it's
  158. // device id...
  159. //
  160. hr = pMoniker->BindToStorage(0,
  161. 0,
  162. IID_IPropertyBag,
  163. (void **)&pPropertyBag);
  164. }
  165. if (hr == S_OK)
  166. {
  167. hr = GetDeviceProperty(pPropertyBag,
  168. L"FriendlyName",
  169. szFriendlyName,
  170. sizeof(szFriendlyName) / sizeof(TCHAR));
  171. }
  172. if (hr == S_OK)
  173. {
  174. SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  175. IDC_LIST_WIA_DEVICES,
  176. LB_ADDSTRING,
  177. 0,
  178. (LPARAM) szFriendlyName);
  179. }
  180. if (pMoniker)
  181. {
  182. pMoniker->Release();
  183. pMoniker = NULL;
  184. }
  185. if (pPropertyBag)
  186. {
  187. pPropertyBag->Release();
  188. pPropertyBag = NULL;
  189. }
  190. }
  191. SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  192. IDC_LIST_WIA_DEVICES,
  193. LB_SETCURSEL,
  194. 0,
  195. 0);
  196. if (pEnumMoniker)
  197. {
  198. pEnumMoniker->Release();
  199. pEnumMoniker = NULL;
  200. }
  201. if (pCreateDevEnum)
  202. {
  203. pCreateDevEnum->Release();
  204. pCreateDevEnum = NULL;
  205. }
  206. return hr;
  207. }
  208. ///////////////////////////////
  209. // VideoProc_DShowListTerm
  210. //
  211. HRESULT VideoProc_DShowListTerm()
  212. {
  213. HRESULT hr = S_OK;
  214. //
  215. // Empty the list
  216. //
  217. SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  218. IDC_LIST_WIA_DEVICES,
  219. LB_RESETCONTENT,
  220. 0,
  221. 0);
  222. return hr;
  223. }
  224. ///////////////////////////////
  225. // VideoProc_TakePicture
  226. //
  227. HRESULT VideoProc_TakePicture()
  228. {
  229. HRESULT hr = S_OK;
  230. hr = TakePicture(FALSE);
  231. return hr;
  232. }
  233. ///////////////////////////////
  234. // VideoProc_ProcessMsg
  235. //
  236. UINT_PTR VideoProc_ProcessMsg(UINT uiControlID)
  237. {
  238. HRESULT hr = S_OK;
  239. UINT_PTR uiReturn = 0;
  240. switch (uiControlID)
  241. {
  242. case IDC_BUTTON_CREATE_VIDEO_WIA:
  243. hr = CreateVideoWia();
  244. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), FALSE);
  245. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), FALSE);
  246. break;
  247. case IDC_BUTTON_CREATE_VIDEO_ENUM_POS:
  248. hr = CreateVideoEnumPos();
  249. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), FALSE);
  250. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), FALSE);
  251. break;
  252. case IDC_BUTTON_CREATE_VIDEO_FRIENDLY_NAME:
  253. hr = CreateVideoFriendlyName();
  254. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), FALSE);
  255. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), FALSE);
  256. break;
  257. case IDC_BUTTON_TAKE_PICTURE_STRESS:
  258. TakePictureStress();
  259. break;
  260. case IDC_BUTTON_TAKE_PICTURE_MULTIPLE:
  261. TakePictureMultiple();
  262. break;
  263. case IDC_BUTTON_DESTROY_VIDEO:
  264. SetCursor( LoadCursor(NULL, IDC_WAIT));
  265. DestroyVideo();
  266. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_WIA_DEVICE_LIST), TRUE);
  267. EnableWindow(GetDlgItem(APP_GVAR.hwndMainDlg, IDC_RADIO_DSHOW_DEVICE_LIST), TRUE);
  268. SetCursor( LoadCursor(NULL, IDC_ARROW));
  269. break;
  270. case IDC_BUTTON_PLAY:
  271. Play();
  272. break;
  273. case IDC_BUTTON_PAUSE:
  274. Pause();
  275. break;
  276. case IDC_BUTTON_TAKE_PICTURE:
  277. TakePicture(FALSE);
  278. break;
  279. case IDC_BUTTON_TAKE_PICTURE_DRIVER:
  280. TakePicture(TRUE);
  281. break;
  282. case IDC_BUTTON_SHOW_VIDEO_TOGGLE:
  283. ShowVideo();
  284. break;
  285. case IDC_BUTTON_RESIZE_TOGGLE:
  286. LOCAL_GVAR.bVideoStretched = (LOCAL_GVAR.bVideoStretched ? FALSE : TRUE);
  287. ResizeVideo(LOCAL_GVAR.bVideoStretched);
  288. break;
  289. default:
  290. break;
  291. }
  292. ShowCurrentState();
  293. return uiReturn;
  294. }
  295. ///////////////////////////////
  296. // CreateVideoWia
  297. //
  298. HRESULT CreateVideoWia()
  299. {
  300. HRESULT hr = S_OK;
  301. TCHAR szDeviceID[MAX_PATH] = {0};
  302. TCHAR szImagesDirectory[MAX_PATH] = {0};
  303. BSTR bstrImagesDir = NULL;
  304. BSTR bstrDeviceID = NULL;
  305. WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
  306. DWORD dwStartTime = 0;
  307. DWORD dwEndTime = 0;
  308. if (LOCAL_GVAR.pWiaVideo == NULL)
  309. {
  310. return E_POINTER;
  311. }
  312. hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
  313. if (VideoState != WIAVIDEO_NO_VIDEO)
  314. {
  315. AppUtil_MsgBox(IDS_ERROR,
  316. IDS_VIDEO_STILL_ACTIVE,
  317. MB_OK | MB_ICONSTOP);
  318. return hr;
  319. }
  320. SetCursor( LoadCursor(NULL, IDC_WAIT));
  321. //
  322. // We need to do this first, otherwise the driver is not loaded yet,
  323. // and therefore the images directory property will have not been set
  324. //
  325. if (hr == S_OK)
  326. {
  327. hr = WiaProc_CreateSelectedDevice(szDeviceID,
  328. sizeof(szDeviceID) / sizeof(TCHAR));
  329. }
  330. dwStartTime = timeGetTime();
  331. //
  332. // Get the images directory stored in the driver. We don't have to do this
  333. // we can come up with our own, but the driver will generate a default temp
  334. // location, which is good enough for our purposes.
  335. //
  336. if (hr == S_OK)
  337. {
  338. hr = WiaProc_GetImageDirectory(szImagesDirectory,
  339. sizeof(szImagesDirectory) / sizeof(TCHAR));
  340. }
  341. if (hr == S_OK)
  342. {
  343. WCHAR wszDeviceID[MAX_PATH] = {0};
  344. AppUtil_ConvertToWideString(szDeviceID, wszDeviceID,
  345. sizeof(wszDeviceID) / sizeof(WCHAR));
  346. bstrDeviceID = ::SysAllocString(wszDeviceID);
  347. }
  348. //
  349. // Set the images directory on the WiaVideo object
  350. //
  351. if (hr == S_OK)
  352. {
  353. WCHAR wszImagesDir[MAX_PATH] = {0};
  354. AppUtil_ConvertToWideString(szImagesDirectory, wszImagesDir,
  355. sizeof(wszImagesDir) / sizeof(WCHAR));
  356. bstrImagesDir = ::SysAllocString(wszImagesDir);
  357. hr = LOCAL_GVAR.pWiaVideo->put_ImagesDirectory(bstrImagesDir);
  358. }
  359. //
  360. // Create Video.
  361. //
  362. if (hr == S_OK)
  363. {
  364. hr = LOCAL_GVAR.pWiaVideo->CreateVideoByWiaDevID(bstrDeviceID,
  365. GetDlgItem(APP_GVAR.hwndMainDlg,
  366. IDC_VIDEO_PREVIEW_WINDOW),
  367. FALSE,
  368. TRUE);
  369. }
  370. dwEndTime = timeGetTime();
  371. SetDlgItemInt(APP_GVAR.hwndMainDlg,
  372. IDC_EDIT_GRAPH_BUILD_TIME,
  373. (UINT) abs(dwEndTime - dwStartTime),
  374. FALSE);
  375. if (hr == S_OK)
  376. {
  377. SetDlgItemText(APP_GVAR.hwndMainDlg,
  378. IDC_EDIT_IMAGES_DIR,
  379. szImagesDirectory);
  380. }
  381. //
  382. // Populate our list of items for this device
  383. //
  384. if (hr == S_OK)
  385. {
  386. hr = WiaProc_PopulateItemList();
  387. }
  388. if (bstrImagesDir)
  389. {
  390. ::SysFreeString(bstrImagesDir);
  391. bstrImagesDir = NULL;
  392. }
  393. if (bstrDeviceID)
  394. {
  395. ::SysFreeString(bstrDeviceID);
  396. bstrDeviceID = NULL;
  397. }
  398. SetCursor( LoadCursor(NULL, IDC_ARROW));
  399. if (hr != S_OK)
  400. {
  401. AppUtil_MsgBox(IDS_ERROR,
  402. IDS_FAILED_TO_CREATE_VIDEO,
  403. MB_OK | MB_ICONSTOP,
  404. hr);
  405. }
  406. return hr;
  407. }
  408. ///////////////////////////////
  409. // CreateVideoEnumPos
  410. //
  411. HRESULT CreateVideoEnumPos()
  412. {
  413. HRESULT hr = S_OK;
  414. TCHAR szImagesDirectory[MAX_PATH] = {0};
  415. TCHAR szFriendlyName[255 + 1] = {0};
  416. BSTR bstrImagesDir = NULL;
  417. WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
  418. DWORD dwStartTime = 0;
  419. DWORD dwEndTime = 0;
  420. if (LOCAL_GVAR.pWiaVideo == NULL)
  421. {
  422. return E_POINTER;
  423. }
  424. hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
  425. if (VideoState != WIAVIDEO_NO_VIDEO)
  426. {
  427. AppUtil_MsgBox(IDS_ERROR,
  428. IDS_VIDEO_STILL_ACTIVE,
  429. MB_OK | MB_ICONSTOP);
  430. return hr;
  431. }
  432. SetCursor( LoadCursor(NULL, IDC_WAIT));
  433. LRESULT lResult = 0;
  434. lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  435. IDC_LIST_WIA_DEVICES,
  436. LB_GETCURSEL,
  437. 0,
  438. 0);
  439. WPARAM Index = (WPARAM) lResult;
  440. lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  441. IDC_LIST_WIA_DEVICES,
  442. LB_GETTEXT,
  443. Index,
  444. (LPARAM) szFriendlyName);
  445. dwStartTime = timeGetTime();
  446. //
  447. // Get the images directory stored in the driver. We don't have to do this
  448. // we can come up with our own, but the driver will generate a default temp
  449. // location, which is good enough for our purposes.
  450. //
  451. TCHAR szTempPath[MAX_PATH] = {0};
  452. if (hr == S_OK)
  453. {
  454. GetTempPath(MAX_PATH, szTempPath);
  455. _sntprintf(szImagesDirectory, sizeof(szImagesDirectory) / sizeof(TCHAR),
  456. TEXT("%s\\WiaVideoTest\\%s"), szTempPath, szFriendlyName);
  457. }
  458. //
  459. // Set the images directory on the WiaVideo object
  460. //
  461. if (hr == S_OK)
  462. {
  463. WCHAR wszImagesDir[MAX_PATH] = {0};
  464. AppUtil_ConvertToWideString(szImagesDirectory, wszImagesDir,
  465. sizeof(wszImagesDir) / sizeof(WCHAR));
  466. bstrImagesDir = ::SysAllocString(wszImagesDir);
  467. hr = LOCAL_GVAR.pWiaVideo->put_ImagesDirectory(bstrImagesDir);
  468. }
  469. //
  470. // Create Video.
  471. //
  472. if (hr == S_OK)
  473. {
  474. UINT uiDeviceNumber = (UINT) Index;
  475. hr = LOCAL_GVAR.pWiaVideo->CreateVideoByDevNum(uiDeviceNumber,
  476. GetDlgItem(APP_GVAR.hwndMainDlg,
  477. IDC_VIDEO_PREVIEW_WINDOW),
  478. FALSE,
  479. TRUE);
  480. }
  481. dwEndTime = timeGetTime();
  482. SetDlgItemInt(APP_GVAR.hwndMainDlg,
  483. IDC_EDIT_GRAPH_BUILD_TIME,
  484. (UINT) abs(dwEndTime - dwStartTime),
  485. FALSE);
  486. if (hr == S_OK)
  487. {
  488. SetDlgItemText(APP_GVAR.hwndMainDlg,
  489. IDC_EDIT_IMAGES_DIR,
  490. szImagesDirectory);
  491. }
  492. //
  493. // Populate our list of items for this device
  494. //
  495. if (hr == S_OK)
  496. {
  497. hr = ImageLst_PopulateDShowItemList(szImagesDirectory);
  498. }
  499. if (bstrImagesDir)
  500. {
  501. ::SysFreeString(bstrImagesDir);
  502. bstrImagesDir = NULL;
  503. }
  504. SetCursor( LoadCursor(NULL, IDC_ARROW));
  505. if (hr != S_OK)
  506. {
  507. AppUtil_MsgBox(IDS_ERROR,
  508. IDS_FAILED_TO_CREATE_VIDEO,
  509. MB_OK | MB_ICONSTOP,
  510. hr);
  511. }
  512. return hr;
  513. }
  514. ///////////////////////////////
  515. // CreateVideoFriendlyName
  516. //
  517. HRESULT CreateVideoFriendlyName()
  518. {
  519. HRESULT hr = S_OK;
  520. TCHAR szImagesDirectory[MAX_PATH] = {0};
  521. TCHAR szFriendlyName[255 + 1] = {0};
  522. BSTR bstrFriendlyName = NULL;
  523. BSTR bstrImagesDir = NULL;
  524. WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
  525. DWORD dwStartTime = 0;
  526. DWORD dwEndTime = 0;
  527. if (LOCAL_GVAR.pWiaVideo == NULL)
  528. {
  529. return E_POINTER;
  530. }
  531. hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
  532. if (VideoState != WIAVIDEO_NO_VIDEO)
  533. {
  534. AppUtil_MsgBox(IDS_ERROR,
  535. IDS_VIDEO_STILL_ACTIVE,
  536. MB_OK | MB_ICONSTOP);
  537. return hr;
  538. }
  539. SetCursor( LoadCursor(NULL, IDC_WAIT));
  540. LRESULT lResult = 0;
  541. lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  542. IDC_LIST_WIA_DEVICES,
  543. LB_GETCURSEL,
  544. 0,
  545. 0);
  546. WPARAM Index = (WPARAM) lResult;
  547. lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  548. IDC_LIST_WIA_DEVICES,
  549. LB_GETTEXT,
  550. Index,
  551. (LPARAM) szFriendlyName);
  552. dwStartTime = timeGetTime();
  553. //
  554. // Get the images directory stored in the driver. We don't have to do this
  555. // we can come up with our own, but the driver will generate a default temp
  556. // location, which is good enough for our purposes.
  557. //
  558. TCHAR szTempPath[MAX_PATH] = {0};
  559. if (hr == S_OK)
  560. {
  561. GetTempPath(MAX_PATH, szTempPath);
  562. _sntprintf(szImagesDirectory, sizeof(szImagesDirectory) / sizeof(TCHAR),
  563. TEXT("%s\\WiaVideoTest\\%s"), szTempPath, szFriendlyName);
  564. }
  565. //
  566. // Set the images directory on the WiaVideo object
  567. //
  568. if (hr == S_OK)
  569. {
  570. WCHAR wszImagesDir[MAX_PATH] = {0};
  571. AppUtil_ConvertToWideString(szImagesDirectory, wszImagesDir,
  572. sizeof(wszImagesDir) / sizeof(WCHAR));
  573. bstrImagesDir = ::SysAllocString(wszImagesDir);
  574. hr = LOCAL_GVAR.pWiaVideo->put_ImagesDirectory(bstrImagesDir);
  575. }
  576. //
  577. // Set the images directory on the WiaVideo object
  578. //
  579. if (hr == S_OK)
  580. {
  581. WCHAR wszFriendlyName[255 + 1] = {0};
  582. AppUtil_ConvertToWideString(szFriendlyName, wszFriendlyName,
  583. sizeof(wszFriendlyName) / sizeof(WCHAR));
  584. bstrFriendlyName = ::SysAllocString(wszFriendlyName);
  585. }
  586. //
  587. // Create Video.
  588. //
  589. if (hr == S_OK)
  590. {
  591. UINT uiDeviceNumber = (UINT) lResult;
  592. hr = LOCAL_GVAR.pWiaVideo->CreateVideoByName(bstrFriendlyName,
  593. GetDlgItem(APP_GVAR.hwndMainDlg,
  594. IDC_VIDEO_PREVIEW_WINDOW),
  595. FALSE,
  596. TRUE);
  597. }
  598. dwEndTime = timeGetTime();
  599. SetDlgItemInt(APP_GVAR.hwndMainDlg,
  600. IDC_EDIT_GRAPH_BUILD_TIME,
  601. (UINT) abs(dwEndTime - dwStartTime),
  602. FALSE);
  603. if (hr == S_OK)
  604. {
  605. SetDlgItemText(APP_GVAR.hwndMainDlg,
  606. IDC_EDIT_IMAGES_DIR,
  607. szImagesDirectory);
  608. }
  609. //
  610. // Populate our list of items for this device
  611. //
  612. if (hr == S_OK)
  613. {
  614. hr = ImageLst_PopulateDShowItemList(szImagesDirectory);
  615. }
  616. if (bstrImagesDir)
  617. {
  618. ::SysFreeString(bstrImagesDir);
  619. bstrImagesDir = NULL;
  620. }
  621. if (bstrFriendlyName)
  622. {
  623. ::SysFreeString(bstrFriendlyName);
  624. bstrFriendlyName = NULL;
  625. }
  626. SetCursor( LoadCursor(NULL, IDC_ARROW));
  627. if (hr != S_OK)
  628. {
  629. AppUtil_MsgBox(IDS_ERROR,
  630. IDS_FAILED_TO_CREATE_VIDEO,
  631. MB_OK | MB_ICONSTOP,
  632. hr);
  633. }
  634. return hr;
  635. }
  636. ///////////////////////////////
  637. // DestroyVideo
  638. //
  639. HRESULT DestroyVideo()
  640. {
  641. HRESULT hr = S_OK;
  642. if (LOCAL_GVAR.pWiaVideo == NULL)
  643. {
  644. return E_POINTER;
  645. }
  646. hr = LOCAL_GVAR.pWiaVideo->DestroyVideo();
  647. if (APP_GVAR.bWiaDeviceListMode)
  648. {
  649. hr = WiaProc_DestroySelectedDevice();
  650. ImageLst_Clear();
  651. }
  652. else
  653. {
  654. ImageLst_Clear();
  655. }
  656. SetDlgItemInt(APP_GVAR.hwndMainDlg,
  657. IDC_EDIT_GRAPH_BUILD_TIME,
  658. 0,
  659. FALSE);
  660. SetDlgItemInt(APP_GVAR.hwndMainDlg,
  661. IDC_EDIT_LIST_LOAD_TIME,
  662. 0,
  663. FALSE);
  664. return hr;
  665. }
  666. ///////////////////////////////
  667. // Play
  668. //
  669. HRESULT Play()
  670. {
  671. HRESULT hr = S_OK;
  672. if (LOCAL_GVAR.pWiaVideo == NULL)
  673. {
  674. return E_POINTER;
  675. }
  676. LOCAL_GVAR.pWiaVideo->Play();
  677. return hr;
  678. }
  679. ///////////////////////////////
  680. // Pause
  681. //
  682. HRESULT Pause()
  683. {
  684. HRESULT hr = S_OK;
  685. if (LOCAL_GVAR.pWiaVideo == NULL)
  686. {
  687. return E_POINTER;
  688. }
  689. LOCAL_GVAR.pWiaVideo->Pause();
  690. return hr;
  691. }
  692. ///////////////////////////////
  693. // TakePicture
  694. //
  695. HRESULT TakePicture(BOOL bTakePictureThroughDriver)
  696. {
  697. HRESULT hr = S_OK;
  698. if (APP_GVAR.bWiaDeviceListMode)
  699. {
  700. if (bTakePictureThroughDriver)
  701. {
  702. //
  703. // send DeviceCommand to driver. This is an async call for
  704. // the Wia Video Driver which means we will NOT receive a
  705. // WiaItem object back.
  706. //
  707. hr = WiaProc_DeviceTakePicture();
  708. }
  709. else
  710. {
  711. if (LOCAL_GVAR.pWiaVideo)
  712. {
  713. BSTR bstrNewImage = NULL;
  714. hr = LOCAL_GVAR.pWiaVideo->TakePicture(&bstrNewImage);
  715. if (hr == S_OK)
  716. {
  717. WiaProc_SetLastSavedImage(bstrNewImage);
  718. }
  719. if (bstrNewImage)
  720. {
  721. ::SysFreeString(bstrNewImage);
  722. bstrNewImage = NULL;
  723. }
  724. }
  725. else
  726. {
  727. hr = E_POINTER;
  728. }
  729. }
  730. }
  731. else
  732. {
  733. if (LOCAL_GVAR.pWiaVideo)
  734. {
  735. BSTR bstrNewImage = NULL;
  736. hr = LOCAL_GVAR.pWiaVideo->TakePicture(&bstrNewImage);
  737. if (hr == S_OK)
  738. {
  739. ImageLst_PostAddImageRequest(bstrNewImage);
  740. if (bstrNewImage)
  741. {
  742. ::SysFreeString(bstrNewImage);
  743. bstrNewImage = NULL;
  744. }
  745. }
  746. }
  747. }
  748. return hr;
  749. }
  750. ///////////////////////////////
  751. // ShowVideo
  752. //
  753. HRESULT ShowVideo()
  754. {
  755. HRESULT hr = S_OK;
  756. if (LOCAL_GVAR.pWiaVideo == NULL)
  757. {
  758. return E_POINTER;
  759. }
  760. if (LOCAL_GVAR.bPreviewVisible)
  761. {
  762. LOCAL_GVAR.bPreviewVisible = FALSE;
  763. }
  764. else
  765. {
  766. LOCAL_GVAR.bPreviewVisible = TRUE;
  767. }
  768. hr = LOCAL_GVAR.pWiaVideo->put_PreviewVisible(LOCAL_GVAR.bPreviewVisible);
  769. return hr;
  770. }
  771. ///////////////////////////////
  772. // ResizeVideo
  773. //
  774. HRESULT ResizeVideo(BOOL bStretchToFitWindow)
  775. {
  776. HRESULT hr = S_OK;
  777. if (LOCAL_GVAR.pWiaVideo == NULL)
  778. {
  779. return E_POINTER;
  780. }
  781. hr = LOCAL_GVAR.pWiaVideo->ResizeVideo(bStretchToFitWindow);
  782. return hr;
  783. }
  784. ///////////////////////////////
  785. // ShowCurrentState
  786. //
  787. HRESULT ShowCurrentState()
  788. {
  789. HRESULT hr = S_OK;
  790. WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
  791. if (LOCAL_GVAR.pWiaVideo == NULL)
  792. {
  793. return E_POINTER;
  794. }
  795. hr = LOCAL_GVAR.pWiaVideo->GetCurrentState(&VideoState);
  796. if (hr == S_OK)
  797. {
  798. UINT uiResID = 0;
  799. TCHAR szState[63 + 1] = {0};
  800. switch (VideoState)
  801. {
  802. case WIAVIDEO_NO_VIDEO:
  803. uiResID = IDS_NO_VIDEO;
  804. break;
  805. case WIAVIDEO_CREATING_VIDEO:
  806. uiResID = IDS_CREATING_VIDEO;
  807. break;
  808. case WIAVIDEO_VIDEO_CREATED:
  809. uiResID = IDS_VIDEO_CREATED;
  810. break;
  811. case WIAVIDEO_VIDEO_PLAYING:
  812. uiResID = IDS_PLAYING_VIDEO;
  813. break;
  814. case WIAVIDEO_VIDEO_PAUSED:
  815. uiResID = IDS_VIDEO_PAUSED;
  816. break;
  817. case WIAVIDEO_DESTROYING_VIDEO:
  818. uiResID = IDS_DESTROYING_VIDEO;
  819. break;
  820. default:
  821. uiResID = IDS_STATE_UNKNOWN;
  822. break;
  823. }
  824. LoadString(APP_GVAR.hInstance,
  825. uiResID,
  826. szState,
  827. sizeof(szState) / sizeof(TCHAR));
  828. if (szState[0] != 0)
  829. {
  830. SetDlgItemText(APP_GVAR.hwndMainDlg,
  831. IDC_EDIT_CURRENT_STATE,
  832. szState);
  833. }
  834. }
  835. return hr;
  836. }
  837. ///////////////////////////////
  838. // CreateWiaVideoObject
  839. //
  840. HRESULT CreateWiaVideoObject()
  841. {
  842. HRESULT hr = S_OK;
  843. if (hr == S_OK)
  844. {
  845. // Create the WiaVideo object
  846. hr = CoCreateInstance(CLSID_WiaVideo, NULL, CLSCTX_INPROC_SERVER,
  847. IID_IWiaVideo, (LPVOID *)&LOCAL_GVAR.pWiaVideo);
  848. }
  849. return hr;
  850. }
  851. ///////////////////////////////
  852. // TakePictureStress
  853. //
  854. HRESULT TakePictureStress()
  855. {
  856. HRESULT hr = S_OK;
  857. INT_PTR iReturn = 0;
  858. //
  859. // Ask user how many threads to use and how many
  860. // pictures each thread should take.
  861. //
  862. LOCAL_GVAR.iNumThreads = 0;
  863. LOCAL_GVAR.uiNumImagesPerThread = 0;
  864. iReturn = DialogBox(APP_GVAR.hInstance,
  865. MAKEINTRESOURCE(IDD_STRESSDLG),
  866. APP_GVAR.hwndMainDlg,
  867. StressDlgProc);
  868. if (iReturn == IDOK)
  869. {
  870. SetDlgItemInt(APP_GVAR.hwndMainDlg, IDC_EDIT_NUM_STRESS_THREADS,
  871. LOCAL_GVAR.iNumThreads, FALSE);
  872. UINT uiNumThreads = (UINT) LOCAL_GVAR.iNumThreads;
  873. for (UINT i = 0; (i < uiNumThreads) && (hr == S_OK); i++)
  874. {
  875. ThreadArgs_t *pArgs = new ThreadArgs_t;
  876. if (pArgs)
  877. {
  878. DWORD dwThreadID = 0;
  879. ZeroMemory(pArgs, sizeof(ThreadArgs_t));
  880. pArgs->uiNumPicturesToTake = LOCAL_GVAR.uiNumImagesPerThread;
  881. pArgs->uiThreadSleepTime = (rand() % 100) + 25; // 25 - 125 ms sleeptime.
  882. CreateThread(NULL,
  883. 0,
  884. TakePictureThreadProc,
  885. (void*) pArgs,
  886. 0,
  887. &dwThreadID);
  888. }
  889. else
  890. {
  891. hr = E_OUTOFMEMORY;
  892. }
  893. }
  894. }
  895. return hr;
  896. }
  897. ///////////////////////////////
  898. // StressDlgProc
  899. //
  900. // Mesage handler for Stress Dialog Box
  901. //
  902. INT_PTR CALLBACK StressDlgProc(HWND hDlg,
  903. UINT message,
  904. WPARAM wParam,
  905. LPARAM lParam)
  906. {
  907. switch (message)
  908. {
  909. case WM_INITDIALOG:
  910. return TRUE;
  911. break;
  912. case WM_COMMAND:
  913. if (LOWORD(wParam) == IDOK)
  914. {
  915. BOOL bTranslated = TRUE;
  916. LOCAL_GVAR.iNumThreads = GetDlgItemInt(hDlg,
  917. IDC_EDIT_NUM_THREADS,
  918. &bTranslated,
  919. FALSE);
  920. LOCAL_GVAR.uiNumImagesPerThread = GetDlgItemInt(hDlg,
  921. IDC_EDIT_NUM_IMAGES_PER_THREAD,
  922. &bTranslated,
  923. FALSE);
  924. EndDialog(hDlg, LOWORD(wParam));
  925. return TRUE;
  926. }
  927. else if (LOWORD(wParam) == IDCANCEL)
  928. {
  929. EndDialog(hDlg, LOWORD(wParam));
  930. return TRUE;
  931. }
  932. break;
  933. }
  934. return FALSE;
  935. }
  936. ///////////////////////////////
  937. // TakePictureMultiple
  938. //
  939. HRESULT TakePictureMultiple()
  940. {
  941. HRESULT hr = S_OK;
  942. INT_PTR iReturn = 0;
  943. //
  944. // Ask user how many threads to use and how many
  945. // pictures each thread should take.
  946. //
  947. LOCAL_GVAR.iNumThreads = 0;
  948. LOCAL_GVAR.uiNumImagesPerThread = 0;
  949. iReturn = DialogBox(APP_GVAR.hInstance,
  950. MAKEINTRESOURCE(IDD_DIALOG_TAKE_PICTURE_MULTIPLE),
  951. APP_GVAR.hwndMainDlg,
  952. MultipleDlgProc);
  953. if (iReturn == IDOK)
  954. {
  955. SetDlgItemInt(APP_GVAR.hwndMainDlg, IDC_EDIT_NUM_STRESS_THREADS,
  956. 1, FALSE);
  957. //
  958. // uiNumThreads should be 1.
  959. //
  960. UINT uiNumThreads = 1;
  961. for (UINT i = 0; i < uiNumThreads; i++)
  962. {
  963. ThreadArgs_t *pArgs = new ThreadArgs_t;
  964. if (pArgs)
  965. {
  966. ZeroMemory(pArgs, sizeof(ThreadArgs_t));
  967. pArgs->uiNumPicturesToTake = LOCAL_GVAR.uiNumImagesPerThread;
  968. pArgs->uiThreadSleepTime = LOCAL_GVAR.uiTakePictureInterval;
  969. DWORD dwThreadID = 0;
  970. CreateThread(NULL,
  971. 0,
  972. TakePictureThreadProc,
  973. (void*) pArgs,
  974. 0,
  975. &dwThreadID);
  976. }
  977. }
  978. }
  979. return hr;
  980. }
  981. ///////////////////////////////
  982. // MultipleDlgProc
  983. //
  984. // Mesage handler for Stress Dialog Box
  985. //
  986. INT_PTR CALLBACK MultipleDlgProc(HWND hDlg,
  987. UINT message,
  988. WPARAM wParam,
  989. LPARAM lParam)
  990. {
  991. switch (message)
  992. {
  993. case WM_INITDIALOG:
  994. return TRUE;
  995. break;
  996. case WM_COMMAND:
  997. if (LOWORD(wParam) == IDOK)
  998. {
  999. BOOL bTranslated = TRUE;
  1000. LOCAL_GVAR.iNumThreads = 1;
  1001. LOCAL_GVAR.uiNumImagesPerThread = GetDlgItemInt(hDlg,
  1002. IDC_EDIT_NUM_PICTURES_TO_TAKE,
  1003. &bTranslated,
  1004. FALSE);
  1005. LOCAL_GVAR.uiTakePictureInterval = GetDlgItemInt(hDlg,
  1006. IDC_EDIT_TAKE_PICTURE_FREQUENCY,
  1007. &bTranslated,
  1008. FALSE);
  1009. EndDialog(hDlg, LOWORD(wParam));
  1010. return TRUE;
  1011. }
  1012. else if (LOWORD(wParam) == IDCANCEL)
  1013. {
  1014. EndDialog(hDlg, LOWORD(wParam));
  1015. return TRUE;
  1016. }
  1017. break;
  1018. }
  1019. return FALSE;
  1020. }
  1021. ///////////////////////////////
  1022. // TakePictureThreadProc
  1023. //
  1024. DWORD WINAPI TakePictureThreadProc(void *pArgs)
  1025. {
  1026. HRESULT hr = S_OK;
  1027. BOOL bDone = FALSE;
  1028. ThreadArgs_t *pThreadArgs = (ThreadArgs_t*) pArgs;
  1029. if (pThreadArgs == NULL)
  1030. {
  1031. return E_POINTER;
  1032. }
  1033. UINT uiNumPicturesToTake = pThreadArgs->uiNumPicturesToTake;
  1034. UINT uiSleepTime = pThreadArgs->uiThreadSleepTime;
  1035. UINT uiNumPicturesTaken = 0;
  1036. delete pThreadArgs;
  1037. pThreadArgs = NULL;
  1038. while (!bDone)
  1039. {
  1040. if ((LOCAL_GVAR.pWiaVideo == NULL) ||
  1041. (LOCAL_GVAR.bExitThreads == TRUE))
  1042. {
  1043. bDone = TRUE;
  1044. }
  1045. if (!bDone)
  1046. {
  1047. hr = TakePicture(FALSE);
  1048. if (hr != S_OK)
  1049. {
  1050. bDone = TRUE;
  1051. }
  1052. Sleep(uiSleepTime);
  1053. ++uiNumPicturesTaken;
  1054. if (uiNumPicturesTaken >= uiNumPicturesToTake)
  1055. {
  1056. bDone = TRUE;
  1057. }
  1058. }
  1059. }
  1060. InterlockedDecrement((LONG*) &LOCAL_GVAR.iNumThreads);
  1061. SetDlgItemInt(APP_GVAR.hwndMainDlg, IDC_EDIT_NUM_STRESS_THREADS,
  1062. LOCAL_GVAR.iNumThreads, FALSE);
  1063. return 0;
  1064. }
  1065. ///////////////////////////////
  1066. // GetDeviceProperty
  1067. //
  1068. // Static Fn
  1069. //
  1070. BOOL GetDeviceProperty(IPropertyBag *pPropertyBag,
  1071. LPCWSTR pwszProperty,
  1072. TCHAR *pszProperty,
  1073. DWORD cchProperty)
  1074. {
  1075. HRESULT hr = S_OK;
  1076. VARIANT VarName;
  1077. if ((pPropertyBag == NULL) ||
  1078. (pwszProperty == NULL) ||
  1079. (pszProperty == NULL))
  1080. {
  1081. hr = E_POINTER;
  1082. }
  1083. if (SUCCEEDED(hr))
  1084. {
  1085. VariantInit(&VarName);
  1086. VarName.vt = VT_BSTR;
  1087. hr = pPropertyBag->Read(pwszProperty, &VarName, 0);
  1088. }
  1089. if (SUCCEEDED(hr))
  1090. {
  1091. hr = AppUtil_ConvertToTCHAR(VarName.bstrVal,
  1092. pszProperty,
  1093. cchProperty);
  1094. VariantClear(&VarName);
  1095. }
  1096. return hr;
  1097. }