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.

1687 lines
58 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: CAMSEL.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 9/28/1999
  12. *
  13. * DESCRIPTION: Camera selection page. Displays thumbnails, and lets the user select which
  14. * ones to download.
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. #include <vcamprop.h>
  20. #include <psutil.h>
  21. #include "camsel.h"
  22. #include "resource.h"
  23. #include "simcrack.h"
  24. #include "waitcurs.h"
  25. #include "mboxex.h"
  26. #include "wiatextc.h"
  27. #include <commctrl.h>
  28. #include <comctrlp.h>
  29. #include "gwiaevnt.h"
  30. #include <itranhlp.h>
  31. #include "createtb.h"
  32. #include <simrect.h>
  33. //
  34. // We use this instead of GetSystemMetrics(SM_CXSMICON)/GetSystemMetrics(SM_CYSMICON) because
  35. // large "small" icons wreak havoc with dialog layout
  36. //
  37. #define SMALL_ICON_SIZE 16
  38. //
  39. // Quickly check a listview state flag to see if it is selected or not
  40. //
  41. static inline bool IsStateChecked( UINT nState )
  42. {
  43. //
  44. // State image indices are stored in bits 12 through 15 of the listview
  45. // item state, so we shift the state right 12 bits. We subtract 1, because
  46. // the selected image is stored as index 2, an unselected image is stored as index 1.
  47. //
  48. return (((nState >> 12) - 1) != 0);
  49. }
  50. #undef VAISHALEE_LETS_ME_PUT_DELETE_IN
  51. #define IDC_ACTION_BUTTON_BAR 1200
  52. #define IDC_SELECTION_BUTTON_BAR 1201
  53. #define IDC_TAKEPICTURE_BUTTON_BAR 1202
  54. //
  55. // Delete item command, doesn't appear in resource header, because there is no UI for it
  56. //
  57. #define IDC_CAMSEL_DELETE 1113
  58. //
  59. // Timer ID for updating the status line
  60. //
  61. #define IDT_UPDATESTATUS 1
  62. //
  63. // Amount of time to wait to update the status line
  64. //
  65. static const UINT c_UpdateStatusTimeout = 200;
  66. // Thumbnail whitespace: the space in between images and their selection rectangles
  67. // These values were discovered by trail and error. For instance, if you reduce
  68. // c_nAdditionalMarginY to 20, you get really bizarre spacing problems in the list view
  69. // in vertical mode. These values could become invalid in future versions of the listview.
  70. static const int c_nAdditionalMarginX = 9;
  71. static const int c_nAdditionalMarginY = 21;
  72. CCameraSelectionPage::CCameraSelectionPage( HWND hWnd )
  73. : m_hWnd(hWnd),
  74. m_pControllerWindow(NULL),
  75. m_nDefaultThumbnailImageListIndex(-1),
  76. m_nWiaEventMessage(RegisterWindowMessage(STR_WIAEVENT_NOTIFICATION_MESSAGE)),
  77. m_nThreadNotificationMessage(RegisterWindowMessage(STR_THREAD_NOTIFICATION_MESSAGE)),
  78. m_bThumbnailsRequested(false),
  79. m_hIconAudioAnnotation(NULL),
  80. m_hIconMiscellaneousAnnotation(NULL),
  81. m_nProgrammaticSetting(0),
  82. m_CameraSelectionButtonBarBitmapInfo( g_hInstance, IDB_CAMSEL_TOOLBAR ),
  83. m_CameraTakePictureButtonBarBitmapInfo( g_hInstance, IDB_CAMSEL_TOOLBAR ),
  84. m_CameraActionButtonBarBitmapInfo( g_hInstance, IDB_CAMSEL_TOOLBAR ),
  85. m_hAccelerators(NULL)
  86. {
  87. }
  88. CCameraSelectionPage::~CCameraSelectionPage(void)
  89. {
  90. m_hWnd = NULL;
  91. m_pControllerWindow = NULL;
  92. if (m_hIconAudioAnnotation)
  93. {
  94. DestroyIcon(m_hIconAudioAnnotation);
  95. m_hIconAudioAnnotation = NULL;
  96. }
  97. if (m_hIconMiscellaneousAnnotation)
  98. {
  99. DestroyIcon(m_hIconMiscellaneousAnnotation);
  100. m_hIconMiscellaneousAnnotation = NULL;
  101. }
  102. if (m_hAccelerators)
  103. {
  104. DestroyAcceleratorTable(m_hAccelerators);
  105. m_hAccelerators = NULL;
  106. }
  107. }
  108. LRESULT CCameraSelectionPage::OnWizNext( WPARAM, LPARAM )
  109. {
  110. return 0;
  111. }
  112. LRESULT CCameraSelectionPage::OnWizBack( WPARAM, LPARAM )
  113. {
  114. return 0;
  115. }
  116. //
  117. // Slightly optimized version of EnableWindow
  118. //
  119. static void MyEnableWindow( HWND hWnd, BOOL bEnable )
  120. {
  121. if (IsWindowEnabled(hWnd) != bEnable)
  122. {
  123. EnableWindow( hWnd, bEnable );
  124. }
  125. }
  126. void CCameraSelectionPage::MyEnableToolbarButton( int nButtonId, bool bEnable )
  127. {
  128. ToolbarHelper::EnableToolbarButton( GetDlgItem( m_hWnd, IDC_ACTION_BUTTON_BAR ), nButtonId, bEnable );
  129. ToolbarHelper::EnableToolbarButton( GetDlgItem( m_hWnd, IDC_SELECTION_BUTTON_BAR ), nButtonId, bEnable );
  130. ToolbarHelper::EnableToolbarButton( GetDlgItem( m_hWnd, IDC_TAKEPICTURE_BUTTON_BAR ), nButtonId, bEnable );
  131. }
  132. LRESULT CCameraSelectionPage::OnTimer( WPARAM wParam, LPARAM )
  133. {
  134. //
  135. // Update the status line
  136. //
  137. if (wParam == IDT_UPDATESTATUS)
  138. {
  139. KillTimer( m_hWnd, IDT_UPDATESTATUS );
  140. //
  141. // Get the item count and selected count
  142. //
  143. int nItemCount = ListView_GetItemCount( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ) );
  144. int nCheckedCount = m_pControllerWindow->GetSelectedImageCount();
  145. if (!nItemCount)
  146. {
  147. //
  148. // If there are no items, tell the user there are no items on the device
  149. //
  150. CSimpleString( IDS_SELECTED_NO_PICTURES, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMSEL_STATUS ) );
  151. }
  152. else if (!nCheckedCount)
  153. {
  154. //
  155. // If none of the items are selected, tell the user there are none selected
  156. //
  157. CSimpleString( IDS_SELECTED_NO_IMAGES_SELECTED, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMSEL_STATUS ) );
  158. }
  159. else
  160. {
  161. //
  162. // Just tell them how many selected items there are
  163. //
  164. CSimpleString().Format( IDS_CAMERA_SELECT_NUMSEL, g_hInstance, nCheckedCount, nItemCount ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMSEL_STATUS ) );
  165. }
  166. }
  167. return 0;
  168. }
  169. void CCameraSelectionPage::UpdateControls(void)
  170. {
  171. int nItemCount = ListView_GetItemCount( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ) );
  172. int nSelCount = ListView_GetSelectedCount( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ) );
  173. int nCheckedCount = m_pControllerWindow->GetSelectedImageCount();
  174. //
  175. // Figure out which wizard buttons to enable
  176. //
  177. int nWizButtons = 0;
  178. //
  179. // Only enable "back" if the first page is available
  180. //
  181. if (!m_pControllerWindow->SuppressFirstPage())
  182. {
  183. nWizButtons |= PSWIZB_BACK;
  184. }
  185. //
  186. // Only enable "next" if there are selected images
  187. //
  188. if (nCheckedCount)
  189. {
  190. nWizButtons |= PSWIZB_NEXT;
  191. }
  192. //
  193. // Set the buttons
  194. //
  195. PropSheet_SetWizButtons( GetParent(m_hWnd), nWizButtons );
  196. //
  197. // Properties are only available for one item at a time
  198. //
  199. MyEnableToolbarButton( IDC_CAMSEL_PROPERTIES, nSelCount == 1 );
  200. //
  201. // Select All is only available if there are images
  202. //
  203. MyEnableToolbarButton( IDC_CAMSEL_SELECT_ALL, (nItemCount != 0) && (nItemCount != nCheckedCount) );
  204. //
  205. // Clear all is only available if there are selected images
  206. //
  207. MyEnableToolbarButton( IDC_CAMSEL_CLEAR_ALL, nCheckedCount != 0 );
  208. //
  209. // Rotate is only available if there are selected images
  210. //
  211. MyEnableToolbarButton( IDC_CAMSEL_ROTATE_RIGHT, nSelCount != 0 );
  212. MyEnableToolbarButton( IDC_CAMSEL_ROTATE_LEFT, nSelCount != 0 );
  213. //
  214. // Set a timer to tell the user how many images are selected. We don't do this
  215. // here because it is kind of slow, and the static control flickers a bit.
  216. //
  217. KillTimer( m_hWnd, IDT_UPDATESTATUS );
  218. SetTimer( m_hWnd, IDT_UPDATESTATUS, c_UpdateStatusTimeout, NULL );
  219. //
  220. // Disable capture if we can't create the dshow graph
  221. //
  222. if (m_pControllerWindow->m_DeviceTypeMode == CAcquisitionManagerControllerWindow::VideoMode)
  223. {
  224. WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
  225. if (m_pWiaVideo)
  226. {
  227. m_pWiaVideo->GetCurrentState(&VideoState);
  228. }
  229. if (VideoState == WIAVIDEO_NO_VIDEO)
  230. {
  231. MyEnableToolbarButton( IDC_CAMSEL_TAKE_PICTURE, FALSE );
  232. }
  233. else
  234. {
  235. MyEnableToolbarButton( IDC_CAMSEL_TAKE_PICTURE, TRUE );
  236. }
  237. }
  238. else
  239. {
  240. if (!m_pControllerWindow->m_bTakePictureIsSupported)
  241. {
  242. MyEnableToolbarButton( IDC_CAMSEL_TAKE_PICTURE, FALSE );
  243. }
  244. else
  245. {
  246. MyEnableToolbarButton( IDC_CAMSEL_TAKE_PICTURE, TRUE );
  247. }
  248. }
  249. }
  250. LRESULT CCameraSelectionPage::OnSetActive( WPARAM, LPARAM )
  251. {
  252. WIA_PUSH_FUNCTION((TEXT("CCameraSelectionPage::OnSetActive")));
  253. //
  254. // Make sure we have a valid controller window
  255. //
  256. if (!m_pControllerWindow)
  257. {
  258. return -1;
  259. }
  260. //
  261. // In case it failed the first time, try creating the graph again
  262. //
  263. InitializeVideoCamera();
  264. //
  265. // Update the enabled state for all affected controls
  266. //
  267. UpdateControls();
  268. //
  269. // We do want to exit on disconnect if we are on this page
  270. //
  271. m_pControllerWindow->m_OnDisconnect = CAcquisitionManagerControllerWindow::OnDisconnectGotoLastpage|CAcquisitionManagerControllerWindow::OnDisconnectFailDownload|CAcquisitionManagerControllerWindow::OnDisconnectFailUpload|CAcquisitionManagerControllerWindow::OnDisconnectFailDelete;
  272. return 0;
  273. }
  274. LRESULT CCameraSelectionPage::OnShowWindow( WPARAM, LPARAM )
  275. {
  276. if (!m_bThumbnailsRequested)
  277. {
  278. //
  279. // Request the thumbnails
  280. //
  281. m_pControllerWindow->DownloadAllThumbnails();
  282. //
  283. // Make sure we don't ask for the thumbnails again
  284. //
  285. m_bThumbnailsRequested = true;
  286. }
  287. return 0;
  288. }
  289. LRESULT CCameraSelectionPage::OnDestroy( WPARAM, LPARAM )
  290. {
  291. m_pControllerWindow->m_WindowList.Remove(m_hWnd);
  292. //
  293. // Nuke the imagelists
  294. //
  295. HIMAGELIST hImageList = ListView_SetImageList( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), NULL, LVSIL_NORMAL );
  296. if (hImageList)
  297. {
  298. ImageList_Destroy(hImageList);
  299. }
  300. hImageList = ListView_SetImageList( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), NULL, LVSIL_SMALL );
  301. if (hImageList)
  302. {
  303. ImageList_Destroy(hImageList);
  304. }
  305. if (m_pWiaVideo)
  306. {
  307. HRESULT hr = m_pWiaVideo->DestroyVideo();
  308. }
  309. return 0;
  310. }
  311. LRESULT CCameraSelectionPage::OnInitDialog( WPARAM, LPARAM lParam )
  312. {
  313. WIA_PUSHFUNCTION(TEXT("CCameraSelectionPage::OnInitDialog"));
  314. //
  315. // Make sure this starts out NULL
  316. //
  317. m_pControllerWindow = NULL;
  318. //
  319. // Get the PROPSHEETPAGE.lParam
  320. //
  321. PROPSHEETPAGE *pPropSheetPage = reinterpret_cast<PROPSHEETPAGE*>(lParam);
  322. if (pPropSheetPage)
  323. {
  324. m_pControllerWindow = reinterpret_cast<CAcquisitionManagerControllerWindow*>(pPropSheetPage->lParam);
  325. if (m_pControllerWindow)
  326. {
  327. m_pControllerWindow->m_WindowList.Add(m_hWnd);
  328. }
  329. }
  330. //
  331. // Bail out
  332. //
  333. if (!m_pControllerWindow)
  334. {
  335. EndDialog(m_hWnd,IDCANCEL);
  336. return -1;
  337. }
  338. //
  339. // Get the annotation helper interface and initialize the annotation icon
  340. //
  341. if (SUCCEEDED(CoCreateInstance( CLSID_WiaDefaultUi, NULL,CLSCTX_INPROC_SERVER, IID_IWiaAnnotationHelpers,(void**)&m_pWiaAnnotationHelpers )))
  342. {
  343. m_pWiaAnnotationHelpers->GetAnnotationOverlayIcon( AnnotationAudio, &m_hIconAudioAnnotation, SMALL_ICON_SIZE );
  344. m_pWiaAnnotationHelpers->GetAnnotationOverlayIcon( AnnotationUnknown, &m_hIconMiscellaneousAnnotation, SMALL_ICON_SIZE );
  345. }
  346. //
  347. // Initialize Thumbnail Listview control
  348. //
  349. HWND hwndList = GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS );
  350. if (hwndList)
  351. {
  352. //
  353. // Get the device name for the root folder group
  354. //
  355. if (m_pControllerWindow->m_strwDeviceName.Length())
  356. {
  357. m_GroupInfoList.Add( hwndList, m_pControllerWindow->m_strwDeviceName );
  358. }
  359. //
  360. // Get the number of items
  361. //
  362. LONG nItemCount = m_pControllerWindow->m_WiaItemList.Count();
  363. //
  364. // Hide the labels and use border selection
  365. //
  366. ListView_SetExtendedListViewStyleEx( hwndList, LVS_EX_DOUBLEBUFFER|LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS|LVS_EX_SIMPLESELECT|LVS_EX_CHECKBOXES, LVS_EX_DOUBLEBUFFER|LVS_EX_BORDERSELECT|LVS_EX_HIDELABELS|LVS_EX_SIMPLESELECT|LVS_EX_CHECKBOXES );
  367. //
  368. // Create the image list
  369. //
  370. HIMAGELIST hImageList = ImageList_Create( m_pControllerWindow->m_sizeThumbnails.cx, m_pControllerWindow->m_sizeThumbnails.cy, ILC_COLOR24|ILC_MIRROR, nItemCount, 50 );
  371. if (hImageList)
  372. {
  373. //
  374. // Create the default thumbnail
  375. //
  376. HBITMAP hBmpDefaultThumbnail = WiaUiUtil::CreateIconThumbnail( hwndList, m_pControllerWindow->m_sizeThumbnails.cx, m_pControllerWindow->m_sizeThumbnails.cy, g_hInstance, IDI_UNAVAILABLE, CSimpleString( IDS_DOWNLOADINGTHUMBNAIL, g_hInstance ));
  377. if (hBmpDefaultThumbnail)
  378. {
  379. m_nDefaultThumbnailImageListIndex = ImageList_Add( hImageList, hBmpDefaultThumbnail, NULL );
  380. DeleteObject( hBmpDefaultThumbnail );
  381. }
  382. //
  383. // Set the image list
  384. //
  385. ListView_SetImageList( hwndList, hImageList, LVSIL_NORMAL );
  386. //
  387. // Set the spacing
  388. //
  389. ListView_SetIconSpacing( hwndList, m_pControllerWindow->m_sizeThumbnails.cx + c_nAdditionalMarginX, m_pControllerWindow->m_sizeThumbnails.cy + c_nAdditionalMarginY );
  390. //
  391. // Set the item count, to minimize recomputing the list size
  392. //
  393. ListView_SetItemCount( hwndList, nItemCount );
  394. }
  395. //
  396. // Create a small image list, to prevent the checkbox state images from being resized in WM_SYSCOLORCHANGE
  397. //
  398. HIMAGELIST hImageListSmall = ImageList_Create( GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR24|ILC_MASK, 1, 1 );
  399. if (hImageListSmall)
  400. {
  401. ListView_SetImageList( hwndList, hImageListSmall, LVSIL_SMALL );
  402. }
  403. }
  404. //
  405. // Populate the list view
  406. //
  407. PopulateListView();
  408. //
  409. // Initialize the video camera
  410. //
  411. InitializeVideoCamera();
  412. //
  413. // Dismiss the progress dialog if it is still up
  414. //
  415. if (m_pControllerWindow->m_pWiaProgressDialog)
  416. {
  417. m_pControllerWindow->m_pWiaProgressDialog->Destroy();
  418. m_pControllerWindow->m_pWiaProgressDialog = NULL;
  419. }
  420. //
  421. // Make sure the wizard still has the focus. This weird hack is necessary
  422. // because user seems to think the wizard is already the foreground window,
  423. // so the second call doesn't do anything
  424. //
  425. SetForegroundWindow( m_pControllerWindow->m_hWnd );
  426. SetForegroundWindow( GetParent(m_hWnd) );
  427. if (m_pControllerWindow->m_DeviceTypeMode == CAcquisitionManagerControllerWindow::CameraMode)
  428. {
  429. bool bShowTakePicture = m_pControllerWindow->m_bTakePictureIsSupported;
  430. ToolbarHelper::CButtonDescriptor ActionButtonDescriptors[] =
  431. {
  432. { 0, IDC_CAMSEL_ROTATE_RIGHT, TBSTATE_ENABLED, BTNS_BUTTON, false, NULL, 0 },
  433. { 1, IDC_CAMSEL_ROTATE_LEFT, TBSTATE_ENABLED, BTNS_BUTTON, false, NULL, 0 },
  434. { 2, IDC_CAMSEL_PROPERTIES, TBSTATE_ENABLED, BTNS_BUTTON, bShowTakePicture, NULL, 0 },
  435. { 3, IDC_CAMSEL_TAKE_PICTURE, TBSTATE_ENABLED, BTNS_BUTTON, false, &bShowTakePicture, 0 }
  436. };
  437. HWND hWndActionToolbar = ToolbarHelper::CreateToolbar(
  438. m_hWnd,
  439. GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS),
  440. GetDlgItem(m_hWnd,IDC_CAMSEL_CAMERA_BUTTON_BAR_GUIDE),
  441. ToolbarHelper::AlignLeft|ToolbarHelper::AlignTop,
  442. IDC_ACTION_BUTTON_BAR,
  443. m_CameraActionButtonBarBitmapInfo,
  444. ActionButtonDescriptors,
  445. ARRAYSIZE(ActionButtonDescriptors) );
  446. ToolbarHelper::CButtonDescriptor SelectionButtonDescriptors[] =
  447. {
  448. { -1, IDC_CAMSEL_CLEAR_ALL, TBSTATE_ENABLED, BTNS_BUTTON, true, NULL, IDS_CAMSEL_CLEAR_ALL },
  449. { -1, IDC_CAMSEL_SELECT_ALL, TBSTATE_ENABLED, BTNS_BUTTON, false, NULL, IDS_CAMSEL_SELECT_ALL }
  450. };
  451. HWND hWndSelectionToolbar = ToolbarHelper::CreateToolbar(
  452. m_hWnd,
  453. hWndActionToolbar,
  454. GetDlgItem(m_hWnd,IDC_CAMSEL_CAMERA_BUTTON_BAR_GUIDE),
  455. ToolbarHelper::AlignRight|ToolbarHelper::AlignTop,
  456. IDC_SELECTION_BUTTON_BAR,
  457. m_CameraSelectionButtonBarBitmapInfo,
  458. SelectionButtonDescriptors,
  459. ARRAYSIZE(SelectionButtonDescriptors) );
  460. //
  461. // Nuke the guide window
  462. //
  463. DestroyWindow( GetDlgItem(m_hWnd,IDC_CAMSEL_CAMERA_BUTTON_BAR_GUIDE) );
  464. //
  465. // Make sure the toolbars are visible
  466. //
  467. ShowWindow( hWndActionToolbar, SW_SHOW );
  468. UpdateWindow( hWndActionToolbar );
  469. ShowWindow( hWndSelectionToolbar, SW_SHOW );
  470. UpdateWindow( hWndSelectionToolbar );
  471. }
  472. else
  473. {
  474. ToolbarHelper::CButtonDescriptor TakePictureButtonDescriptors[] =
  475. {
  476. { 3, IDC_CAMSEL_TAKE_PICTURE, TBSTATE_ENABLED, BTNS_BUTTON, false, NULL, IDS_CAMSEL_TAKE_PICTURE }
  477. };
  478. HWND hWndTakePictureToolbar = ToolbarHelper::CreateToolbar(
  479. m_hWnd,
  480. GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS),
  481. GetDlgItem(m_hWnd,IDC_CAMSEL_VIDEO_PREVIEW_BUTTON_BAR_GUIDE),
  482. ToolbarHelper::AlignHCenter|ToolbarHelper::AlignTop,
  483. IDC_TAKEPICTURE_BUTTON_BAR,
  484. m_CameraTakePictureButtonBarBitmapInfo,
  485. TakePictureButtonDescriptors,
  486. ARRAYSIZE(TakePictureButtonDescriptors) );
  487. ToolbarHelper::CButtonDescriptor ActionButtonDescriptors[] =
  488. {
  489. { 0, IDC_CAMSEL_ROTATE_RIGHT, TBSTATE_ENABLED, BTNS_BUTTON, false, NULL, 0 },
  490. { 1, IDC_CAMSEL_ROTATE_LEFT, TBSTATE_ENABLED, BTNS_BUTTON, false, NULL, 0 },
  491. { 2, IDC_CAMSEL_PROPERTIES, TBSTATE_ENABLED, BTNS_BUTTON, true, NULL, 0 }
  492. };
  493. HWND hWndActionToolbar = ToolbarHelper::CreateToolbar(
  494. m_hWnd,
  495. hWndTakePictureToolbar,
  496. GetDlgItem(m_hWnd,IDC_CAMSEL_VIDEO_SELECTION_BUTTON_BAR_GUIDE),
  497. ToolbarHelper::AlignLeft|ToolbarHelper::AlignTop,
  498. IDC_ACTION_BUTTON_BAR,
  499. m_CameraActionButtonBarBitmapInfo,
  500. ActionButtonDescriptors,
  501. ARRAYSIZE(ActionButtonDescriptors) );
  502. ToolbarHelper::CButtonDescriptor SelectionButtonDescriptors[] =
  503. {
  504. { -1, IDC_CAMSEL_CLEAR_ALL, TBSTATE_ENABLED, BTNS_BUTTON, true, NULL, IDS_CAMSEL_CLEAR_ALL },
  505. { -1, IDC_CAMSEL_SELECT_ALL, TBSTATE_ENABLED, BTNS_BUTTON, false, NULL, IDS_CAMSEL_SELECT_ALL }
  506. };
  507. HWND hWndSelectionToolbar = ToolbarHelper::CreateToolbar(
  508. m_hWnd,
  509. hWndActionToolbar,
  510. GetDlgItem(m_hWnd,IDC_CAMSEL_VIDEO_SELECTION_BUTTON_BAR_GUIDE),
  511. ToolbarHelper::AlignRight|ToolbarHelper::AlignTop,
  512. IDC_SELECTION_BUTTON_BAR,
  513. m_CameraSelectionButtonBarBitmapInfo,
  514. SelectionButtonDescriptors,
  515. ARRAYSIZE(SelectionButtonDescriptors) );
  516. //
  517. // Nuke the guide windows
  518. //
  519. DestroyWindow( GetDlgItem(m_hWnd,IDC_CAMSEL_VIDEO_PREVIEW_BUTTON_BAR_GUIDE) );
  520. DestroyWindow( GetDlgItem(m_hWnd,IDC_CAMSEL_VIDEO_SELECTION_BUTTON_BAR_GUIDE) );
  521. //
  522. // Make sure the toolbars are visible
  523. //
  524. ShowWindow( hWndTakePictureToolbar, SW_SHOW );
  525. UpdateWindow( hWndTakePictureToolbar );
  526. ShowWindow( hWndActionToolbar, SW_SHOW );
  527. UpdateWindow( hWndActionToolbar );
  528. ShowWindow( hWndSelectionToolbar, SW_SHOW );
  529. UpdateWindow( hWndSelectionToolbar );
  530. }
  531. m_hAccelerators = LoadAccelerators( g_hInstance, MAKEINTRESOURCE(IDR_CAMERASELECTIONACCEL) );
  532. return 0;
  533. }
  534. LRESULT CCameraSelectionPage::OnTranslateAccelerator( WPARAM, LPARAM lParam )
  535. {
  536. //
  537. // Assume we won't be handling this message
  538. //
  539. LRESULT lResult = PSNRET_NOERROR;
  540. //
  541. // Make sure this is the current window
  542. //
  543. if (PropSheet_GetCurrentPageHwnd(GetParent(m_hWnd)) == m_hWnd)
  544. {
  545. //
  546. // Make sure we have a valid accelerator table
  547. //
  548. if (m_hAccelerators)
  549. {
  550. //
  551. // Get the WM_NOTIFY message goo for this message
  552. //
  553. PSHNOTIFY *pPropSheetNotify = reinterpret_cast<PSHNOTIFY*>(lParam);
  554. if (pPropSheetNotify)
  555. {
  556. //
  557. // Get the MSG
  558. //
  559. MSG *pMsg = reinterpret_cast<MSG*>(pPropSheetNotify->lParam);
  560. if (pMsg)
  561. {
  562. //
  563. // Try to translate the accelerator
  564. //
  565. if (TranslateAccelerator( m_hWnd, m_hAccelerators, pMsg ))
  566. {
  567. //
  568. // If we were able to
  569. //
  570. lResult = PSNRET_MESSAGEHANDLED;
  571. }
  572. }
  573. }
  574. }
  575. }
  576. return lResult;
  577. }
  578. void CCameraSelectionPage::InitializeVideoCamera(void)
  579. {
  580. //
  581. // Make sure this is a video camera
  582. //
  583. if (m_pControllerWindow->m_DeviceTypeMode != CAcquisitionManagerControllerWindow::VideoMode)
  584. {
  585. return;
  586. }
  587. HRESULT hr = S_OK;
  588. WIAVIDEO_STATE VideoState = WIAVIDEO_NO_VIDEO;
  589. CSimpleStringWide strImagesDirectory;
  590. if (m_pWiaVideo == NULL)
  591. {
  592. hr = CoCreateInstance(CLSID_WiaVideo,
  593. NULL,
  594. CLSCTX_INPROC_SERVER,
  595. IID_IWiaVideo,
  596. (void**) &m_pWiaVideo);
  597. }
  598. //
  599. // No point continuing if we can't create the video interface
  600. //
  601. if (!m_pWiaVideo)
  602. {
  603. return;
  604. }
  605. if (hr == S_OK)
  606. {
  607. BOOL bSuccess = FALSE;
  608. //
  609. // Get the IMAGES_DIRECTORY property from the Wia Video Driver.
  610. //
  611. bSuccess = PropStorageHelpers::GetProperty(m_pControllerWindow->m_pWiaItemRoot,
  612. WIA_DPV_IMAGES_DIRECTORY,
  613. strImagesDirectory);
  614. if (!bSuccess)
  615. {
  616. hr = E_FAIL;
  617. }
  618. }
  619. if (hr == S_OK)
  620. {
  621. //
  622. // Get the current state of the WiaVideo object. If we just created it
  623. // then the state will be NO_VIDEO, otherwise, it could already be previewing video,
  624. // in which case we shouldn't do anything.
  625. //
  626. hr = m_pWiaVideo->GetCurrentState(&VideoState);
  627. if (VideoState == WIAVIDEO_NO_VIDEO)
  628. {
  629. //
  630. // Set the directory we want to save our images to. We got the image directory
  631. // from the Wia Video Driver IMAGES_DIRECTORY property
  632. //
  633. if (hr == S_OK)
  634. {
  635. hr = m_pWiaVideo->put_ImagesDirectory(CSimpleBStr(strImagesDirectory));
  636. }
  637. //
  638. // Create the video preview as a child of the IDC_VIDSEL_PREVIEW dialog item
  639. // and automatically begin playback after creating the preview.
  640. //
  641. if (hr == S_OK)
  642. {
  643. hr = m_pWiaVideo->CreateVideoByWiaDevID(
  644. CSimpleBStr(m_pControllerWindow->m_pEventParameters->strDeviceID),
  645. GetDlgItem(m_hWnd, IDC_VIDSEL_PREVIEW),
  646. FALSE,
  647. TRUE);
  648. }
  649. }
  650. }
  651. //
  652. // If there was a failure, tell the user
  653. //
  654. if (hr != S_OK)
  655. {
  656. CSimpleString( IDS_VIDEOPREVIEWUNAVAILABLE, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_VIDSEL_PREVIEW ) );
  657. }
  658. else
  659. {
  660. SetWindowText( GetDlgItem( m_hWnd, IDC_VIDSEL_PREVIEW ), TEXT("") );
  661. }
  662. }
  663. CWiaItem *CCameraSelectionPage::GetItemFromListByIndex( HWND hwndList, int nItem )
  664. {
  665. LVITEM LvItem;
  666. ZeroMemory( &LvItem, sizeof(LvItem) );
  667. LvItem.iItem = nItem;
  668. LvItem.mask = LVIF_PARAM;
  669. if (ListView_GetItem( hwndList, &LvItem ))
  670. {
  671. return reinterpret_cast<CWiaItem*>(LvItem.lParam);
  672. }
  673. return NULL;
  674. }
  675. int CCameraSelectionPage::FindItemListIndex( HWND hwndList, CWiaItem *pWiaItem )
  676. {
  677. for (int i=0;i<ListView_GetItemCount(hwndList);i++)
  678. {
  679. CWiaItem *pItem = GetItemFromListByIndex( hwndList, i );
  680. if (pWiaItem && pWiaItem == pItem)
  681. return i;
  682. }
  683. return -1;
  684. }
  685. void CCameraSelectionPage::DrawAnnotationIcons( HDC hDC, CWiaItem *pWiaItem, HBITMAP hBitmap )
  686. {
  687. if (hDC && hBitmap && pWiaItem)
  688. {
  689. //
  690. // Create a memory DC
  691. //
  692. HDC hMemDC = CreateCompatibleDC( hDC );
  693. if (hMemDC)
  694. {
  695. //
  696. // Select the bitmap into the memory DC
  697. //
  698. HBITMAP hOldBitmap = SelectBitmap( hMemDC, hBitmap );
  699. //
  700. // Assume we will not neen an annotation icon
  701. //
  702. HICON hIcon = NULL;
  703. //
  704. // Figure out which icon to use
  705. //
  706. CAnnotationType AnnotationType = pWiaItem->AnnotationType();
  707. if (AnnotationAudio == AnnotationType)
  708. {
  709. hIcon = m_hIconAudioAnnotation;
  710. }
  711. else if (AnnotationUnknown == AnnotationType)
  712. {
  713. hIcon = m_hIconMiscellaneousAnnotation;
  714. }
  715. //
  716. // If we need an annotation icon
  717. //
  718. if (hIcon)
  719. {
  720. //
  721. // Get the icon's dimensions
  722. //
  723. SIZE sizeIcon = {0};
  724. if (PrintScanUtil::GetIconSize( hIcon, sizeIcon ))
  725. {
  726. //
  727. // Get the bitmap's dimensions
  728. //
  729. SIZE sizeBitmap = {0};
  730. if (PrintScanUtil::GetBitmapSize( hBitmap, sizeBitmap ))
  731. {
  732. //
  733. // Set up a good margin for this icon, so it isn't right up against the edge
  734. //
  735. const int nMargin = 3;
  736. //
  737. // Draw the icon
  738. //
  739. DrawIconEx( hMemDC, sizeBitmap.cx-sizeIcon.cx-nMargin, sizeBitmap.cy-sizeIcon.cy-nMargin, hIcon, sizeIcon.cx, sizeIcon.cy, 0, NULL, DI_NORMAL );
  740. }
  741. }
  742. }
  743. //
  744. // Restore the old bitmap and delete the DC
  745. //
  746. SelectBitmap( hMemDC, hOldBitmap );
  747. DeleteDC(hMemDC);
  748. }
  749. }
  750. }
  751. int CCameraSelectionPage::AddThumbnailToListViewImageList( HWND hwndList, CWiaItem *pWiaItem, int nIndex )
  752. {
  753. WIA_PUSH_FUNCTION((TEXT("CCameraSelectionPage::AddThumbnailToListViewImageList")));
  754. //
  755. // Assume we have the default thumbnail. If there are any problems, this is what we will use.
  756. //
  757. int nImageListIndex = m_nDefaultThumbnailImageListIndex;
  758. //
  759. // Make sure we have a valid item
  760. //
  761. if (pWiaItem)
  762. {
  763. //
  764. // We need a DC to create and scale the thumbnail
  765. //
  766. HDC hDC = GetDC(m_hWnd);
  767. if (hDC)
  768. {
  769. //
  770. // Is there a valid thumbnail for this image? If so, prepare it.
  771. //
  772. HBITMAP hThumbnail = pWiaItem->CreateThumbnailBitmap( m_hWnd, m_GdiPlusHelper, m_pControllerWindow->m_sizeThumbnails.cx, m_pControllerWindow->m_sizeThumbnails.cy );
  773. if (hThumbnail)
  774. {
  775. //
  776. // Draw any annotation icons
  777. //
  778. DrawAnnotationIcons( hDC, pWiaItem, hThumbnail );
  779. //
  780. // Find out if we already have a thumbnail in the list
  781. // If we do have a thumbnail, we want to replace it in the image list
  782. //
  783. LVITEM LvItem = {0};
  784. LvItem.mask = LVIF_IMAGE;
  785. LvItem.iItem = nIndex;
  786. if (ListView_GetItem( hwndList, &LvItem ) && LvItem.iImage != m_nDefaultThumbnailImageListIndex)
  787. {
  788. //
  789. // Get the image list
  790. //
  791. HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
  792. if (hImageList)
  793. {
  794. //
  795. // Replace the image and save the index
  796. //
  797. if (ImageList_Replace( hImageList, LvItem.iImage, hThumbnail, NULL ))
  798. {
  799. nImageListIndex = LvItem.iImage;
  800. }
  801. }
  802. }
  803. else
  804. {
  805. //
  806. // Get the image list
  807. //
  808. HIMAGELIST hImageList = ListView_GetImageList( hwndList, LVSIL_NORMAL );
  809. if (hImageList)
  810. {
  811. //
  812. // Add this image to the listview's imagelist and save the index
  813. //
  814. nImageListIndex = ImageList_Add( hImageList, hThumbnail, NULL );
  815. }
  816. }
  817. //
  818. // Delete the thumbnail to prevent a leak
  819. //
  820. DeleteBitmap(hThumbnail);
  821. }
  822. //
  823. // Release the client DC
  824. //
  825. ReleaseDC( m_hWnd, hDC );
  826. }
  827. }
  828. //
  829. // Return the index of the image in the imagelist
  830. //
  831. return nImageListIndex;
  832. }
  833. int CCameraSelectionPage::AddItem( HWND hwndList, CWiaItem *pWiaItem, bool bEnsureVisible )
  834. {
  835. //
  836. // Prevent handling of change notifications while we do this.
  837. //
  838. m_nProgrammaticSetting++;
  839. int nResult = -1;
  840. if (pWiaItem && hwndList)
  841. {
  842. //
  843. // Find out where we are going to insert this image
  844. //
  845. int nIndex = ListView_GetItemCount( hwndList );
  846. //
  847. // Add or replace the thumbnail
  848. //
  849. int nImageListIndex = AddThumbnailToListViewImageList( hwndList, pWiaItem, nIndex );
  850. if (nImageListIndex >= 0)
  851. {
  852. //
  853. // Get the item ready to insert and insert it
  854. //
  855. LVITEM lvItem = {0};
  856. lvItem.iItem = nIndex;
  857. lvItem.mask = LVIF_IMAGE|LVIF_PARAM|LVIF_STATE|LVIF_GROUPID;
  858. lvItem.iImage = nImageListIndex;
  859. lvItem.lParam = reinterpret_cast<LPARAM>(pWiaItem);
  860. lvItem.state = !nIndex ? LVIS_SELECTED|LVIS_FOCUSED : 0;
  861. lvItem.iGroupId = m_GroupInfoList.GetGroupId(pWiaItem,hwndList);
  862. nResult = ListView_InsertItem( hwndList, &lvItem );
  863. if (nResult >= 0)
  864. {
  865. //
  866. // Set the check if the item is selected
  867. //
  868. ListView_SetCheckState( hwndList, nIndex, pWiaItem->SelectedForDownload() );
  869. //
  870. // Ensure the item is visible, if necessary
  871. //
  872. if (bEnsureVisible)
  873. {
  874. ListView_EnsureVisible( hwndList, nResult, FALSE );
  875. }
  876. }
  877. }
  878. }
  879. //
  880. // Enable handling of change notifications
  881. //
  882. m_nProgrammaticSetting--;
  883. return nResult;
  884. }
  885. void CCameraSelectionPage::AddEnumeratedItems( HWND hwndList, CWiaItem *pFirstItem )
  886. {
  887. //
  888. // First, enumerate all of the images on this level and add them
  889. //
  890. CWiaItem *pCurrItem = pFirstItem;
  891. while (pCurrItem)
  892. {
  893. if (pCurrItem->IsDownloadableItemType())
  894. {
  895. AddItem( hwndList, pCurrItem );
  896. }
  897. pCurrItem = pCurrItem->Next();
  898. }
  899. //
  900. // Now look for children, and recursively add them
  901. //
  902. pCurrItem = pFirstItem;
  903. while (pCurrItem)
  904. {
  905. AddEnumeratedItems( hwndList, pCurrItem->Children() );
  906. pCurrItem = pCurrItem->Next();
  907. }
  908. }
  909. void CCameraSelectionPage::PopulateListView(void)
  910. {
  911. HWND hwndList = GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS );
  912. if (hwndList)
  913. {
  914. //
  915. // Tell the window not to redraw while we add these items
  916. //
  917. SendMessage( hwndList, WM_SETREDRAW, FALSE, 0 );
  918. //
  919. // Begin recursively adding all of the items
  920. //
  921. AddEnumeratedItems( hwndList, m_pControllerWindow->m_WiaItemList.Root() );
  922. //
  923. // If we have any folders, allow group view
  924. //
  925. if (m_GroupInfoList.Size() > 1)
  926. {
  927. ListView_EnableGroupView( hwndList, TRUE );
  928. }
  929. //
  930. // Tell the window to redraw now, because we are done. Invalidate the window, in case it is visible
  931. //
  932. SendMessage( hwndList, WM_SETREDRAW, TRUE, 0 );
  933. InvalidateRect( hwndList, NULL, FALSE );
  934. }
  935. }
  936. int CCameraSelectionPage::GetSelectionIndices( CSimpleDynamicArray<int> &aIndices )
  937. {
  938. HWND hwndList = GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS );
  939. if (!hwndList)
  940. return(0);
  941. int iCount = ListView_GetItemCount(hwndList);
  942. for (int i=0;i<iCount;i++)
  943. if (ListView_GetItemState(hwndList,i,LVIS_SELECTED) & LVIS_SELECTED)
  944. aIndices.Append(i);
  945. return(aIndices.Size());
  946. }
  947. // This function gets called in response to an image downloading. We're only interested in items being deleted.
  948. void CCameraSelectionPage::OnNotifyDownloadImage( UINT nMsg, CThreadNotificationMessage *pThreadNotificationMessage )
  949. {
  950. CDownloadImagesThreadNotifyMessage *pDownloadImageThreadNotifyMessage = dynamic_cast<CDownloadImagesThreadNotifyMessage*>(pThreadNotificationMessage);
  951. if (pDownloadImageThreadNotifyMessage && m_pControllerWindow)
  952. {
  953. switch (pDownloadImageThreadNotifyMessage->Status())
  954. {
  955. case CDownloadImagesThreadNotifyMessage::End:
  956. {
  957. switch (pDownloadImageThreadNotifyMessage->Operation())
  958. {
  959. case CDownloadImagesThreadNotifyMessage::DownloadAll:
  960. {
  961. //
  962. // Make sure the download was successful, and not cancelled
  963. //
  964. if (S_OK == pDownloadImageThreadNotifyMessage->hr())
  965. {
  966. //
  967. // Mark each successfully downloaded image as not-downloadable, and clear its selection state
  968. //
  969. for (int i=0;i<pDownloadImageThreadNotifyMessage->DownloadedFileInformation().Size();i++)
  970. {
  971. CWiaItem *pWiaItem = m_pControllerWindow->m_WiaItemList.Find( pDownloadImageThreadNotifyMessage->DownloadedFileInformation()[i].Cookie() );
  972. if (pWiaItem)
  973. {
  974. pWiaItem->SelectedForDownload( false );
  975. int nItem = FindItemListIndex( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), pWiaItem );
  976. if (nItem >= 0)
  977. {
  978. ListView_SetCheckState( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), nItem, FALSE );
  979. }
  980. }
  981. }
  982. }
  983. }
  984. break;
  985. }
  986. }
  987. break;
  988. }
  989. }
  990. }
  991. // This function gets called in response to a thumbnail download finishing.
  992. void CCameraSelectionPage::OnNotifyDownloadThumbnail( UINT nMsg, CThreadNotificationMessage *pThreadNotificationMessage )
  993. {
  994. CDownloadThumbnailsThreadNotifyMessage *pDownloadThumbnailsThreadNotifyMessage= dynamic_cast<CDownloadThumbnailsThreadNotifyMessage*>(pThreadNotificationMessage);
  995. if (pDownloadThumbnailsThreadNotifyMessage)
  996. {
  997. switch (pDownloadThumbnailsThreadNotifyMessage->Status())
  998. {
  999. case CDownloadThumbnailsThreadNotifyMessage::End:
  1000. {
  1001. switch (pDownloadThumbnailsThreadNotifyMessage->Operation())
  1002. {
  1003. case CDownloadThumbnailsThreadNotifyMessage::DownloadThumbnail:
  1004. {
  1005. // Find the item in the list
  1006. CWiaItem *pWiaItem = m_pControllerWindow->m_WiaItemList.Find( pDownloadThumbnailsThreadNotifyMessage->Cookie() );
  1007. if (pWiaItem)
  1008. {
  1009. int nItem = FindItemListIndex( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), pWiaItem );
  1010. if (nItem >= 0)
  1011. {
  1012. int nImageListIndex = AddThumbnailToListViewImageList( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), pWiaItem, nItem );
  1013. if (nImageListIndex >= 0)
  1014. {
  1015. LVITEM LvItem;
  1016. ZeroMemory( &LvItem, sizeof(LvItem) );
  1017. LvItem.iItem = nItem;
  1018. LvItem.mask = LVIF_IMAGE;
  1019. LvItem.iImage = nImageListIndex;
  1020. ListView_SetItem( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), &LvItem );
  1021. if (PropSheet_GetCurrentPageHwnd(GetParent(m_hWnd)) == m_hWnd)
  1022. {
  1023. UpdateControls();
  1024. }
  1025. }
  1026. }
  1027. }
  1028. }
  1029. break;
  1030. }
  1031. }
  1032. break;
  1033. }
  1034. }
  1035. }
  1036. LRESULT CCameraSelectionPage::OnThumbnailListSelChange( WPARAM wParam, LPARAM lParam )
  1037. {
  1038. WIA_PUSHFUNCTION(TEXT("CCameraSelectionPage::OnThumbnailListSelChange"));
  1039. if (!m_nProgrammaticSetting)
  1040. {
  1041. NMLISTVIEW *pNmListView = reinterpret_cast<NMLISTVIEW*>(lParam);
  1042. if (pNmListView)
  1043. {
  1044. WIA_TRACE((TEXT("pNmListView->uChanged: %08X, pNmListView->uOldState: %08X, pNmListView->uNewState: %08X"), pNmListView->uChanged, pNmListView->uOldState, pNmListView->uNewState ));
  1045. //
  1046. // If this is a check state change
  1047. //
  1048. if ((pNmListView->uChanged & LVIF_STATE) && ((pNmListView->uOldState&LVIS_STATEIMAGEMASK) ^ (pNmListView->uNewState&LVIS_STATEIMAGEMASK)))
  1049. {
  1050. //
  1051. // Get the item * from the LVITEM structure
  1052. //
  1053. CWiaItem *pWiaItem = reinterpret_cast<CWiaItem *>(pNmListView->lParam);
  1054. if (pWiaItem)
  1055. {
  1056. //
  1057. // Set selected flag in the item
  1058. //
  1059. pWiaItem->SelectedForDownload( IsStateChecked(pNmListView->uNewState) );
  1060. //
  1061. // If this is the current page, update the control state
  1062. //
  1063. if (PropSheet_GetCurrentPageHwnd(GetParent(m_hWnd)) == m_hWnd)
  1064. {
  1065. UpdateControls();
  1066. }
  1067. }
  1068. }
  1069. else if ((pNmListView->uChanged & LVIF_STATE) && ((pNmListView->uOldState&LVIS_SELECTED) ^ (pNmListView->uNewState&LVIS_SELECTED)))
  1070. {
  1071. //
  1072. // If this is the current page, update the control state
  1073. //
  1074. if (PropSheet_GetCurrentPageHwnd(GetParent(m_hWnd)) == m_hWnd)
  1075. {
  1076. UpdateControls();
  1077. }
  1078. }
  1079. }
  1080. }
  1081. return 0;
  1082. }
  1083. void CCameraSelectionPage::OnProperties( WPARAM, LPARAM )
  1084. {
  1085. CSimpleDynamicArray<int> aSelIndices;
  1086. if (GetSelectionIndices( aSelIndices ))
  1087. {
  1088. if (aSelIndices.Size() == 1)
  1089. {
  1090. CWiaItem *pWiaItem = GetItemFromListByIndex( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), aSelIndices[0]);
  1091. if (pWiaItem && pWiaItem->WiaItem())
  1092. {
  1093. m_pControllerWindow->m_pThreadMessageQueue->Pause();
  1094. HRESULT hr = WiaUiUtil::SystemPropertySheet( g_hInstance, m_hWnd, pWiaItem->WiaItem(), CSimpleString(IDS_ADVANCEDPROPERTIES, g_hInstance) );
  1095. m_pControllerWindow->m_pThreadMessageQueue->Resume();
  1096. if (FAILED(hr))
  1097. {
  1098. CMessageBoxEx::MessageBox( m_hWnd, CSimpleString( IDS_PROPERTY_SHEET_ERROR, g_hInstance ), CSimpleString( IDS_ERROR_TITLE, g_hInstance ), CMessageBoxEx::MBEX_ICONINFORMATION );
  1099. }
  1100. }
  1101. }
  1102. }
  1103. }
  1104. void CCameraSelectionPage::OnSelectAll( WPARAM, LPARAM )
  1105. {
  1106. HWND hwndList = GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS);
  1107. if (hwndList)
  1108. {
  1109. ListView_SetCheckState( hwndList, -1, TRUE );
  1110. }
  1111. }
  1112. void CCameraSelectionPage::OnClearAll( WPARAM, LPARAM )
  1113. {
  1114. HWND hwndList = GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS);
  1115. if (hwndList)
  1116. {
  1117. ListView_SetCheckState( hwndList, -1, FALSE );
  1118. }
  1119. }
  1120. LRESULT CCameraSelectionPage::OnThumbnailListKeyDown( WPARAM, LPARAM lParam )
  1121. {
  1122. NMLVKEYDOWN *pNmLvKeyDown = reinterpret_cast<NMLVKEYDOWN*>(lParam);
  1123. bool bControl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
  1124. bool bShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
  1125. bool bAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;
  1126. if (pNmLvKeyDown->wVKey == TEXT('A') && bControl && !bShift && !bAlt)
  1127. {
  1128. SendMessage( m_hWnd, WM_COMMAND, MAKEWPARAM(IDC_CAMSEL_SELECT_ALL,0), 0 );
  1129. }
  1130. #if defined(VAISHALEE_LETS_ME_PUT_DELETE_IN)
  1131. else if (VK_DELETE == pNmLvKeyDown->wVKey && !bAlt && !bControl && !bShift)
  1132. {
  1133. SendMessage( m_hWnd, WM_COMMAND, MAKEWPARAM(IDC_CAMSEL_DELETE,0), 0 );
  1134. }
  1135. #endif
  1136. return 0;
  1137. }
  1138. void CCameraSelectionPage::OnTakePicture( WPARAM, LPARAM )
  1139. {
  1140. WIA_PUSH_FUNCTION((TEXT("CCameraSelectionPage::OnTakePicture")));
  1141. if (m_pControllerWindow->m_bTakePictureIsSupported)
  1142. {
  1143. CWaitCursor wc;
  1144. //
  1145. // Tell the user we are taking a picture
  1146. //
  1147. CSimpleString( IDS_TAKING_PICTURE, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMSEL_STATUS ) );
  1148. HRESULT hr = S_OK;
  1149. //
  1150. // If we are not a video camera, just tell the device to snap a picture
  1151. //
  1152. if (m_pControllerWindow->m_DeviceTypeMode == CAcquisitionManagerControllerWindow::CameraMode)
  1153. {
  1154. CComPtr<IWiaItem> pNewWiaItem;
  1155. hr = m_pControllerWindow->m_pWiaItemRoot->DeviceCommand(0,&WIA_CMD_TAKE_PICTURE,&pNewWiaItem);
  1156. }
  1157. else if (m_pWiaVideo)
  1158. {
  1159. //
  1160. // Take the picture
  1161. //
  1162. BSTR bstrNewImageFileName = NULL;
  1163. hr = m_pWiaVideo->TakePicture(&bstrNewImageFileName);
  1164. if (hr == S_OK)
  1165. {
  1166. //
  1167. // Succeeded in taking the picture, setting the LAST_PICTURE_TAKEN property
  1168. // on the video driver to create a new item.
  1169. //
  1170. PROPVARIANT pv = {0};
  1171. PropVariantInit(&pv);
  1172. pv.vt = VT_BSTR;
  1173. pv.bstrVal = bstrNewImageFileName;
  1174. BOOL bSuccess = PropStorageHelpers::SetProperty( m_pControllerWindow->m_pWiaItemRoot, WIA_DPV_LAST_PICTURE_TAKEN, pv );
  1175. if (!bSuccess)
  1176. {
  1177. hr = E_FAIL;
  1178. WIA_PRINTHRESULT((hr,TEXT("PropStorageHelpers::SetProperty failed")));
  1179. }
  1180. //
  1181. // Note that this will free the bstrNewImageFileName returned to
  1182. // us by WiaVideo
  1183. //
  1184. PropVariantClear(&pv);
  1185. }
  1186. else
  1187. {
  1188. WIA_PRINTHRESULT((hr,TEXT("m_pWiaVideo->TakePicture failed")));
  1189. }
  1190. }
  1191. //
  1192. // Clear the status
  1193. //
  1194. if (SUCCEEDED(hr))
  1195. {
  1196. SetWindowText( GetDlgItem( m_hWnd, IDC_CAMSEL_STATUS ), TEXT("") );
  1197. }
  1198. else
  1199. {
  1200. MessageBeep(MB_ICONEXCLAMATION);
  1201. CSimpleString( IDS_UNABLE_TO_TAKE_PICTURE, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMSEL_STATUS ) );
  1202. WIA_PRINTHRESULT((hr,TEXT("Take picture failed")));
  1203. }
  1204. }
  1205. }
  1206. void CCameraSelectionPage::OnRotate( WPARAM wParam, LPARAM )
  1207. {
  1208. //
  1209. // This could take a while for a lot of images, especially since we don't cache DIBs,
  1210. // so we'll display an hourglass cursor here.
  1211. //
  1212. CWaitCursor wc;
  1213. bool bAtLeastOneWasSuccessful = false;
  1214. bool bAtLeastOneWasInitialized = false;
  1215. CSimpleDynamicArray<int> aIndices;
  1216. if (CCameraSelectionPage::GetSelectionIndices( aIndices ))
  1217. {
  1218. for (int i=0;i<aIndices.Size();i++)
  1219. {
  1220. CWiaItem *pWiaItem = GetItemFromListByIndex( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS), aIndices[i] );
  1221. if (pWiaItem)
  1222. {
  1223. if (pWiaItem->RotationEnabled(true))
  1224. {
  1225. bool bRotateRight = true;
  1226. if (IDC_CAMSEL_ROTATE_LEFT == LOWORD(wParam))
  1227. {
  1228. bRotateRight = false;
  1229. }
  1230. pWiaItem->Rotate(bRotateRight);
  1231. int nImageListIndex = AddThumbnailToListViewImageList( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS), pWiaItem, aIndices[i] );
  1232. LVITEM LvItem;
  1233. ZeroMemory( &LvItem, sizeof(LvItem) );
  1234. LvItem.iItem = aIndices[i];
  1235. LvItem.mask = LVIF_IMAGE;
  1236. LvItem.iImage = nImageListIndex;
  1237. ListView_SetItem( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS), &LvItem );
  1238. bAtLeastOneWasSuccessful = true;
  1239. }
  1240. //
  1241. // We don't want to warn the user about failure to rotate images for which we haven't downloaded the preferred format
  1242. //
  1243. else if (pWiaItem->DefaultFormat() == IID_NULL)
  1244. {
  1245. bAtLeastOneWasSuccessful = true;
  1246. }
  1247. else
  1248. {
  1249. bAtLeastOneWasInitialized = true;
  1250. }
  1251. }
  1252. }
  1253. //
  1254. // If not one picture could be rotated AND at least one had already been initialized, warn the user
  1255. //
  1256. if (!bAtLeastOneWasSuccessful && bAtLeastOneWasInitialized)
  1257. {
  1258. //
  1259. // Beep and tell the user
  1260. //
  1261. MessageBeep(MB_ICONEXCLAMATION);
  1262. CSimpleString( IDS_UNABLETOROTATE, g_hInstance ).SetWindowText( GetDlgItem( m_hWnd, IDC_CAMSEL_STATUS ) );
  1263. }
  1264. //
  1265. // Repaint the items
  1266. //
  1267. ListView_RedrawItems( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS), aIndices[0], aIndices[aIndices.Size()-1] );
  1268. //
  1269. // Force an immediate update
  1270. //
  1271. UpdateWindow( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS) );
  1272. }
  1273. }
  1274. LRESULT CCameraSelectionPage::OnEventNotification( WPARAM, LPARAM lParam )
  1275. {
  1276. WIA_PUSH_FUNCTION((TEXT("CCommonFirstPage::OnEventNotification") ));
  1277. CGenericWiaEventHandler::CEventMessage *pEventMessage = reinterpret_cast<CGenericWiaEventHandler::CEventMessage *>(lParam);
  1278. if (pEventMessage)
  1279. {
  1280. //
  1281. // Handle the deleted item event
  1282. //
  1283. if (pEventMessage->EventId() == WIA_EVENT_ITEM_DELETED)
  1284. {
  1285. //
  1286. // Try to find this item in the item list
  1287. //
  1288. CWiaItem *pWiaItem = m_pControllerWindow->FindItemByName( pEventMessage->FullItemName() );
  1289. if (pWiaItem)
  1290. {
  1291. //
  1292. // Find the item in the listview and delete it from the listview
  1293. //
  1294. int nItem = FindItemListIndex( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), pWiaItem );
  1295. if (nItem >= 0)
  1296. {
  1297. ListView_DeleteItem( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), nItem );
  1298. }
  1299. }
  1300. if (PropSheet_GetCurrentPageHwnd(GetParent(m_hWnd)) == m_hWnd)
  1301. {
  1302. UpdateControls();
  1303. }
  1304. }
  1305. else if (pEventMessage->EventId() == WIA_EVENT_ITEM_CREATED)
  1306. {
  1307. //
  1308. // Make sure we have a valid controller window
  1309. //
  1310. //
  1311. // Find the new item
  1312. //
  1313. CWiaItem *pWiaItem = m_pControllerWindow->FindItemByName( pEventMessage->FullItemName() );
  1314. if (pWiaItem)
  1315. {
  1316. //
  1317. // If this is the current page, select the image.
  1318. //
  1319. if (PropSheet_GetCurrentPageHwnd(GetParent(m_hWnd)) == m_hWnd)
  1320. {
  1321. pWiaItem->SelectedForDownload(true);
  1322. }
  1323. //
  1324. // Make sure it isn't already in the list
  1325. //
  1326. if (FindItemListIndex( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), pWiaItem ) < 0)
  1327. {
  1328. //
  1329. // Add it to the list view
  1330. //
  1331. AddItem( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), pWiaItem, true );
  1332. }
  1333. }
  1334. if (PropSheet_GetCurrentPageHwnd(GetParent(m_hWnd)) == m_hWnd)
  1335. {
  1336. UpdateControls();
  1337. }
  1338. }
  1339. //
  1340. // Don't delete the message, it is deleted in the controller window
  1341. //
  1342. }
  1343. return 0;
  1344. }
  1345. void CCameraSelectionPage::OnDelete( WPARAM, LPARAM )
  1346. {
  1347. int nSelCount = ListView_GetSelectedCount( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ) );
  1348. if (nSelCount)
  1349. {
  1350. if (m_pControllerWindow->CanSomeSelectedImagesBeDeleted())
  1351. {
  1352. if (CMessageBoxEx::IDMBEX_YES == CMessageBoxEx::MessageBox( m_hWnd, CSimpleString(IDS_CONFIRMDELETE,g_hInstance), CSimpleString(IDS_ERROR_TITLE,g_hInstance), CMessageBoxEx::MBEX_ICONQUESTION|CMessageBoxEx::MBEX_YESNO|CMessageBoxEx::MBEX_DEFBUTTON2))
  1353. {
  1354. m_pControllerWindow->DeleteSelectedImages();
  1355. }
  1356. }
  1357. }
  1358. }
  1359. LRESULT CCameraSelectionPage::OnGetToolTipDispInfo( WPARAM wParam, LPARAM lParam )
  1360. {
  1361. TOOLTIPTEXT *pToolTipText = reinterpret_cast<TOOLTIPTEXT*>(lParam);
  1362. if (pToolTipText)
  1363. {
  1364. switch (pToolTipText->hdr.idFrom)
  1365. {
  1366. case IDC_CAMSEL_ROTATE_RIGHT:
  1367. pToolTipText->hinst = g_hInstance;
  1368. pToolTipText->lpszText = MAKEINTRESOURCE(IDS_CAMSEL_TOOLTIP_ROTATE_RIGHT);
  1369. break;
  1370. case IDC_CAMSEL_ROTATE_LEFT:
  1371. pToolTipText->hinst = g_hInstance;
  1372. pToolTipText->lpszText = MAKEINTRESOURCE(IDS_CAMSEL_TOOLTIP_ROTATE_LEFT);
  1373. break;
  1374. case IDC_CAMSEL_PROPERTIES:
  1375. pToolTipText->hinst = g_hInstance;
  1376. pToolTipText->lpszText = MAKEINTRESOURCE(IDS_CAMSEL_TOOLTIP_PROPERTIES);
  1377. break;
  1378. case IDC_CAMSEL_TAKE_PICTURE:
  1379. pToolTipText->hinst = g_hInstance;
  1380. pToolTipText->lpszText = MAKEINTRESOURCE(IDS_CAMSEL_TOOLTIP_TAKE_PICTURE);
  1381. break;
  1382. case IDC_CAMSEL_CLEAR_ALL:
  1383. pToolTipText->hinst = g_hInstance;
  1384. pToolTipText->lpszText = MAKEINTRESOURCE(IDS_CAMSEL_TOOLTIP_CLEAR_ALL);
  1385. break;
  1386. case IDC_CAMSEL_SELECT_ALL:
  1387. pToolTipText->hinst = g_hInstance;
  1388. pToolTipText->lpszText = MAKEINTRESOURCE(IDS_CAMSEL_TOOLTIP_SELECT_ALL);
  1389. break;
  1390. }
  1391. }
  1392. return 0;
  1393. }
  1394. void CCameraSelectionPage::RepaintAllThumbnails()
  1395. {
  1396. //
  1397. // This could take a while for a lot of images, especially since we don't cache DIBs,
  1398. // so we'll display an hourglass cursor here.
  1399. //
  1400. CWaitCursor wc;
  1401. for (int i=0;i<ListView_GetItemCount(GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS));i++)
  1402. {
  1403. CWiaItem *pWiaItem = GetItemFromListByIndex( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS), i );
  1404. if (pWiaItem)
  1405. {
  1406. int nImageListIndex = AddThumbnailToListViewImageList( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS), pWiaItem, i );
  1407. if (nImageListIndex >= 0)
  1408. {
  1409. LVITEM LvItem = {0};
  1410. LvItem.iItem = i;
  1411. LvItem.mask = LVIF_IMAGE;
  1412. LvItem.iImage = nImageListIndex;
  1413. ListView_SetItem( GetDlgItem(m_hWnd,IDC_CAMSEL_THUMBNAILS), &LvItem );
  1414. }
  1415. }
  1416. }
  1417. UpdateWindow( m_hWnd );
  1418. }
  1419. LRESULT CCameraSelectionPage::OnSysColorChange( WPARAM wParam, LPARAM lParam )
  1420. {
  1421. SendDlgItemMessage( m_hWnd, IDC_CAMSEL_THUMBNAILS, WM_SYSCOLORCHANGE, wParam, lParam );
  1422. SendDlgItemMessage( m_hWnd, IDC_ACTION_BUTTON_BAR, WM_SYSCOLORCHANGE, wParam, lParam );
  1423. SendDlgItemMessage( m_hWnd, IDC_SELECTION_BUTTON_BAR, WM_SYSCOLORCHANGE, wParam, lParam );
  1424. SendDlgItemMessage( m_hWnd, IDC_TAKEPICTURE_BUTTON_BAR, WM_SYSCOLORCHANGE, wParam, lParam );
  1425. m_CameraSelectionButtonBarBitmapInfo.ReloadAndReplaceBitmap();
  1426. m_CameraTakePictureButtonBarBitmapInfo.ReloadAndReplaceBitmap();
  1427. m_CameraActionButtonBarBitmapInfo.ReloadAndReplaceBitmap();
  1428. RepaintAllThumbnails();
  1429. return 0;
  1430. }
  1431. LRESULT CCameraSelectionPage::OnThemeChanged( WPARAM wParam, LPARAM lParam )
  1432. {
  1433. SendDlgItemMessage( m_hWnd, IDC_CAMSEL_THUMBNAILS, WM_THEMECHANGED, wParam, lParam );
  1434. return 0;
  1435. }
  1436. LRESULT CCameraSelectionPage::OnSettingChange( WPARAM wParam, LPARAM lParam )
  1437. {
  1438. //
  1439. // Create a small image list, to prevent the checkbox state images from being resized in WM_SYSCOLORCHANGE
  1440. //
  1441. HIMAGELIST hImageListSmall = ImageList_Create( GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_COLOR24|ILC_MASK, 1, 1 );
  1442. if (hImageListSmall)
  1443. {
  1444. HIMAGELIST hImgListOld = ListView_SetImageList( GetDlgItem( m_hWnd, IDC_CAMSEL_THUMBNAILS ), hImageListSmall, LVSIL_SMALL );
  1445. if (hImgListOld)
  1446. {
  1447. ImageList_Destroy(hImgListOld);
  1448. }
  1449. }
  1450. SendDlgItemMessage( m_hWnd, IDC_CAMSEL_THUMBNAILS, WM_SETTINGCHANGE, wParam, lParam );
  1451. return 0;
  1452. }
  1453. LRESULT CCameraSelectionPage::OnCommand( WPARAM wParam, LPARAM lParam )
  1454. {
  1455. SC_BEGIN_COMMAND_HANDLERS()
  1456. {
  1457. SC_HANDLE_COMMAND( IDC_CAMSEL_SELECT_ALL, OnSelectAll );
  1458. SC_HANDLE_COMMAND( IDC_CAMSEL_CLEAR_ALL, OnClearAll );
  1459. SC_HANDLE_COMMAND( IDC_CAMSEL_PROPERTIES, OnProperties );
  1460. SC_HANDLE_COMMAND( IDC_CAMSEL_ROTATE_RIGHT, OnRotate );
  1461. SC_HANDLE_COMMAND( IDC_CAMSEL_ROTATE_LEFT, OnRotate );
  1462. SC_HANDLE_COMMAND( IDC_CAMSEL_TAKE_PICTURE, OnTakePicture );
  1463. SC_HANDLE_COMMAND( IDC_CAMSEL_DELETE, OnDelete );
  1464. }
  1465. SC_END_COMMAND_HANDLERS();
  1466. }
  1467. LRESULT CCameraSelectionPage::OnNotify( WPARAM wParam, LPARAM lParam )
  1468. {
  1469. SC_BEGIN_NOTIFY_MESSAGE_HANDLERS()
  1470. {
  1471. SC_HANDLE_NOTIFY_MESSAGE_CODE(PSN_WIZNEXT,OnWizNext);
  1472. SC_HANDLE_NOTIFY_MESSAGE_CODE(PSN_WIZBACK,OnWizBack);
  1473. SC_HANDLE_NOTIFY_MESSAGE_CODE(PSN_SETACTIVE,OnSetActive);
  1474. SC_HANDLE_NOTIFY_MESSAGE_CODE(PSN_TRANSLATEACCELERATOR,OnTranslateAccelerator);
  1475. SC_HANDLE_NOTIFY_MESSAGE_CODE(TTN_GETDISPINFO,OnGetToolTipDispInfo);
  1476. SC_HANDLE_NOTIFY_MESSAGE_CONTROL(LVN_ITEMCHANGED,IDC_CAMSEL_THUMBNAILS,OnThumbnailListSelChange);
  1477. SC_HANDLE_NOTIFY_MESSAGE_CONTROL(LVN_KEYDOWN,IDC_CAMSEL_THUMBNAILS,OnThumbnailListKeyDown);
  1478. }
  1479. SC_END_NOTIFY_MESSAGE_HANDLERS();
  1480. }
  1481. LRESULT CCameraSelectionPage::OnThreadNotification( WPARAM wParam, LPARAM lParam )
  1482. {
  1483. WTM_BEGIN_THREAD_NOTIFY_MESSAGE_HANDLERS()
  1484. {
  1485. WTM_HANDLE_NOTIFY_MESSAGE( TQ_DOWNLOADTHUMBNAIL, OnNotifyDownloadThumbnail );
  1486. WTM_HANDLE_NOTIFY_MESSAGE( TQ_DOWNLOADIMAGE, OnNotifyDownloadImage );
  1487. }
  1488. WTM_END_THREAD_NOTIFY_MESSAGE_HANDLERS();
  1489. }
  1490. INT_PTR CALLBACK CCameraSelectionPage::DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  1491. {
  1492. SC_BEGIN_DIALOG_MESSAGE_HANDLERS(CCameraSelectionPage)
  1493. {
  1494. SC_HANDLE_DIALOG_MESSAGE( WM_INITDIALOG, OnInitDialog );
  1495. SC_HANDLE_DIALOG_MESSAGE( WM_DESTROY, OnDestroy );
  1496. SC_HANDLE_DIALOG_MESSAGE( WM_COMMAND, OnCommand );
  1497. SC_HANDLE_DIALOG_MESSAGE( WM_NOTIFY, OnNotify );
  1498. SC_HANDLE_DIALOG_MESSAGE( WM_SHOWWINDOW, OnShowWindow );
  1499. SC_HANDLE_DIALOG_MESSAGE( WM_TIMER, OnTimer );
  1500. SC_HANDLE_DIALOG_MESSAGE( WM_SYSCOLORCHANGE, OnSysColorChange );
  1501. SC_HANDLE_DIALOG_MESSAGE( WM_THEMECHANGED, OnThemeChanged );
  1502. SC_HANDLE_DIALOG_MESSAGE( WM_SETTINGCHANGE, OnSettingChange );
  1503. }
  1504. SC_HANDLE_REGISTERED_DIALOG_MESSAGE( m_nThreadNotificationMessage, OnThreadNotification );
  1505. SC_HANDLE_REGISTERED_DIALOG_MESSAGE( m_nWiaEventMessage, OnEventNotification );
  1506. SC_END_DIALOG_MESSAGE_HANDLERS();
  1507. }