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.

2613 lines
80 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) CORPYRIGHT MICROSOFT CORPORATION, 1999 - 2000
  4. *
  5. * TITLE: videodlg.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: RickTu
  10. *
  11. * DATE: 10/14/99
  12. *
  13. * DESCRIPTION: Implementation of DialogProc for video capture common dialog
  14. *
  15. *****************************************************************************/
  16. #include <precomp.h>
  17. #pragma hdrstop
  18. #include "wiacsh.h"
  19. #include "modlock.h"
  20. #include "wiadevdp.h"
  21. //
  22. // Help IDs
  23. //
  24. static const DWORD g_HelpIDs[] =
  25. {
  26. IDC_VIDDLG_BIG_TITLE, -1,
  27. IDC_VIDDLG_LITTLE_TITLE, -1,
  28. IDC_VIDDLG_PREVIEW, IDH_WIA_VIDEO,
  29. IDC_VIDDLG_THUMBNAILLIST, IDH_WIA_CAPTURED_IMAGES,
  30. IDC_VIDDLG_CAPTURE, IDH_WIA_CAPTURE,
  31. IDOK, IDH_WIA_VIDEO_GET_PICTURE,
  32. IDCANCEL, IDH_CANCEL,
  33. 0, 0
  34. };
  35. #define IDC_SIZEBOX 1113
  36. //
  37. // If the callee doesn't return this value, we delete the message data ourselves.
  38. //
  39. #ifndef HANDLED_THREAD_MESSAGE
  40. #define HANDLED_THREAD_MESSAGE 2032
  41. #endif
  42. // Thumbnail whitespace: the space in between images and their selection rectangles
  43. // CThese values were discovered by trail and error. For instance, if you reduce
  44. // c_nAdditionalMarginY to 20, you get really bizarre spacing problems in the list view
  45. // in vertical mode. These values could become invalid in future versions of the listview.
  46. static const int c_nAdditionalMarginX = 10;
  47. static const int c_nAdditionalMarginY = 6;
  48. static int c_nMinThumbnailWidth = 90;
  49. static int c_nMinThumbnailHeight = 90;
  50. static int c_nMaxThumbnailWidth = 120;
  51. static int c_nMaxThumbnailHeight = 120;
  52. //
  53. // Map of background thread messages
  54. //
  55. static CThreadMessageMap g_MsgMap[] =
  56. {
  57. { TQ_DESTROY, CVideoCaptureDialog::OnThreadDestroy},
  58. { TQ_GETTHUMBNAIL, CVideoCaptureDialog::OnGetThumbnail},
  59. { 0, NULL}
  60. };
  61. class CGlobalInterfaceTableThreadMessage : public CNotifyThreadMessage
  62. {
  63. private:
  64. DWORD m_dwGlobalInterfaceTableCookie;
  65. private:
  66. // No implementation
  67. CGlobalInterfaceTableThreadMessage(void);
  68. CGlobalInterfaceTableThreadMessage &operator=( const CGlobalInterfaceTableThreadMessage & );
  69. CGlobalInterfaceTableThreadMessage( const CGlobalInterfaceTableThreadMessage & );
  70. public:
  71. CGlobalInterfaceTableThreadMessage( int nMessage, HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie )
  72. : CNotifyThreadMessage( nMessage, hWndNotify ),
  73. m_dwGlobalInterfaceTableCookie(dwGlobalInterfaceTableCookie)
  74. {
  75. }
  76. DWORD GlobalInterfaceTableCookie(void) const
  77. {
  78. return(m_dwGlobalInterfaceTableCookie);
  79. }
  80. };
  81. class CThumbnailThreadMessage : public CGlobalInterfaceTableThreadMessage
  82. {
  83. private:
  84. SIZE m_sizeThumb;
  85. private:
  86. // No implementation
  87. CThumbnailThreadMessage(void);
  88. CThumbnailThreadMessage &operator=( const CThumbnailThreadMessage & );
  89. CThumbnailThreadMessage( const CThumbnailThreadMessage & );
  90. public:
  91. CThumbnailThreadMessage( HWND hWndNotify, DWORD dwGlobalInterfaceTableCookie, const SIZE &sizeThumb )
  92. : CGlobalInterfaceTableThreadMessage( TQ_GETTHUMBNAIL, hWndNotify, dwGlobalInterfaceTableCookie ),
  93. m_sizeThumb(sizeThumb)
  94. {
  95. }
  96. const SIZE &ThumbSize(void) const
  97. {
  98. return(m_sizeThumb);
  99. }
  100. };
  101. //
  102. // Avoids unnecessary state changes
  103. //
  104. static inline VOID MyEnableWindow( HWND hWnd, BOOL bEnable )
  105. {
  106. if (bEnable && !IsWindowEnabled(hWnd))
  107. {
  108. EnableWindow(hWnd,TRUE);
  109. }
  110. else if (!bEnable && IsWindowEnabled(hWnd))
  111. {
  112. EnableWindow(hWnd,FALSE);
  113. }
  114. }
  115. /*****************************************************************************
  116. CVideoCaptureDialog constructor
  117. We don't have a destructor
  118. *****************************************************************************/
  119. CVideoCaptureDialog::CVideoCaptureDialog( HWND hWnd )
  120. : m_hWnd(hWnd),
  121. m_bFirstTime(true),
  122. m_hBigFont(NULL),
  123. m_nListViewWidth(0),
  124. m_hIconLarge(NULL),
  125. m_hIconSmall(NULL),
  126. m_hBackgroundThread(NULL),
  127. m_nDialogMode(0),
  128. m_hAccelTable(NULL),
  129. m_nParentFolderImageListIndex(0),
  130. m_pThreadMessageQueue(NULL)
  131. {
  132. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::CVideoCaptureDialog")));
  133. m_pThreadMessageQueue = new CThreadMessageQueue;
  134. if (m_pThreadMessageQueue)
  135. {
  136. //
  137. // Note that CBackgroundThread takes ownership of m_pThreadMessageQueue, and it doesn't have to be deleted in this thread
  138. //
  139. m_hBackgroundThread = CBackgroundThread::Create( m_pThreadMessageQueue, g_MsgMap, m_CancelEvent.Event(), g_hInstance );
  140. }
  141. m_CurrentAspectRatio.cx = 4;
  142. m_CurrentAspectRatio.cy = 3;
  143. m_sizeThumbnails.cx = c_nMaxThumbnailWidth;
  144. m_sizeThumbnails.cy = c_nMaxThumbnailHeight;
  145. WIA_ASSERT(m_hBackgroundThread != NULL);
  146. }
  147. /*****************************************************************************
  148. CVideoCaptureDialog::OnInitDialog
  149. Handle WM_INITIDIALOG
  150. *****************************************************************************/
  151. LRESULT CVideoCaptureDialog::OnInitDialog( WPARAM, LPARAM lParam )
  152. {
  153. WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::OnInitDialog"));
  154. HRESULT hr;
  155. //
  156. // Make sure the background queue was successfully created
  157. //
  158. if (!m_pThreadMessageQueue)
  159. {
  160. WIA_ERROR((TEXT("VIDEODLG: unable to start background queue")));
  161. EndDialog( m_hWnd, E_OUTOFMEMORY );
  162. return(0);
  163. }
  164. //
  165. // Save incoming data
  166. //
  167. m_pDeviceDialogData = (PDEVICEDIALOGDATA)lParam;
  168. //
  169. // Make sure we have valid arguments
  170. //
  171. if (!m_pDeviceDialogData)
  172. {
  173. WIA_ERROR((TEXT("VIDEODLG: Invalid paramater: PDEVICEDIALOGDATA")));
  174. EndDialog( m_hWnd, E_INVALIDARG );
  175. return(0);
  176. }
  177. //
  178. // Initialialize our return stuff
  179. //
  180. if (m_pDeviceDialogData)
  181. {
  182. m_pDeviceDialogData->lItemCount = 0;
  183. m_pDeviceDialogData->ppWiaItems = NULL;
  184. }
  185. //
  186. // Make sure we have a valid device
  187. //
  188. if (!m_pDeviceDialogData->pIWiaItemRoot)
  189. {
  190. WIA_ERROR((TEXT("VIDEODLG: Invalid paramaters: pIWiaItem")));
  191. EndDialog( m_hWnd, E_INVALIDARG );
  192. return(0);
  193. }
  194. //
  195. // Get deviceID for this device
  196. //
  197. PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_DEV_ID,m_strwDeviceId);
  198. //
  199. // Register for device disconnected, item creation and deletion events...
  200. //
  201. hr = CoCreateInstance( CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (LPVOID *)&m_pDevMgr );
  202. WIA_CHECK_HR(hr,"CoCreateInstance( WiaDevMgr )");
  203. if (SUCCEEDED(hr) && m_pDevMgr)
  204. {
  205. CVideoCallback *pVC = new CVideoCallback();
  206. if (pVC)
  207. {
  208. hr = pVC->Initialize( m_hWnd );
  209. WIA_CHECK_HR(hr,"pVC->Initialize()");
  210. if (SUCCEEDED(hr))
  211. {
  212. CComPtr<IWiaEventCallback> pWiaEventCallback;
  213. hr = pVC->QueryInterface( IID_IWiaEventCallback,
  214. (void**)&pWiaEventCallback
  215. );
  216. WIA_CHECK_HR(hr,"pVC->QI( IID_IWiaEventCallback )");
  217. if (SUCCEEDED(hr) && pWiaEventCallback)
  218. {
  219. CSimpleBStr bstr( m_strwDeviceId );
  220. hr = m_pDevMgr->RegisterEventCallbackInterface( WIA_REGISTER_EVENT_CALLBACK,
  221. bstr,
  222. &WIA_EVENT_DEVICE_DISCONNECTED,
  223. pWiaEventCallback,
  224. &m_pDisconnectedCallback
  225. );
  226. WIA_CHECK_HR(hr,"RegisterEvent( DEVICE_DISCONNECTED )");
  227. hr = m_pDevMgr->RegisterEventCallbackInterface( WIA_REGISTER_EVENT_CALLBACK,
  228. bstr,
  229. &WIA_EVENT_ITEM_DELETED,
  230. pWiaEventCallback,
  231. &m_pCreateCallback
  232. );
  233. WIA_CHECK_HR(hr,"RegisterEvent( ITEM_DELETE )");
  234. hr = m_pDevMgr->RegisterEventCallbackInterface( WIA_REGISTER_EVENT_CALLBACK,
  235. bstr,
  236. &WIA_EVENT_ITEM_CREATED,
  237. pWiaEventCallback,
  238. &m_pDeleteCallback
  239. );
  240. WIA_CHECK_HR(hr,"RegisterEvent( ITEM_CREATED )");
  241. }
  242. else
  243. {
  244. WIA_ERROR((TEXT("Either QI failed or pWiaEventCallback is NULL!")));
  245. }
  246. }
  247. pVC->Release();
  248. }
  249. }
  250. if (SUCCEEDED(hr) )
  251. {
  252. // Create the WiaVideo object
  253. hr = CoCreateInstance(CLSID_WiaVideo, NULL, CLSCTX_INPROC_SERVER,
  254. IID_IWiaVideo, (LPVOID *)&m_pWiaVideo);
  255. WIA_CHECK_HR(hr,"CoCreateInstance( WiaVideo )");
  256. }
  257. //
  258. // Prevent multiple selection
  259. //
  260. if (m_pDeviceDialogData->dwFlags & WIA_DEVICE_DIALOG_SINGLE_IMAGE)
  261. {
  262. LONG_PTR lStyle = GetWindowLongPtr( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), GWL_STYLE );
  263. SetWindowLongPtr( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), GWL_STYLE, lStyle | LVS_SINGLESEL );
  264. m_nDialogMode = SINGLESEL_MODE;
  265. //
  266. // Hide the "Select All" button
  267. //
  268. ShowWindow( GetDlgItem( m_hWnd, IDC_VIDDLG_SELECTALL ), SW_HIDE );
  269. //
  270. // Change text accordingly
  271. //
  272. CSimpleString( IDS_VIDDLG_TITLE_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_VIDDLG_BIG_TITLE ) );
  273. CSimpleString( IDS_VIDDLG_SUBTITLE_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_VIDDLG_LITTLE_TITLE ) );
  274. CSimpleString( IDS_VIDDLG_OK_SINGLE_SEL, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDOK ) );
  275. }
  276. else
  277. {
  278. m_nDialogMode = MULTISEL_MODE;
  279. }
  280. //
  281. // Make the lovely font
  282. //
  283. m_hBigFont = WiaUiUtil::CreateFontWithPointSizeFromWindow( GetDlgItem(m_hWnd,IDC_VIDDLG_BIG_TITLE), 14, false, false );
  284. if (m_hBigFont)
  285. {
  286. SendDlgItemMessage( m_hWnd,
  287. IDC_VIDDLG_BIG_TITLE,
  288. WM_SETFONT,
  289. reinterpret_cast<WPARAM>(m_hBigFont),
  290. MAKELPARAM(TRUE,0)
  291. );
  292. }
  293. //
  294. // Save the minimum size of the dialog
  295. //
  296. RECT rcWindow;
  297. GetWindowRect( m_hWnd, &rcWindow );
  298. m_sizeMinimumWindow.cx = rcWindow.right - rcWindow.left;
  299. m_sizeMinimumWindow.cy = rcWindow.bottom - rcWindow.top;
  300. //
  301. // Create the sizing control
  302. //
  303. HWND hWndSizingControl = CreateWindowEx( 0, TEXT("scrollbar"), TEXT(""),
  304. WS_CHILD|WS_VISIBLE|SBS_SIZEGRIP|WS_CLIPSIBLINGS|SBS_SIZEBOXBOTTOMRIGHTALIGN|SBS_BOTTOMALIGN|WS_GROUP,
  305. CSimpleRect(m_hWnd).Width()-GetSystemMetrics(SM_CXVSCROLL),
  306. CSimpleRect(m_hWnd).Height()-GetSystemMetrics(SM_CYHSCROLL),
  307. GetSystemMetrics(SM_CXVSCROLL),
  308. GetSystemMetrics(SM_CYHSCROLL),
  309. m_hWnd, reinterpret_cast<HMENU>(IDC_SIZEBOX),
  310. g_hInstance, NULL );
  311. if (!hWndSizingControl)
  312. {
  313. WIA_ERROR((TEXT("CreateWindowEx( sizing control ) failed!")));
  314. }
  315. //
  316. // Reposition all the controls
  317. //
  318. ResizeAll();
  319. //
  320. // Center the window over its parent
  321. //
  322. WiaUiUtil::CenterWindow( m_hWnd, GetParent(m_hWnd) );
  323. //
  324. // Get the device icons and set the window icons
  325. //
  326. CSimpleStringWide strwDeviceId, strwClassId;
  327. LONG nDeviceType;
  328. if (PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_UI_CLSID,strwClassId) &&
  329. PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_DEV_ID,strwDeviceId) &&
  330. PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,WIA_DIP_DEV_TYPE,nDeviceType))
  331. {
  332. if (SUCCEEDED(WiaUiExtensionHelper::GetDeviceIcons( CSimpleBStr(strwClassId), nDeviceType, &m_hIconSmall, &m_hIconLarge )))
  333. {
  334. if (m_hIconSmall)
  335. {
  336. SendMessage( m_hWnd, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(m_hIconSmall) );
  337. }
  338. if (m_hIconLarge)
  339. {
  340. SendMessage( m_hWnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(m_hIconLarge) );
  341. }
  342. }
  343. }
  344. SetForegroundWindow(m_hWnd);
  345. return(0);
  346. }
  347. /*****************************************************************************
  348. CVideoCaptureDialog::ResizeAll
  349. Resizes and repositions all the controls when the dialog size
  350. changes.
  351. *****************************************************************************/
  352. VOID CVideoCaptureDialog::ResizeAll(VOID)
  353. {
  354. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::ResizeAll")));
  355. CSimpleRect rcClient(m_hWnd);
  356. CMoveWindow mw;
  357. CDialogUnits dialogUnits(m_hWnd);
  358. //WIA_TRACE((TEXT("rcClient is l(%d) t(%d) r(%d) b(%d)"),rcClient.left, rcClient.top, rcClient.right, rcClient.bottom));
  359. //WIA_TRACE((TEXT("rcClient is w(%d) h(%d)"),rcClient.Width(),rcClient.Height()));
  360. //WIA_TRACE((TEXT("dialogUnits.StandardMargin is cx(%d) cy(%d)"),dialogUnits.StandardMargin().cx,dialogUnits.StandardMargin().cy));
  361. //WIA_TRACE((TEXT("dialogUnits.StandardButtonMargin is cx(%d) cy(%d)"),dialogUnits.StandardButtonMargin().cx,dialogUnits.StandardButtonMargin().cy));
  362. //
  363. // Resize the big title
  364. //
  365. mw.Size( GetDlgItem( m_hWnd, IDC_VIDDLG_BIG_TITLE ),
  366. rcClient.Width() - dialogUnits.StandardMargin().cx * 2,
  367. 0,
  368. CMoveWindow::NO_SIZEY );
  369. //
  370. // Resize the subtitle
  371. //
  372. mw.Size( GetDlgItem( m_hWnd, IDC_VIDDLG_LITTLE_TITLE ),
  373. rcClient.Width() - dialogUnits.StandardMargin().cx * 2,
  374. 0,
  375. CMoveWindow::NO_SIZEY );
  376. CSimpleRect rcOK( GetDlgItem( m_hWnd, IDOK ), CSimpleRect::WindowRect );
  377. CSimpleRect rcCancel( GetDlgItem( m_hWnd, IDCANCEL ), CSimpleRect::WindowRect );
  378. //WIA_TRACE((TEXT("rcOK is l(%d) t(%d) r(%d) b(%d)"),rcOK.left, rcOK.top, rcOK.right, rcOK.bottom));
  379. //WIA_TRACE((TEXT("rcOK is w(%d) h(%d)"),rcOK.Width(), rcOK.Height()));
  380. //WIA_TRACE((TEXT("rcCancel is l(%d) t(%d) r(%d) b(%d)"),rcCancel.left, rcCancel.top, rcCancel.right, rcCancel.bottom));
  381. //WIA_TRACE((TEXT("rcCancel is w(%d) h(%d)"),rcCancel.Width(), rcCancel.Height()));
  382. //
  383. // Move the OK button
  384. //
  385. LONG x,y;
  386. x = rcClient.Width() - dialogUnits.StandardMargin().cx - dialogUnits.StandardButtonMargin().cx - rcCancel.Width() - rcOK.Width();
  387. y = rcClient.Height() - dialogUnits.StandardMargin().cy - rcOK.Height();
  388. //WIA_TRACE((TEXT("Moving IDOK to x(%x) y(%d)"),x,y));
  389. mw.Move( GetDlgItem( m_hWnd, IDOK ), x, y, 0 );
  390. INT nTopOfOK = y;
  391. INT nBottomOfSub = CSimpleRect( GetDlgItem(m_hWnd,IDC_VIDDLG_LITTLE_TITLE), CSimpleRect::WindowRect ).ScreenToClient(m_hWnd).bottom;
  392. //
  393. // Move the cancel button
  394. //
  395. x = rcClient.Width() - dialogUnits.StandardMargin().cx - rcCancel.Width();
  396. y = rcClient.Height() - dialogUnits.StandardMargin().cy - rcCancel.Height();
  397. //WIA_TRACE((TEXT("Moving IDCANCEL to x(%x) y(%d)"),x,y));
  398. mw.Move( GetDlgItem( m_hWnd, IDCANCEL ), x, y, 0 );
  399. //
  400. // Move the resizing handle
  401. //
  402. x = rcClient.Width() - GetSystemMetrics(SM_CXVSCROLL);
  403. y = rcClient.Height() - GetSystemMetrics(SM_CYHSCROLL);
  404. //WIA_TRACE((TEXT("Moving IDC_SIZEBOX to x(%x) y(%d)"),x,y));
  405. mw.Move( GetDlgItem( m_hWnd, IDC_SIZEBOX ), x, y );
  406. //
  407. // Resize the preview window & move the capture button
  408. //
  409. CSimpleRect rcSubTitle( GetDlgItem( m_hWnd, IDC_VIDDLG_LITTLE_TITLE ), CSimpleRect::ClientRect );
  410. CSimpleRect rcCapture( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ), CSimpleRect::ClientRect );
  411. CSimpleRect rcSelectAll( GetDlgItem( m_hWnd, IDC_VIDDLG_SELECTALL ), CSimpleRect::ClientRect );
  412. //WIA_TRACE((TEXT("rcSubTitle is l(%d) t(%d) r(%d) b(%d)"),rcSubTitle.left, rcSubTitle.top, rcSubTitle.right, rcSubTitle.bottom));
  413. //WIA_TRACE((TEXT("rcSubTitle is w(%d) h(%d)"),rcSubTitle.Width(), rcSubTitle.Height()));
  414. //WIA_TRACE((TEXT("rcCapture is l(%d) t(%d) r(%d) b(%d)"),rcCapture.left, rcCapture.top, rcCapture.right, rcCapture.bottom));
  415. //WIA_TRACE((TEXT("rcCapture is w(%d) h(%d)"),rcCapture.Width(), rcCapture.Height()));
  416. //WIA_TRACE((TEXT("rcSelectAll is l(%d) t(%d) r(%d) b(%d)"),rcSelectAll.left, rcSelectAll.top, rcSelectAll.right, rcSelectAll.bottom));
  417. //WIA_TRACE((TEXT("rcSelectAll is w(%d) h(%d)"),rcSelectAll.Width(), rcSelectAll.Height()));
  418. //WIA_TRACE((TEXT("nTopOfOK is (%d)"),nTopOfOK));
  419. //WIA_TRACE((TEXT("nBottomOfSub is (%d)"),nBottomOfSub));
  420. CSimpleRect rcAvailableArea(
  421. dialogUnits.StandardMargin().cx,
  422. nBottomOfSub + dialogUnits.StandardMargin().cy,
  423. rcClient.right - dialogUnits.StandardMargin().cx,
  424. nTopOfOK - (dialogUnits.StandardButtonMargin().cy * 2)
  425. );
  426. //WIA_TRACE((TEXT("rcAvailableArea is l(%d) t(%d) r(%d) b(%d)"),rcAvailableArea.left, rcAvailableArea.top, rcAvailableArea.right, rcAvailableArea.bottom));
  427. //WIA_TRACE((TEXT("rcAvailableArea is w(%d) h(%d)"),rcAvailableArea.Width(), rcAvailableArea.Height()));
  428. INT full_width = rcAvailableArea.right - rcAvailableArea.left;
  429. INT preview_width = (full_width * 53) / 100;
  430. //WIA_TRACE((TEXT("full_width is (%d)"),full_width));
  431. //WIA_TRACE((TEXT("preview_width is (%d)"),preview_width));
  432. //WIA_TRACE((TEXT("SizeMoving IDC_VIDDLG_PREVIEW to x(%d) y(%d) w(%d) h(%d)"),rcAvailableArea.left,rcAvailableArea.top,preview_width,rcAvailableArea.Height() - rcCapture.Height() - dialogUnits.StandardButtonMargin().cy));
  433. mw.SizeMove( GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW ),
  434. rcAvailableArea.left,
  435. rcAvailableArea.top,
  436. preview_width,
  437. rcAvailableArea.Height() - rcCapture.Height() - dialogUnits.StandardButtonMargin().cy
  438. );
  439. INT offset = (preview_width - rcCapture.Width()) / 2;
  440. //WIA_TRACE((TEXT("offset is (%d)"),offset));
  441. //WIA_TRACE((TEXT("Moving IDC_VIDDLG_CAPTURE to x(%d) y(%d)"),rcAvailableArea.left + offset,rcAvailableArea.bottom - rcCapture.Height()));
  442. mw.Move( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ),
  443. rcAvailableArea.left + offset,
  444. rcAvailableArea.bottom - rcCapture.Height(),
  445. 0 );
  446. //
  447. // Resize the thumbnail list & move the selectall button
  448. //
  449. INT leftThumbEdge = rcAvailableArea.left + preview_width + dialogUnits.StandardMargin().cx;
  450. //WIA_TRACE((TEXT("leftThumbEdge is (%d)"),leftThumbEdge));
  451. //WIA_TRACE((TEXT("SizeMoving IDC_VIDDLG_THUMBNAILLIST to x(%d) y(%d) w(%d) h(%d)"),leftThumbEdge,rcAvailableArea.top,rcAvailableArea.Width() - preview_width - dialogUnits.StandardMargin().cx,rcAvailableArea.Height() - rcSelectAll.Height() - dialogUnits.StandardButtonMargin().cy));
  452. mw.SizeMove( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ),
  453. leftThumbEdge,
  454. rcAvailableArea.top,
  455. rcAvailableArea.Width() - preview_width - dialogUnits.StandardMargin().cx,
  456. rcAvailableArea.Height() - rcSelectAll.Height() - dialogUnits.StandardButtonMargin().cy
  457. );
  458. offset = ((rcAvailableArea.right - leftThumbEdge - rcSelectAll.Width()) / 2);
  459. //WIA_TRACE((TEXT("offset(new) is (%d)"),offset));
  460. //WIA_TRACE((TEXT("Moving IDC_VIDDLG_SELECTALL to x(%d) y(%d)"),leftThumbEdge + offset,rcAvailableArea.bottom - rcSelectAll.Height()));
  461. mw.Move( GetDlgItem( m_hWnd, IDC_VIDDLG_SELECTALL ),
  462. leftThumbEdge + offset,
  463. rcAvailableArea.bottom - rcSelectAll.Height(),
  464. 0 );
  465. //
  466. // Explicitly apply the moves, because the toolbar frame doesn't get painted properly
  467. //
  468. mw.Apply();
  469. //
  470. // Update the dialog's background to remove any weird stuff left behind
  471. //
  472. InvalidateRect( m_hWnd, NULL, FALSE );
  473. UpdateWindow( m_hWnd );
  474. }
  475. /*****************************************************************************
  476. CVideoCaptureDialog::OnSize
  477. Handle WM_SIZE messages
  478. *****************************************************************************/
  479. LRESULT CVideoCaptureDialog::OnSize( WPARAM, LPARAM )
  480. {
  481. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnSize")));
  482. ResizeAll();
  483. //
  484. // Tell the video preview window to resize in within it's
  485. // container window as best it can.
  486. //
  487. if (m_pWiaVideo)
  488. {
  489. m_pWiaVideo->ResizeVideo(FALSE);
  490. }
  491. return(0);
  492. }
  493. /*****************************************************************************
  494. CVideoCaptureDialog::OnShow
  495. Handle WM_SHOW message
  496. *****************************************************************************/
  497. LRESULT CVideoCaptureDialog::OnShow( WPARAM, LPARAM )
  498. {
  499. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnShow")));
  500. if (m_bFirstTime)
  501. {
  502. PostMessage( m_hWnd, PWM_POSTINIT, 0, 0 );
  503. m_bFirstTime = false;
  504. }
  505. return(0);
  506. }
  507. /*****************************************************************************
  508. CVideoCameraDialog::OnGetMinMaxInfo
  509. Handle WM_GETMINMAXINFO
  510. *****************************************************************************/
  511. LRESULT CVideoCaptureDialog::OnGetMinMaxInfo( WPARAM, LPARAM lParam )
  512. {
  513. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnGetMinMaxInfo")));
  514. WIA_TRACE((TEXT("m_sizeMinimumWindow = %d,%d"),m_sizeMinimumWindow.cx,m_sizeMinimumWindow.cy));
  515. LPMINMAXINFO pMinMaxInfo = (LPMINMAXINFO)lParam;
  516. pMinMaxInfo->ptMinTrackSize.x = m_sizeMinimumWindow.cx;
  517. pMinMaxInfo->ptMinTrackSize.y = m_sizeMinimumWindow.cy;
  518. return(0);
  519. }
  520. /*****************************************************************************
  521. CVideoCameraDialog::OnDestroy
  522. Handle WM_DESTROY message and do cleanup
  523. *****************************************************************************/
  524. LRESULT CVideoCaptureDialog::OnDestroy( WPARAM, LPARAM )
  525. {
  526. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDestroy")));
  527. //
  528. // Unregister for events
  529. //
  530. m_pCreateCallback = NULL;
  531. m_pDeleteCallback = NULL;
  532. m_pDisconnectedCallback = NULL;
  533. //
  534. // Tell the background thread to destroy itself
  535. //
  536. m_pThreadMessageQueue->Enqueue( new CThreadMessage(TQ_DESTROY),CThreadMessageQueue::PriorityUrgent );
  537. //
  538. // Close the thread handle
  539. //
  540. CloseHandle( m_hBackgroundThread );
  541. if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot && m_pWiaVideo)
  542. {
  543. m_pWiaVideo->DestroyVideo();
  544. }
  545. //
  546. // Delete resources
  547. //
  548. if (m_hBigFont)
  549. {
  550. DeleteObject(m_hBigFont);
  551. m_hBigFont = NULL;
  552. }
  553. if (m_hImageList)
  554. {
  555. m_hImageList = NULL;
  556. }
  557. if (m_hAccelTable)
  558. {
  559. DestroyAcceleratorTable(m_hAccelTable);
  560. m_hAccelTable = NULL;
  561. }
  562. if (m_hIconLarge)
  563. {
  564. DestroyIcon(m_hIconLarge);
  565. m_hIconLarge = NULL;
  566. }
  567. if (m_hIconSmall)
  568. {
  569. DestroyIcon(m_hIconSmall);
  570. m_hIconSmall = NULL;
  571. }
  572. return(0);
  573. }
  574. /*****************************************************************************
  575. CVideoCaptureDialog::OnOK
  576. Handle when the user presses "Get Pictures"
  577. *****************************************************************************/
  578. VOID CVideoCaptureDialog::OnOK( WPARAM, LPARAM )
  579. {
  580. WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnOK")));
  581. HRESULT hr = S_OK;
  582. //
  583. // Start w/nothing to return
  584. //
  585. m_pDeviceDialogData->lItemCount = 0;
  586. m_pDeviceDialogData->ppWiaItems = NULL;
  587. //
  588. // Get the indicies of the items that are selected
  589. //
  590. CSimpleDynamicArray<int> aIndices;
  591. GetSelectionIndices( aIndices );
  592. //
  593. // Are there any items selected?
  594. //
  595. if (aIndices.Size())
  596. {
  597. //
  598. // Calculate the size of the buffer needed
  599. //
  600. INT nArraySizeInBytes = sizeof(IWiaItem*) * aIndices.Size();
  601. //
  602. // Alloc a buffer to hold the items
  603. //
  604. m_pDeviceDialogData->ppWiaItems = (IWiaItem**)CoTaskMemAlloc(nArraySizeInBytes);
  605. //
  606. // If we allocated a buffer, fill it up with the
  607. // items to return...
  608. //
  609. if (m_pDeviceDialogData->ppWiaItems)
  610. {
  611. INT i;
  612. ZeroMemory( m_pDeviceDialogData->ppWiaItems, nArraySizeInBytes );
  613. for (i=0;i<aIndices.Size();i++)
  614. {
  615. CCameraItem *pItem = GetListItemNode(aIndices[i]);
  616. if (pItem && pItem->Item())
  617. {
  618. m_pDeviceDialogData->ppWiaItems[i] = pItem->Item();
  619. m_pDeviceDialogData->ppWiaItems[i]->AddRef();
  620. }
  621. else
  622. {
  623. //
  624. // Somehow the list got corrupted
  625. //
  626. hr = E_UNEXPECTED;
  627. break;
  628. }
  629. }
  630. if (!SUCCEEDED(hr))
  631. {
  632. //
  633. // Clean up if we had a failure
  634. //
  635. for (i=0;i<aIndices.Size();i++)
  636. {
  637. if (m_pDeviceDialogData->ppWiaItems[i])
  638. {
  639. m_pDeviceDialogData->ppWiaItems[i]->Release();
  640. }
  641. }
  642. CoTaskMemFree( m_pDeviceDialogData->ppWiaItems );
  643. m_pDeviceDialogData->ppWiaItems = NULL;
  644. }
  645. else
  646. {
  647. m_pDeviceDialogData->lItemCount = aIndices.Size();
  648. }
  649. }
  650. else
  651. {
  652. //
  653. // Unable to alloc buffer
  654. //
  655. WIA_ERROR((TEXT("Couldn't allocate a buffer")));
  656. hr = E_OUTOFMEMORY;
  657. }
  658. }
  659. else
  660. {
  661. //
  662. // There aren't any items selected, so just return without
  663. // ending the dialog...
  664. //
  665. return;
  666. }
  667. EndDialog( m_hWnd, hr );
  668. }
  669. /*****************************************************************************
  670. CVideoCaptureDialog::OnCancel
  671. Handle when the user presses cancel.
  672. *****************************************************************************/
  673. VOID CVideoCaptureDialog::OnCancel( WPARAM, LPARAM )
  674. {
  675. WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnCancel")));
  676. EndDialog( m_hWnd, S_FALSE );
  677. }
  678. /*****************************************************************************
  679. CVideoCaptureDialog::OnSelectAll
  680. Handle when the user presses "Select All" button
  681. *****************************************************************************/
  682. VOID CVideoCaptureDialog::OnSelectAll( WPARAM, LPARAM )
  683. {
  684. WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnSelectAll")));
  685. LVITEM lvItem;
  686. lvItem.mask = LVIF_STATE;
  687. lvItem.iItem = 0;
  688. lvItem.state = LVIS_SELECTED;
  689. lvItem.stateMask = LVIS_SELECTED;
  690. SendMessage( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), LVM_SETITEMSTATE, -1, reinterpret_cast<LPARAM>(&lvItem) );
  691. }
  692. /*****************************************************************************
  693. CVideoCaptureDialog::AddItemToListView
  694. Adds a new IWiaItem to the list view...
  695. *****************************************************************************/
  696. BOOL CVideoCaptureDialog::AddItemToListView( IWiaItem * pItem )
  697. {
  698. WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::AddItemToListView")));
  699. if (!pItem)
  700. {
  701. WIA_ERROR((TEXT("pItem is NULL!")));
  702. return FALSE;
  703. }
  704. //
  705. // Add the new picture to our list
  706. //
  707. CCameraItem * pNewCameraItem = new CCameraItem( pItem );
  708. if (pNewCameraItem)
  709. {
  710. WIA_TRACE((TEXT("Attempting to add new item to tree")));
  711. m_CameraItemList.Add( NULL, pNewCameraItem );
  712. }
  713. else
  714. {
  715. WIA_ERROR((TEXT("Couldn't create a new pNewCameraItem")));
  716. }
  717. //
  718. // Create a thumbnail for the new item
  719. //
  720. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  721. if (hwndList && pNewCameraItem)
  722. {
  723. HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
  724. if (hImageList)
  725. {
  726. CVideoCaptureDialog::CreateThumbnails( pNewCameraItem,
  727. hImageList,
  728. FALSE
  729. );
  730. }
  731. else
  732. {
  733. WIA_ERROR((TEXT("Couldn't get hImageList to get new thumbnail")));
  734. }
  735. //
  736. // Update the listview with the new item
  737. //
  738. LVITEM lvItem;
  739. INT iItem = ListView_GetItemCount( hwndList ) + 1;
  740. ZeroMemory( &lvItem, sizeof(lvItem) );
  741. lvItem.iItem = iItem;
  742. lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
  743. lvItem.iImage = pNewCameraItem->ImageListIndex();
  744. lvItem.lParam = (LPARAM)pNewCameraItem;
  745. int nIndex = ListView_InsertItem( hwndList, &lvItem );
  746. //
  747. // Retrieve actual thumbnail
  748. //
  749. RequestThumbnails( pNewCameraItem );
  750. //
  751. // Select the new item
  752. //
  753. SetSelectedListItem( nIndex );
  754. //
  755. // Make sure the item is visible
  756. //
  757. ListView_EnsureVisible( hwndList, nIndex, FALSE );
  758. }
  759. return TRUE;
  760. }
  761. /*****************************************************************************
  762. CVideoCaptureDialog::OnCapture
  763. Handle when the user presses the "Capture" button
  764. *****************************************************************************/
  765. VOID CVideoCaptureDialog::OnCapture( WPARAM, LPARAM )
  766. {
  767. WIA_PUSHFUNCTION((TEXT("CVideoCameraDialog::OnCapture")));
  768. //
  769. // Disable capture button until we're done with this iteration
  770. //
  771. MyEnableWindow( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ), FALSE );
  772. //
  773. // Tell the video device to snap a picture
  774. //
  775. CComPtr<IWiaItem> pItem;
  776. if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot && m_pWiaVideo)
  777. {
  778. WIA_TRACE((TEXT("Telling WiaVideo to take a picture")));
  779. BSTR bstrNewImageFileName = NULL;
  780. //
  781. // Take the picture
  782. //
  783. HRESULT hr = m_pWiaVideo->TakePicture(&bstrNewImageFileName);
  784. WIA_CHECK_HR(hr,"m_pWiaVideo->TakePicture");
  785. if (hr == S_OK)
  786. {
  787. //
  788. // Succeeded in taking the picture, setting the LAST_PICTURE_TAKEN property
  789. // on the video driver to create a new item.
  790. //
  791. BOOL bSuccess = FALSE;
  792. PROPVARIANT pv;
  793. PropVariantInit(&pv);
  794. pv.vt = VT_BSTR;
  795. pv.bstrVal = bstrNewImageFileName;
  796. bSuccess = PropStorageHelpers::SetProperty(m_pDeviceDialogData->pIWiaItemRoot,
  797. WIA_DPV_LAST_PICTURE_TAKEN,
  798. pv);
  799. //
  800. // Note that this will free the bstrNewImageFileName returned to
  801. // us by WiaVideo
  802. //
  803. PropVariantClear(&pv);
  804. }
  805. }
  806. //
  807. // Re-Enable capture button now that we're done
  808. //
  809. MyEnableWindow( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ), TRUE );
  810. //
  811. // Make sure the focus is still on our control
  812. //
  813. SetFocus( GetDlgItem( m_hWnd, IDC_VIDDLG_CAPTURE ) );
  814. }
  815. /*****************************************************************************
  816. CVideoCaptureDialog::OnDblClickImageList
  817. Translate a dbl-click on a thumbnail in the listview into a click
  818. on the "Get Pictures" button.
  819. *****************************************************************************/
  820. LRESULT CVideoCaptureDialog::OnDblClkImageList( WPARAM, LPARAM )
  821. {
  822. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDblClkImageList")));
  823. SendMessage( m_hWnd, WM_COMMAND, MAKEWPARAM(IDOK,0), 0 );
  824. return 0;
  825. }
  826. /*****************************************************************************
  827. CVideoCaptureDialog::OnImageListItemChanged
  828. Sent whenever an item in the thumbnail list changes.
  829. *****************************************************************************/
  830. LRESULT CVideoCaptureDialog::OnImageListItemChanged( WPARAM, LPARAM )
  831. {
  832. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnImageListItemChanged")));
  833. HandleSelectionChange();
  834. return 0;
  835. }
  836. /*****************************************************************************
  837. CVideoCaptureDialog::OnImageListKeyDown
  838. Forward the keyboard messages within the listview appropriately.
  839. *****************************************************************************/
  840. LRESULT CVideoCaptureDialog::OnImageListKeyDown( WPARAM, LPARAM lParam )
  841. {
  842. LPNMLVKEYDOWN pnkd = reinterpret_cast<LPNMLVKEYDOWN>(lParam);
  843. if (pnkd)
  844. {
  845. if (VK_LEFT == pnkd->wVKey && (GetKeyState(VK_MENU) & 0x8000))
  846. {
  847. SendMessage( m_hWnd, PWM_CHANGETOPARENT, 0, 0 );
  848. }
  849. }
  850. return 0;
  851. }
  852. /*****************************************************************************
  853. CVideoCaptureDialog::OnNotify
  854. Handle WM_NOTIFY messages
  855. *****************************************************************************/
  856. LRESULT CVideoCaptureDialog::OnNotify( WPARAM wParam, LPARAM lParam )
  857. {
  858. SC_BEGIN_NOTIFY_MESSAGE_HANDLERS()
  859. {
  860. SC_HANDLE_NOTIFY_MESSAGE_CONTROL( NM_DBLCLK, IDC_VIDDLG_THUMBNAILLIST, OnDblClkImageList );
  861. SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_ITEMCHANGED, IDC_VIDDLG_THUMBNAILLIST, OnImageListItemChanged );
  862. SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_KEYDOWN, IDC_VIDDLG_THUMBNAILLIST, OnImageListKeyDown );
  863. }
  864. SC_END_NOTIFY_MESSAGE_HANDLERS();
  865. }
  866. /*****************************************************************************
  867. CVideoCaptureDialog::OnCommand
  868. Handle WM_COMMAND messages
  869. *****************************************************************************/
  870. LRESULT CVideoCaptureDialog::OnCommand( WPARAM wParam, LPARAM lParam )
  871. {
  872. SC_BEGIN_COMMAND_HANDLERS()
  873. {
  874. SC_HANDLE_COMMAND(IDOK, OnOK);
  875. SC_HANDLE_COMMAND(IDCANCEL, OnCancel);
  876. SC_HANDLE_COMMAND(IDC_VIDDLG_CAPTURE, OnCapture);
  877. SC_HANDLE_COMMAND(IDC_VIDDLG_SELECTALL, OnSelectAll);
  878. }
  879. SC_END_COMMAND_HANDLERS();
  880. }
  881. /*****************************************************************************
  882. CVideoCaptureDialog::OnGetThumbnail
  883. Called by background thread to get the thumbnail for a given item.
  884. *****************************************************************************/
  885. BOOL WINAPI CVideoCaptureDialog::OnGetThumbnail( CThreadMessage *pMsg )
  886. {
  887. WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::OnGetThumbnail"));
  888. HBITMAP hBmpThumbnail = NULL;
  889. CThumbnailThreadMessage *pThumbMsg = (CThumbnailThreadMessage *)(pMsg);
  890. if (pThumbMsg)
  891. {
  892. CComPtr<IGlobalInterfaceTable> pGlobalInterfaceTable;
  893. HRESULT hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable,
  894. NULL,
  895. CLSCTX_INPROC_SERVER,
  896. IID_IGlobalInterfaceTable,
  897. (void **)&pGlobalInterfaceTable);
  898. if (SUCCEEDED(hr) && pGlobalInterfaceTable)
  899. {
  900. CComPtr<IWiaItem> pIWiaItem;
  901. hr = pGlobalInterfaceTable->GetInterfaceFromGlobal(
  902. pThumbMsg->GlobalInterfaceTableCookie(),
  903. IID_IWiaItem,
  904. (void**)&pIWiaItem);
  905. if (SUCCEEDED(hr) && pIWiaItem)
  906. {
  907. CComPtr<IWiaPropertyStorage> pIWiaPropertyStorage;
  908. hr = pIWiaItem->QueryInterface( IID_IWiaPropertyStorage,
  909. (void**)&pIWiaPropertyStorage
  910. );
  911. if (SUCCEEDED(hr) && pIWiaPropertyStorage)
  912. {
  913. PROPVARIANT PropVar[3];
  914. PROPSPEC PropSpec[3];
  915. PropSpec[0].ulKind = PRSPEC_PROPID;
  916. PropSpec[0].propid = WIA_IPC_THUMB_WIDTH;
  917. PropSpec[1].ulKind = PRSPEC_PROPID;
  918. PropSpec[1].propid = WIA_IPC_THUMB_HEIGHT;
  919. PropSpec[2].ulKind = PRSPEC_PROPID;
  920. PropSpec[2].propid = WIA_IPC_THUMBNAIL;
  921. hr = pIWiaPropertyStorage->ReadMultiple(ARRAYSIZE(PropSpec),PropSpec,PropVar );
  922. if (SUCCEEDED(hr))
  923. {
  924. WIA_TRACE((TEXT("Attempting to get the thumbnail for GIT entry: %08X, %08X, %08X, %08X"),pThumbMsg->GlobalInterfaceTableCookie(),PropVar[0].vt,PropVar[1].vt,PropVar[2].vt));
  925. if ((PropVar[0].vt == VT_I4 || PropVar[0].vt == VT_UI4) &&
  926. (PropVar[1].vt == VT_I4 || PropVar[1].vt == VT_UI4) &&
  927. (PropVar[2].vt == (VT_UI1|VT_VECTOR)))
  928. {
  929. //
  930. // Calculate the actual amount of data to copy from the thumbnail bitmap.
  931. // We have to round up to the nearest DWORD boundary, so we align on Width * BYTES_PER_PIXEL
  932. //
  933. UINT nBitmapDataSize = WiaUiUtil::Align( PropVar[0].ulVal * 3, sizeof(DWORD) ) * PropVar[1].ulVal;
  934. if (nBitmapDataSize <= PropVar[2].caub.cElems)
  935. {
  936. BITMAPINFO bmi;
  937. bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  938. bmi.bmiHeader.biWidth = PropVar[0].ulVal;
  939. bmi.bmiHeader.biHeight = PropVar[1].ulVal;
  940. bmi.bmiHeader.biPlanes = 1;
  941. bmi.bmiHeader.biBitCount = 24;
  942. bmi.bmiHeader.biCompression = BI_RGB;
  943. bmi.bmiHeader.biSizeImage = 0;
  944. bmi.bmiHeader.biXPelsPerMeter = 0;
  945. bmi.bmiHeader.biYPelsPerMeter = 0;
  946. bmi.bmiHeader.biClrUsed = 0;
  947. bmi.bmiHeader.biClrImportant = 0;
  948. HDC hDC = GetDC(NULL);
  949. if (hDC)
  950. {
  951. PBYTE *pBits;
  952. HBITMAP hDibSection = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS, (PVOID*)&pBits, NULL, 0 );
  953. if (hDibSection)
  954. {
  955. CopyMemory( pBits, PropVar[2].caub.pElems, nBitmapDataSize );
  956. hr = ScaleImage( hDC, hDibSection, hBmpThumbnail, pThumbMsg->ThumbSize());
  957. if (SUCCEEDED(hr))
  958. {
  959. WIA_TRACE((TEXT("Sending this image to the notification window: %08X"),pThumbMsg->NotifyWindow()));
  960. }
  961. else
  962. {
  963. hBmpThumbnail = NULL;
  964. }
  965. DeleteObject(hDibSection);
  966. }
  967. ReleaseDC(NULL,hDC);
  968. }
  969. }
  970. }
  971. PropVariantClear(&PropVar[0]);
  972. PropVariantClear(&PropVar[1]);
  973. PropVariantClear(&PropVar[2]);
  974. }
  975. }
  976. }
  977. }
  978. }
  979. LRESULT lRes = SendMessage( pThumbMsg->NotifyWindow(), PWM_THUMBNAILSTATUS, (WPARAM)pThumbMsg->GlobalInterfaceTableCookie(), (LPARAM)hBmpThumbnail );
  980. if (HANDLED_THREAD_MESSAGE != lRes && hBmpThumbnail)
  981. {
  982. DeleteObject( hBmpThumbnail );
  983. }
  984. return TRUE;
  985. }
  986. /*****************************************************************************
  987. CVideoCaptureDialog::OnThreadDestroy
  988. <Notes>
  989. *****************************************************************************/
  990. BOOL WINAPI CVideoCaptureDialog::OnThreadDestroy( CThreadMessage * )
  991. {
  992. WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::OnThreadDestroy"));
  993. return FALSE;
  994. }
  995. /*****************************************************************************
  996. CVideoCaptureDialog::SetSelectedListItem
  997. <Notes>
  998. *****************************************************************************/
  999. BOOL
  1000. CVideoCaptureDialog::SetSelectedListItem( int nIndex )
  1001. {
  1002. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1003. //
  1004. // Check for bad args
  1005. //
  1006. if (!hwndList)
  1007. {
  1008. return FALSE;
  1009. }
  1010. int iCount = ListView_GetItemCount(hwndList);
  1011. for (int i=0;i<iCount;i++)
  1012. {
  1013. ListView_SetItemState(hwndList,i,0,LVIS_SELECTED|LVIS_FOCUSED);
  1014. }
  1015. ListView_SetItemState(hwndList,nIndex,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
  1016. return TRUE;
  1017. }
  1018. /*****************************************************************************
  1019. CVideoCaptureDialog::MarkItemDeletePending
  1020. <Notes>
  1021. *****************************************************************************/
  1022. VOID
  1023. CVideoCaptureDialog::MarkItemDeletePending( INT nIndex, BOOL bSet )
  1024. {
  1025. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1026. if (hwndList)
  1027. {
  1028. ListView_SetItemState( hwndList, nIndex, bSet ? LVIS_CUT : 0, LVIS_CUT );
  1029. }
  1030. }
  1031. /*****************************************************************************
  1032. CVideoCaptureDialog::PopulateList
  1033. Populates the listview with the current items.
  1034. *****************************************************************************/
  1035. BOOL
  1036. CVideoCaptureDialog::PopulateList( CCameraItem *pOldParent )
  1037. {
  1038. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1039. int nSelItem = 0;
  1040. if (hwndList)
  1041. {
  1042. ListView_DeleteAllItems( hwndList );
  1043. int nItem = 0;
  1044. CCameraItem *pCurr;
  1045. //
  1046. // If this is a child directory...
  1047. //
  1048. if (m_pCurrentParentItem)
  1049. {
  1050. //
  1051. // Start adding children
  1052. //
  1053. pCurr = m_pCurrentParentItem->Children();
  1054. //
  1055. // Insert a dummy item that the user can use to
  1056. // switch to the parent directory
  1057. //
  1058. LVITEM lvItem;
  1059. ZeroMemory( &lvItem, sizeof(lvItem) );
  1060. lvItem.iItem = nItem++;
  1061. lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
  1062. lvItem.iImage = m_nParentFolderImageListIndex;
  1063. lvItem.lParam = 0;
  1064. ListView_InsertItem( hwndList, &lvItem );
  1065. }
  1066. else
  1067. {
  1068. //
  1069. // if it's a parent directory...
  1070. //
  1071. pCurr = m_CameraItemList.Root();
  1072. }
  1073. while (pCurr)
  1074. {
  1075. if (pOldParent && *pCurr == *pOldParent)
  1076. {
  1077. nSelItem = nItem;
  1078. }
  1079. if (pCurr->DeleteState() != CCameraItem::Delete_Deleted)
  1080. {
  1081. LVITEM lvItem;
  1082. ZeroMemory( &lvItem, sizeof(lvItem) );
  1083. lvItem.iItem = nItem++;
  1084. lvItem.mask = LVIF_IMAGE|LVIF_PARAM;
  1085. lvItem.iImage = pCurr->ImageListIndex();
  1086. lvItem.lParam = (LPARAM)pCurr;
  1087. int nIndex = ListView_InsertItem( hwndList, &lvItem );
  1088. if (nIndex >= 0 && pCurr->DeleteState() == CCameraItem::Delete_Pending)
  1089. {
  1090. MarkItemDeletePending(nIndex,true);
  1091. }
  1092. }
  1093. pCurr = pCurr->Next();
  1094. }
  1095. }
  1096. //
  1097. // If we've not calculated the width of the list in preview mode, attempt to do it
  1098. //
  1099. if (!m_nListViewWidth)
  1100. {
  1101. RECT rcItem;
  1102. if (ListView_GetItemRect( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), 0, &rcItem, LVIR_ICON ))
  1103. {
  1104. m_nListViewWidth = (rcItem.right-rcItem.left) + rcItem.left * 2 + GetSystemMetrics(SM_CXHSCROLL) + c_nAdditionalMarginX;
  1105. }
  1106. }
  1107. SetSelectedListItem(nSelItem);
  1108. return TRUE;
  1109. }
  1110. /*****************************************************************************
  1111. CVideoCaptureDialog::OnThumbnailStatus
  1112. <Notes>
  1113. *****************************************************************************/
  1114. LRESULT
  1115. CVideoCaptureDialog::OnThumbnailStatus( WPARAM wParam, LPARAM lParam )
  1116. {
  1117. WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::OnThumbnailStatus"));
  1118. WIA_TRACE((TEXT("Looking for the item with the ID %08X"),wParam));
  1119. CCameraItem *pCameraItem = m_CameraItemList.Find( (DWORD)wParam );
  1120. if (pCameraItem)
  1121. {
  1122. WIA_TRACE((TEXT("Found a CameraItem * (%08X)"),pCameraItem));
  1123. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1124. if (hwndList)
  1125. {
  1126. WIA_TRACE((TEXT("Got the list control")));
  1127. HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
  1128. if (hImageList)
  1129. {
  1130. WIA_TRACE((TEXT("Got the image list")));
  1131. if ((HBITMAP)lParam)
  1132. {
  1133. if (ImageList_Replace( hImageList, pCameraItem->ImageListIndex(), (HBITMAP)lParam, NULL ))
  1134. {
  1135. WIA_TRACE((TEXT("Replaced the image in the list")));
  1136. int nItem = FindItemInList(pCameraItem);
  1137. if (nItem >= 0)
  1138. {
  1139. LV_ITEM lvItem;
  1140. ::ZeroMemory(&lvItem,sizeof(LV_ITEM));
  1141. lvItem.iItem = nItem;
  1142. lvItem.mask = LVIF_IMAGE;
  1143. lvItem.iImage = pCameraItem->ImageListIndex();
  1144. ListView_SetItem( hwndList, &lvItem );
  1145. ListView_Update( hwndList, nItem );
  1146. InvalidateRect( hwndList, NULL, FALSE );
  1147. }
  1148. }
  1149. }
  1150. }
  1151. }
  1152. }
  1153. //
  1154. // Clean up the bitmap, regardless of any other failures, to avoid memory leaks
  1155. //
  1156. HBITMAP hBmpThumb = (HBITMAP)lParam;
  1157. if (hBmpThumb)
  1158. {
  1159. DeleteObject(hBmpThumb);
  1160. }
  1161. return HANDLED_THREAD_MESSAGE;
  1162. }
  1163. /*****************************************************************************
  1164. CVideoCaptureDialog::CreateThumbnails
  1165. <Notes>
  1166. *****************************************************************************/
  1167. void CVideoCaptureDialog::CreateThumbnails( CCameraItem *pRoot, HIMAGELIST hImageList, bool bForce )
  1168. {
  1169. CCameraItem *pCurr = pRoot;
  1170. while (pCurr)
  1171. {
  1172. if (pCurr->ImageListIndex()<0 || bForce)
  1173. {
  1174. //
  1175. // Get the item name
  1176. //
  1177. CSimpleStringWide strItemName;
  1178. PropStorageHelpers::GetProperty( pCurr->Item(), WIA_IPA_ITEM_NAME, strItemName );
  1179. //
  1180. // Create the title for the icon
  1181. //
  1182. CSimpleString strIconTitle;
  1183. if (pCurr->IsFolder())
  1184. {
  1185. strIconTitle = CSimpleStringConvert::NaturalString(strItemName);
  1186. }
  1187. else if (strItemName.Length())
  1188. {
  1189. strIconTitle.Format( IDS_VIDDLG_DOWNLOADINGTHUMBNAIL, g_hInstance, CSimpleStringConvert::NaturalString(strItemName).String() );
  1190. }
  1191. //
  1192. // Create the thumbnail
  1193. //
  1194. HBITMAP hBmp = WiaUiUtil::CreateIconThumbnail( GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ), m_sizeThumbnails.cx, m_sizeThumbnails.cy, g_hInstance, pCurr->IsFolder()?IDI_VIDDLG_FOLDER:IDI_VIDDLG_UNAVAILABLE, strIconTitle );
  1195. if (hBmp)
  1196. {
  1197. if (pCurr->ImageListIndex()<0)
  1198. {
  1199. pCurr->ImageListIndex(ImageList_Add( hImageList, hBmp, NULL ));
  1200. }
  1201. else
  1202. {
  1203. pCurr->ImageListIndex(ImageList_Replace( hImageList, pCurr->ImageListIndex(), hBmp, NULL ));
  1204. }
  1205. DeleteObject(hBmp);
  1206. }
  1207. }
  1208. if (pCurr->Children())
  1209. {
  1210. CreateThumbnails( pCurr->Children(), hImageList, bForce );
  1211. }
  1212. pCurr = pCurr->Next();
  1213. }
  1214. }
  1215. /*****************************************************************************
  1216. CVideoCaptureDialog::RequestThumbnails
  1217. <Notes>
  1218. *****************************************************************************/
  1219. VOID
  1220. CVideoCaptureDialog::RequestThumbnails( CCameraItem *pRoot )
  1221. {
  1222. WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::RequestThumbnails"));
  1223. CCameraItem *pCurr = pRoot;
  1224. while (pCurr)
  1225. {
  1226. if (!pCurr->IsFolder())
  1227. {
  1228. m_pThreadMessageQueue->Enqueue( new CThumbnailThreadMessage( m_hWnd, pCurr->GlobalInterfaceTableCookie(), m_sizeThumbnails ) );
  1229. }
  1230. if (pCurr->Children())
  1231. {
  1232. RequestThumbnails( pCurr->Children() );
  1233. }
  1234. pCurr = pCurr->Next();
  1235. }
  1236. }
  1237. /*****************************************************************************
  1238. CVideoCaptureDialog::CreateThumbnails
  1239. <Notes>
  1240. *****************************************************************************/
  1241. VOID
  1242. CVideoCaptureDialog::CreateThumbnails( BOOL bForce )
  1243. {
  1244. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1245. if (hwndList)
  1246. {
  1247. HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
  1248. if (hImageList)
  1249. {
  1250. //
  1251. // Create the parent folder image and add it to the image list
  1252. //
  1253. HBITMAP hParentBitmap = WiaUiUtil::CreateIconThumbnail(
  1254. hwndList,
  1255. m_sizeThumbnails.cx,
  1256. m_sizeThumbnails.cy,
  1257. g_hInstance,
  1258. IDI_VIDDLG_PARENTFOLDER,
  1259. TEXT("(..)") );
  1260. if (hParentBitmap)
  1261. {
  1262. m_nParentFolderImageListIndex = ImageList_Add( hImageList, hParentBitmap, NULL );
  1263. DeleteObject(hParentBitmap);
  1264. }
  1265. //
  1266. // Create all of the other images
  1267. //
  1268. CreateThumbnails( m_CameraItemList.Root(), hImageList, bForce != 0 );
  1269. }
  1270. }
  1271. }
  1272. /*****************************************************************************
  1273. CVideoCaptureDialog::FindMaximumThumbnailSize
  1274. Looks through entire item list to get larget thumbnail.
  1275. *****************************************************************************/
  1276. BOOL
  1277. CVideoCaptureDialog::FindMaximumThumbnailSize( VOID )
  1278. {
  1279. WIA_PUSHFUNCTION(TEXT("CVideoCaptureDialog::FindMaximumThumbnailSize"));
  1280. BOOL bResult = false;
  1281. if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot)
  1282. {
  1283. LONG nWidth, nHeight;
  1284. if (PropStorageHelpers::GetProperty( m_pDeviceDialogData->pIWiaItemRoot, WIA_DPC_THUMB_WIDTH, nWidth ) &&
  1285. PropStorageHelpers::GetProperty( m_pDeviceDialogData->pIWiaItemRoot, WIA_DPC_THUMB_WIDTH, nHeight ))
  1286. {
  1287. m_sizeThumbnails.cx = max(c_nMinThumbnailWidth,min(nWidth,c_nMaxThumbnailWidth));
  1288. m_sizeThumbnails.cy = max(c_nMinThumbnailHeight,min(nHeight,c_nMaxThumbnailHeight));
  1289. }
  1290. else
  1291. {
  1292. WIA_TRACE((TEXT("FindMaximumThumbnailSize: Unable to retrieve thumbnail size for device")));
  1293. }
  1294. }
  1295. return(bResult && m_sizeThumbnails.cx && m_sizeThumbnails.cy);
  1296. }
  1297. /*****************************************************************************
  1298. CVideoCaptureDialog::EnumerateItems
  1299. Enumerate all the items at this level of the camera.
  1300. *****************************************************************************/
  1301. HRESULT
  1302. CVideoCaptureDialog::EnumerateItems( CCameraItem *pCurrentParent, IEnumWiaItem *pIEnumWiaItem )
  1303. {
  1304. WIA_PUSHFUNCTION(TEXT("CCameraItemList::EnumerateItems"));
  1305. HRESULT hr = E_FAIL;
  1306. if (pIEnumWiaItem != NULL)
  1307. {
  1308. hr = pIEnumWiaItem->Reset();
  1309. while (hr == S_OK)
  1310. {
  1311. CComPtr<IWiaItem> pIWiaItem;
  1312. hr = pIEnumWiaItem->Next(1, &pIWiaItem, NULL);
  1313. if (hr == S_OK)
  1314. {
  1315. CCameraItem *pNewCameraItem = new CCameraItem( pIWiaItem );
  1316. if (pNewCameraItem && pNewCameraItem->Item())
  1317. {
  1318. m_CameraItemList.Add( pCurrentParent, pNewCameraItem );
  1319. LONG ItemType;
  1320. HRESULT hr2;
  1321. hr2 = pNewCameraItem->Item()->GetItemType(&ItemType);
  1322. if (SUCCEEDED(hr2))
  1323. {
  1324. if (ItemType & WiaItemTypeImage)
  1325. {
  1326. WIA_TRACE((TEXT("Found an image")));
  1327. }
  1328. else
  1329. {
  1330. WIA_TRACE((TEXT("Found something that is NOT an image")));
  1331. }
  1332. CComPtr <IEnumWiaItem> pIEnumChildItem;
  1333. hr2 = pIWiaItem->EnumChildItems(&pIEnumChildItem);
  1334. if (hr2 == S_OK)
  1335. {
  1336. EnumerateItems( pNewCameraItem, pIEnumChildItem );
  1337. }
  1338. }
  1339. }
  1340. }
  1341. }
  1342. }
  1343. return hr;
  1344. }
  1345. /*****************************************************************************
  1346. CVideoCaptureDialog::EnumerateAllCameraItems
  1347. Enumerate all the items in camera, including folders.
  1348. *****************************************************************************/
  1349. HRESULT CVideoCaptureDialog::EnumerateAllCameraItems(void)
  1350. {
  1351. CComPtr<IEnumWiaItem> pIEnumItem;
  1352. HRESULT hr = m_pDeviceDialogData->pIWiaItemRoot->EnumChildItems(&pIEnumItem);
  1353. if (hr == S_OK)
  1354. {
  1355. hr = EnumerateItems( NULL, pIEnumItem );
  1356. }
  1357. return(hr);
  1358. }
  1359. /*****************************************************************************
  1360. CVideoCaptureDialog::GetSelectionIndices
  1361. Returns an array with the list indicies of the items that are
  1362. selected in IDC_VIDDLG_THUMBNAILLIST
  1363. *****************************************************************************/
  1364. INT
  1365. CVideoCaptureDialog::GetSelectionIndices( CSimpleDynamicArray<int> &aIndices )
  1366. {
  1367. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1368. if (!hwndList)
  1369. {
  1370. return 0;
  1371. }
  1372. INT iCount = ListView_GetItemCount(hwndList);
  1373. for (INT i=0; i<iCount; i++)
  1374. {
  1375. if (ListView_GetItemState(hwndList,i,LVIS_SELECTED) & LVIS_SELECTED)
  1376. {
  1377. aIndices.Append(i);
  1378. }
  1379. }
  1380. return aIndices.Size();
  1381. }
  1382. /*****************************************************************************
  1383. CVideoCaptureDialog::OnPostInit
  1384. Handle the post WM_INIT processing that needs to take place.
  1385. *****************************************************************************/
  1386. LRESULT CVideoCaptureDialog::OnPostInit( WPARAM, LPARAM )
  1387. {
  1388. //
  1389. // Create the progress dialog
  1390. //
  1391. CComPtr<IWiaProgressDialog> pWiaProgressDialog;
  1392. HRESULT hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaProgressDialog, (void**)&pWiaProgressDialog );
  1393. if (SUCCEEDED(hr))
  1394. {
  1395. //
  1396. // Initialize the progress dialog
  1397. //
  1398. pWiaProgressDialog->Create( m_hWnd, WIA_PROGRESSDLG_ANIM_VIDEO_COMMUNICATE|WIA_PROGRESSDLG_NO_PROGRESS|WIA_PROGRESSDLG_NO_CANCEL|WIA_PROGRESSDLG_NO_TITLE );
  1399. pWiaProgressDialog->SetTitle( CSimpleStringConvert::WideString(CSimpleString(IDS_VIDDLG_PROGDLG_TITLE,g_hInstance)));
  1400. pWiaProgressDialog->SetMessage( CSimpleStringConvert::WideString(CSimpleString(IDS_VIDDLG_PROGDLG_MESSAGE,g_hInstance)));
  1401. //
  1402. // Show the progress dialog
  1403. //
  1404. pWiaProgressDialog->Show();
  1405. if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot && m_pWiaVideo)
  1406. {
  1407. CSimpleString strImagesDirectory;
  1408. if (hr == S_OK)
  1409. {
  1410. BOOL bSuccess = FALSE;
  1411. //
  1412. // Get the IMAGES_DIRECTORY property from the Wia Video Driver.
  1413. //
  1414. bSuccess = PropStorageHelpers::GetProperty(m_pDeviceDialogData->pIWiaItemRoot,
  1415. WIA_DPV_IMAGES_DIRECTORY,
  1416. strImagesDirectory);
  1417. if (!bSuccess)
  1418. {
  1419. hr = E_FAIL;
  1420. }
  1421. }
  1422. if (hr == S_OK)
  1423. {
  1424. WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
  1425. //
  1426. // Get the current state of the WiaVideo object. If we just created it
  1427. // then the state will be NO_VIDEO, otherwise, it could already be previewing video,
  1428. // in which case we shouldn't do anything.
  1429. //
  1430. hr = m_pWiaVideo->GetCurrentState(&VideoState);
  1431. if (VideoState == WIAVIDEO_NO_VIDEO)
  1432. {
  1433. //
  1434. // Set the directory we want to save our images to. We got the image directory
  1435. // from the Wia Video Driver IMAGES_DIRECTORY property
  1436. //
  1437. if (hr == S_OK)
  1438. {
  1439. hr = m_pWiaVideo->put_ImagesDirectory(CSimpleBStr(strImagesDirectory));
  1440. }
  1441. //
  1442. // Create the video preview as a child of the IDC_VIDSEL_PREVIEW dialog item
  1443. // and automatically begin playback after creating the preview.
  1444. //
  1445. if (hr == S_OK)
  1446. {
  1447. hr = m_pWiaVideo->CreateVideoByWiaDevID(CSimpleBStr(m_strwDeviceId),
  1448. GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW ),
  1449. FALSE,
  1450. TRUE);
  1451. }
  1452. }
  1453. }
  1454. if (hr != S_OK)
  1455. {
  1456. //
  1457. // Let the user know that the graph is most likely already
  1458. // in use...
  1459. //
  1460. MessageBox( m_hWnd,
  1461. CSimpleString(IDS_VIDDLG_BUSY_TEXT, g_hInstance),
  1462. CSimpleString(IDS_VIDDLG_BUSY_TITLE, g_hInstance),
  1463. MB_OK | MB_ICONWARNING | MB_SETFOREGROUND
  1464. );
  1465. //
  1466. // Disable the capture button since we have no graph
  1467. //
  1468. MyEnableWindow( GetDlgItem(m_hWnd,IDC_VIDDLG_CAPTURE), FALSE );
  1469. }
  1470. }
  1471. //
  1472. // Go get all the items..
  1473. //
  1474. EnumerateAllCameraItems();
  1475. FindMaximumThumbnailSize();
  1476. //
  1477. // Initialize Thumbnail Listview control
  1478. //
  1479. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1480. if (hwndList)
  1481. {
  1482. ListView_SetExtendedListViewStyleEx( hwndList,
  1483. LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS,
  1484. LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS
  1485. );
  1486. m_hImageList = ImageList_Create( m_sizeThumbnails.cx,
  1487. m_sizeThumbnails.cy,
  1488. ILC_COLOR24|ILC_MIRROR, 1, 1
  1489. );
  1490. if (m_hImageList)
  1491. {
  1492. ListView_SetImageList( hwndList,
  1493. m_hImageList,
  1494. LVSIL_NORMAL
  1495. );
  1496. ListView_SetIconSpacing( hwndList,
  1497. m_sizeThumbnails.cx + c_nAdditionalMarginX,
  1498. m_sizeThumbnails.cy + c_nAdditionalMarginY
  1499. );
  1500. }
  1501. }
  1502. CreateThumbnails();
  1503. //
  1504. // This causes the list to be populated
  1505. //
  1506. ChangeFolder(NULL);
  1507. HandleSelectionChange();
  1508. RequestThumbnails( m_CameraItemList.Root() );
  1509. //
  1510. // Close the progress dialog
  1511. //
  1512. pWiaProgressDialog->Destroy();
  1513. }
  1514. return(0);
  1515. }
  1516. /*****************************************************************************
  1517. CVideoCaptureDialog::FindItemInList
  1518. <Notes>
  1519. *****************************************************************************/
  1520. INT CVideoCaptureDialog::FindItemInList( CCameraItem *pItem )
  1521. {
  1522. if (pItem)
  1523. {
  1524. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1525. if (hwndList)
  1526. {
  1527. for (int i=0;i<ListView_GetItemCount(hwndList);i++)
  1528. {
  1529. if (pItem == GetListItemNode(i))
  1530. {
  1531. return i;
  1532. }
  1533. }
  1534. }
  1535. }
  1536. return -1;
  1537. }
  1538. /*****************************************************************************
  1539. CVideoCaptureDialog::GetListItemNode
  1540. <Notes>
  1541. *****************************************************************************/
  1542. CCameraItem *
  1543. CVideoCaptureDialog::GetListItemNode( int nIndex )
  1544. {
  1545. HWND hwndList = GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST );
  1546. if (!hwndList)
  1547. {
  1548. return NULL;
  1549. }
  1550. LV_ITEM lvItem;
  1551. ::ZeroMemory(&lvItem,sizeof(LV_ITEM));
  1552. lvItem.mask = LVIF_PARAM;
  1553. lvItem.iItem = nIndex;
  1554. if (!ListView_GetItem( hwndList, &lvItem ))
  1555. {
  1556. return NULL ;
  1557. }
  1558. return((CCameraItem *)lvItem.lParam);
  1559. }
  1560. /*****************************************************************************
  1561. CVideoCaptureDialog::ChangeFolder
  1562. Change the current folder being viewed
  1563. *****************************************************************************/
  1564. BOOL
  1565. CVideoCaptureDialog::ChangeFolder( CCameraItem *pNode )
  1566. {
  1567. CCameraItem *pOldParent = m_pCurrentParentItem;
  1568. m_pCurrentParentItem = pNode;
  1569. return PopulateList(pOldParent);
  1570. }
  1571. /*****************************************************************************
  1572. CVideoCaptureDialog::OnChangeToParent
  1573. <Notes>
  1574. *****************************************************************************/
  1575. LRESULT
  1576. CVideoCaptureDialog::OnChangeToParent( WPARAM, LPARAM )
  1577. {
  1578. if (m_pCurrentParentItem)
  1579. {
  1580. ChangeFolder(m_pCurrentParentItem->Parent());
  1581. }
  1582. return(0);
  1583. }
  1584. /*****************************************************************************
  1585. CVideoCaptureDialog::HandleSelectionChange
  1586. <Notes>
  1587. *****************************************************************************/
  1588. VOID
  1589. CVideoCaptureDialog::HandleSelectionChange( VOID )
  1590. {
  1591. CWaitCursor wc;
  1592. INT nSelCount = ListView_GetSelectedCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ) );
  1593. INT nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ) );
  1594. //
  1595. // OK should be disabled for 0 items
  1596. //
  1597. MyEnableWindow( GetDlgItem(m_hWnd,IDOK), nSelCount != 0 );
  1598. //
  1599. // Select all should be disabled for 0 items
  1600. //
  1601. MyEnableWindow( GetDlgItem(m_hWnd,IDC_VIDDLG_SELECTALL), nItemCount != 0 );
  1602. }
  1603. /*****************************************************************************
  1604. CVideoCaptureDialog::OnTimer
  1605. Handle WM_TIMER messages
  1606. *****************************************************************************/
  1607. LRESULT
  1608. CVideoCaptureDialog::OnTimer( WPARAM wParam, LPARAM )
  1609. {
  1610. /*
  1611. switch (wParam)
  1612. {
  1613. case IDT_UPDATEPREVIEW:
  1614. {
  1615. KillTimer( m_hWnd, IDT_UPDATEPREVIEW );
  1616. UpdatePreview();
  1617. }
  1618. break;
  1619. }
  1620. */
  1621. return(0);
  1622. }
  1623. /*****************************************************************************
  1624. CVideoCaptureDialog::OnNewItemEvent
  1625. This gets called when get an event from the driver that a new item has
  1626. been created.
  1627. *****************************************************************************/
  1628. LRESULT
  1629. CVideoCaptureDialog::OnNewItemEvent( WPARAM, LPARAM lParam )
  1630. {
  1631. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnNewItemEvent")));
  1632. //
  1633. // Make sure we have a valid item name
  1634. //
  1635. BSTR bstrFullItemName = reinterpret_cast<BSTR>(lParam);
  1636. if (!bstrFullItemName)
  1637. {
  1638. WIA_TRACE((TEXT("bstrFullItemName was NULL")));
  1639. return 0;
  1640. }
  1641. //
  1642. // Check to see if the item is already in our list
  1643. //
  1644. CCameraItem *pListItem = m_CameraItemList.Find(bstrFullItemName);
  1645. if (!pListItem)
  1646. {
  1647. if (m_pDeviceDialogData && m_pDeviceDialogData->pIWiaItemRoot)
  1648. {
  1649. WIA_TRACE((TEXT("Finding new item in device")));
  1650. //
  1651. // Get an IWiaItem ptr to new item
  1652. //
  1653. CComPtr<IWiaItem> pItem;
  1654. HRESULT hr = m_pDeviceDialogData->pIWiaItemRoot->FindItemByName(0,bstrFullItemName,&pItem);
  1655. WIA_CHECK_HR(hr,"pWiaItemRoot->FindItemByName()");
  1656. if (SUCCEEDED(hr) && pItem)
  1657. {
  1658. //
  1659. // Add the item to the list
  1660. //
  1661. AddItemToListView( pItem );
  1662. //
  1663. // Make sure we update controls' states
  1664. //
  1665. HandleSelectionChange();
  1666. }
  1667. else
  1668. {
  1669. WIA_ERROR((TEXT("FindItemByName returned NULL pItem")));
  1670. }
  1671. }
  1672. else
  1673. {
  1674. WIA_ERROR((TEXT("m_pDeviceDialogData or m_pDeviceDialogData->pIWiaItemRoot were NULL")));
  1675. }
  1676. }
  1677. else
  1678. {
  1679. WIA_TRACE((TEXT("We found the item is already in our list, doing nothing")));
  1680. }
  1681. //
  1682. // Free the item name
  1683. //
  1684. SysFreeString(bstrFullItemName);
  1685. return HANDLED_THREAD_MESSAGE;
  1686. }
  1687. /*****************************************************************************
  1688. CVideoCaptureDialog::OnDeleteItemEvent
  1689. This gets called when we get an event from the driver that an item has
  1690. been deleted.
  1691. *****************************************************************************/
  1692. LRESULT
  1693. CVideoCaptureDialog::OnDeleteItemEvent( WPARAM, LPARAM lParam )
  1694. {
  1695. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDeleteItemEvent")));
  1696. CSimpleBStr bstrFullItem = reinterpret_cast<BSTR>(lParam);
  1697. SysFreeString( reinterpret_cast<BSTR>(lParam) );
  1698. WIA_TRACE((TEXT("The deleted item is %s"),CSimpleStringConvert::NaturalString(CSimpleStringWide(bstrFullItem)).String()));
  1699. CCameraItem *pDeletedItem = m_CameraItemList.Find(bstrFullItem);
  1700. if (pDeletedItem)
  1701. {
  1702. //
  1703. // If we're deleting the current parent item,
  1704. // select a new one.
  1705. //
  1706. if (pDeletedItem == m_pCurrentParentItem)
  1707. {
  1708. ChangeFolder(m_pCurrentParentItem->Parent());
  1709. }
  1710. int nIndex = FindItemInList(pDeletedItem);
  1711. if (nIndex >= 0)
  1712. {
  1713. //
  1714. // Remove the item from the listview
  1715. //
  1716. ListView_DeleteItem(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ),nIndex);
  1717. //
  1718. // Make sure we leave something selected
  1719. //
  1720. if (!ListView_GetSelectedCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST )))
  1721. {
  1722. int nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_VIDDLG_THUMBNAILLIST ));
  1723. if (nItemCount)
  1724. {
  1725. if (nIndex >= nItemCount)
  1726. {
  1727. nIndex = nItemCount-1;
  1728. }
  1729. SetSelectedListItem(nIndex);
  1730. }
  1731. }
  1732. //
  1733. // Make sure we update controls' states
  1734. //
  1735. HandleSelectionChange();
  1736. }
  1737. else
  1738. {
  1739. WIA_ERROR((TEXT("FindItemInList coulnd't find the item")));
  1740. }
  1741. //
  1742. // Mark the item as deleted.
  1743. //
  1744. pDeletedItem->DeleteState( CCameraItem::Delete_Deleted );
  1745. }
  1746. else
  1747. {
  1748. WIA_ERROR((TEXT("The item could not be found in m_CameraItemList")));
  1749. }
  1750. return HANDLED_THREAD_MESSAGE;
  1751. }
  1752. /*****************************************************************************
  1753. CVideoCaptureDialog::OnDeviceDisconnect
  1754. This gets called when we get an event from the driver that device has
  1755. been disconnected.
  1756. *****************************************************************************/
  1757. LRESULT
  1758. CVideoCaptureDialog::OnDeviceDisconnect( WPARAM, LPARAM )
  1759. {
  1760. WIA_PUSHFUNCTION((TEXT("CVideoCaptureDialog::OnDeviceDisconnect")));
  1761. //
  1762. // Close the dialog with the approriate error
  1763. //
  1764. EndDialog( m_hWnd, WIA_ERROR_OFFLINE );
  1765. return 0;
  1766. }
  1767. /*****************************************************************************
  1768. CVideoCaptureDialog::GetGraphWindowHandle
  1769. Find the window handle of the video window
  1770. *****************************************************************************/
  1771. HWND
  1772. CVideoCaptureDialog::GetGraphWindowHandle(void)
  1773. {
  1774. HWND hWndGraphParent = GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW );
  1775. if (hWndGraphParent)
  1776. {
  1777. return FindWindowEx( hWndGraphParent, NULL, TEXT("VideoRenderer"), NULL );
  1778. }
  1779. return NULL;
  1780. }
  1781. /*****************************************************************************
  1782. CCameraAcquireDialog::OnContextMenu
  1783. Message handler for WM_HELP message
  1784. *****************************************************************************/
  1785. LRESULT
  1786. CVideoCaptureDialog::OnHelp( WPARAM wParam, LPARAM lParam )
  1787. {
  1788. HELPINFO *pHelpInfo = reinterpret_cast<HELPINFO*>(lParam);
  1789. if (pHelpInfo && HELPINFO_WINDOW==pHelpInfo->iContextType && GetGraphWindowHandle()==pHelpInfo->hItemHandle)
  1790. {
  1791. pHelpInfo->hItemHandle = GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW );
  1792. }
  1793. return WiaHelp::HandleWmHelp( wParam, lParam, g_HelpIDs );
  1794. }
  1795. /*****************************************************************************
  1796. CCameraAcquireDialog::OnContextMenu
  1797. Message handler for right-mouse-button click
  1798. *****************************************************************************/
  1799. LRESULT
  1800. CVideoCaptureDialog::OnContextMenu( WPARAM wParam, LPARAM lParam )
  1801. {
  1802. if (GetGraphWindowHandle() == reinterpret_cast<HWND>(wParam))
  1803. {
  1804. wParam = reinterpret_cast<WPARAM>(GetDlgItem( m_hWnd, IDC_VIDDLG_PREVIEW ));
  1805. }
  1806. return WiaHelp::HandleWmContextMenu( wParam, lParam, g_HelpIDs );
  1807. }
  1808. /*****************************************************************************
  1809. CVideoCaptureDialog::DialogProc
  1810. Dialog proc for video capture dialog
  1811. *****************************************************************************/
  1812. INT_PTR PASCAL CVideoCaptureDialog::DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  1813. {
  1814. SC_BEGIN_DIALOG_MESSAGE_HANDLERS(CVideoCaptureDialog)
  1815. {
  1816. SC_HANDLE_DIALOG_MESSAGE( WM_INITDIALOG, OnInitDialog );
  1817. SC_HANDLE_DIALOG_MESSAGE( WM_SIZE, OnSize );
  1818. SC_HANDLE_DIALOG_MESSAGE( WM_COMMAND, OnCommand );
  1819. SC_HANDLE_DIALOG_MESSAGE( WM_NOTIFY, OnNotify );
  1820. SC_HANDLE_DIALOG_MESSAGE( WM_GETMINMAXINFO, OnGetMinMaxInfo );
  1821. SC_HANDLE_DIALOG_MESSAGE( WM_DESTROY, OnDestroy );
  1822. SC_HANDLE_DIALOG_MESSAGE( WM_SHOWWINDOW, OnShow );
  1823. SC_HANDLE_DIALOG_MESSAGE( WM_TIMER, OnTimer );
  1824. SC_HANDLE_DIALOG_MESSAGE( WM_HELP, OnHelp );
  1825. SC_HANDLE_DIALOG_MESSAGE( WM_CONTEXTMENU, OnContextMenu );
  1826. SC_HANDLE_DIALOG_MESSAGE( PWM_POSTINIT, OnPostInit );
  1827. SC_HANDLE_DIALOG_MESSAGE( PWM_CHANGETOPARENT, OnChangeToParent );
  1828. SC_HANDLE_DIALOG_MESSAGE( PWM_THUMBNAILSTATUS, OnThumbnailStatus );
  1829. SC_HANDLE_DIALOG_MESSAGE( VD_NEW_ITEM, OnNewItemEvent );
  1830. SC_HANDLE_DIALOG_MESSAGE( VD_DELETE_ITEM, OnDeleteItemEvent );
  1831. SC_HANDLE_DIALOG_MESSAGE( VD_DEVICE_DISCONNECTED, OnDeviceDisconnect );
  1832. }
  1833. SC_END_DIALOG_MESSAGE_HANDLERS();
  1834. }
  1835. /*****************************************************************************
  1836. CVideoCallback::CVideoCallback
  1837. Constructor for class
  1838. *****************************************************************************/
  1839. CVideoCallback::CVideoCallback()
  1840. : m_cRef(1),
  1841. m_hWnd(NULL)
  1842. {
  1843. WIA_PUSHFUNCTION((TEXT("CVideoCallback::CVideoCallback()")));
  1844. }
  1845. /*****************************************************************************
  1846. CVideoCallback::Initialize
  1847. Let us set which hwnd to notify when events come
  1848. *****************************************************************************/
  1849. STDMETHODIMP
  1850. CVideoCallback::Initialize( HWND hWnd )
  1851. {
  1852. WIA_PUSHFUNCTION((TEXT("CVideoCallback::Initialize()")));
  1853. m_hWnd = hWnd;
  1854. return S_OK;
  1855. }
  1856. /*****************************************************************************
  1857. CVideoCallback::AddRef
  1858. Standard COM
  1859. *****************************************************************************/
  1860. STDMETHODIMP_(ULONG)
  1861. CVideoCallback::AddRef( VOID )
  1862. {
  1863. WIA_PUSHFUNCTION((TEXT("CVideoCallback::AddRef")));
  1864. return(InterlockedIncrement(&m_cRef));
  1865. }
  1866. /*****************************************************************************
  1867. CVideoCallback::Release
  1868. Standard COM
  1869. *****************************************************************************/
  1870. STDMETHODIMP_(ULONG)
  1871. CVideoCallback::Release( VOID )
  1872. {
  1873. WIA_PUSHFUNCTION(TEXT("CVideoCallback::Release"));
  1874. LONG nRefCount = InterlockedDecrement(&m_cRef);
  1875. if (!nRefCount)
  1876. {
  1877. delete this;
  1878. }
  1879. return(nRefCount);
  1880. }
  1881. /*****************************************************************************
  1882. CVideoCallback::QueryInterface
  1883. Standard COM
  1884. *****************************************************************************/
  1885. STDMETHODIMP
  1886. CVideoCallback::QueryInterface( REFIID riid, LPVOID *ppvObject )
  1887. {
  1888. WIA_PUSHFUNCTION((TEXT("CVideoCallback::QueryInterface")));
  1889. HRESULT hr = S_OK;
  1890. if (ppvObject)
  1891. {
  1892. if (IsEqualIID( riid, IID_IUnknown ))
  1893. {
  1894. WIA_TRACE((TEXT("Supported RIID asked for was IID_IUnknown")));
  1895. *ppvObject = static_cast<IUnknown*>(this);
  1896. reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
  1897. }
  1898. else if (IsEqualIID( riid, IID_IWiaEventCallback ))
  1899. {
  1900. WIA_TRACE((TEXT("Supported RIID asked for was IID_IWiaEventCallback")));
  1901. *ppvObject = static_cast<IWiaEventCallback*>(this);
  1902. reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
  1903. }
  1904. else
  1905. {
  1906. WIA_PRINTGUID((riid,TEXT("Unsupported interface!")));
  1907. *ppvObject = NULL;
  1908. hr = E_NOINTERFACE;
  1909. }
  1910. }
  1911. else
  1912. {
  1913. hr = E_INVALIDARG;
  1914. }
  1915. WIA_RETURN_HR(hr);
  1916. }
  1917. /*****************************************************************************
  1918. CVideoCallback::ImageEventCallback
  1919. WIA callback interface for events.
  1920. *****************************************************************************/
  1921. STDMETHODIMP
  1922. CVideoCallback::ImageEventCallback( const GUID *pEventGUID,
  1923. BSTR bstrEventDescription,
  1924. BSTR bstrDeviceID,
  1925. BSTR bstrDeviceDescription,
  1926. DWORD dwDeviceType,
  1927. BSTR bstrFullItemName,
  1928. ULONG *pulEventType,
  1929. ULONG ulReserved)
  1930. {
  1931. WIA_PUSHFUNCTION((TEXT("CVideoCallback::ImageEventCallback")));
  1932. HRESULT hr = S_OK;
  1933. if (pEventGUID)
  1934. {
  1935. if (IsEqualGUID( *pEventGUID, WIA_EVENT_ITEM_CREATED ))
  1936. {
  1937. WIA_TRACE((TEXT("Got WIA_EVENT_ITEM_CREATED")));
  1938. BSTR bstrToSend = SysAllocString( bstrFullItemName );
  1939. LRESULT lRes = SendMessage( m_hWnd, VD_NEW_ITEM, 0, reinterpret_cast<LPARAM>(bstrToSend) );
  1940. if (HANDLED_THREAD_MESSAGE != lRes && bstrToSend)
  1941. {
  1942. SysFreeString( bstrToSend );
  1943. }
  1944. }
  1945. else if (IsEqualGUID( *pEventGUID, WIA_EVENT_ITEM_DELETED ))
  1946. {
  1947. WIA_TRACE((TEXT("Got WIA_EVENT_ITEM_DELETED")));
  1948. BSTR bstrToSend = SysAllocString( bstrFullItemName );
  1949. LRESULT lRes = SendMessage( m_hWnd, VD_DELETE_ITEM, 0, reinterpret_cast<LPARAM>(bstrToSend) );
  1950. if (HANDLED_THREAD_MESSAGE != lRes && bstrToSend)
  1951. {
  1952. SysFreeString( bstrToSend );
  1953. }
  1954. }
  1955. else if (IsEqualGUID( *pEventGUID, WIA_EVENT_DEVICE_DISCONNECTED ))
  1956. {
  1957. PostMessage( m_hWnd, VD_DEVICE_DISCONNECTED, 0, 0 );
  1958. }
  1959. else
  1960. {
  1961. WIA_ERROR((TEXT("Got an event other that what we registered for!")));
  1962. }
  1963. }
  1964. WIA_RETURN_HR(hr);
  1965. }