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.

811 lines
26 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: CHOOSDLG.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 5/12/1998
  12. *
  13. * DESCRIPTION: Dialog class for selecting an WIA device
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include <uiexthlp.h>
  19. #include <modlock.h>
  20. #include <wiacsh.h>
  21. #include <wiadevdp.h>
  22. #include <gwiaevnt.h>
  23. #include <psutil.h>
  24. static const DWORD g_HelpIDs[] =
  25. {
  26. IDC_VENDORSTRING_PROMPT, IDH_WIA_MAKER,
  27. IDC_VENDORSTRING, IDH_WIA_MAKER,
  28. IDC_DESCRIPTIONSTRING_PROMPT, IDH_WIA_DESCRIBE,
  29. IDC_DESCRIPTIONSTRING, IDH_WIA_DESCRIBE,
  30. IDC_DEVICELIST, IDH_WIA_DEVICE_LIST,
  31. IDC_SELDLG_PROPERTIES, IDH_WIA_BUTTON_PROP,
  32. IDOK, IDH_OK,
  33. IDCANCEL, IDH_CANCEL,
  34. IDC_BIG_TITLE, -1,
  35. IDC_SETTINGS_GROUP, -1,
  36. 0, 0
  37. };
  38. /*
  39. * Add a device to the list view control. We use the LPARAM in the list control
  40. * to store each interface pointer and any other per-device data we need
  41. */
  42. CChooseDeviceDialog::CChooseDeviceDialog( HWND hwnd )
  43. : m_pChooseDeviceDialogParams(NULL),
  44. m_hWnd(hwnd),
  45. m_hBigFont(NULL)
  46. {
  47. }
  48. /*
  49. * Destructor
  50. */
  51. CChooseDeviceDialog::~CChooseDeviceDialog(void)
  52. {
  53. m_pChooseDeviceDialogParams = NULL;
  54. m_hWnd = NULL;
  55. }
  56. /*
  57. * Find an item that matches the unique device string. Return <0 if not found.
  58. */
  59. int CChooseDeviceDialog::FindItemMatch( const CSimpleStringWide &strw )
  60. {
  61. WIA_PUSH_FUNCTION((TEXT("CChooseDeviceDialog::FindItemMatch( %ws )"), strw.String() ));
  62. HWND hwndList = GetDlgItem( m_hWnd, IDC_DEVICELIST );
  63. if (!hwndList)
  64. return -1;
  65. int iCount = ListView_GetItemCount(hwndList);
  66. if (!iCount)
  67. return -1;
  68. CSimpleString str = CSimpleStringConvert::NaturalString(strw);
  69. for (int i=0;i<iCount;i++)
  70. {
  71. LV_ITEM lvItem;
  72. ::ZeroMemory(&lvItem,sizeof(LV_ITEM));
  73. lvItem.mask = LVIF_PARAM;
  74. lvItem.iItem = i;
  75. ListView_GetItem( hwndList, &lvItem );
  76. CSimpleStringWide strwDeviceId;
  77. CDeviceInfo *pDevInfo = (CDeviceInfo *)lvItem.lParam;
  78. if (!pDevInfo)
  79. continue;
  80. if (!pDevInfo->GetProperty(WIA_DIP_DEV_ID,strwDeviceId))
  81. continue;
  82. CSimpleString strDeviceId = CSimpleStringConvert::NaturalString(strwDeviceId);
  83. WIA_TRACE((TEXT("Comparing %s to %s"), str.String(), strDeviceId.String()));
  84. if (str.CompareNoCase(strDeviceId)==0)
  85. {
  86. WIA_TRACE((TEXT("Found a match (%s == %s), returning index %d"), str.String(), strDeviceId.String(), i ));
  87. return i;
  88. }
  89. }
  90. return -1;
  91. }
  92. /*
  93. * Set the specified item to selected and focused, all others to neither.
  94. */
  95. bool CChooseDeviceDialog::SetSelectedItem( int iItem )
  96. {
  97. HWND hwndList = GetDlgItem( m_hWnd, IDC_DEVICELIST );
  98. if (!hwndList)
  99. return false;
  100. int iCount = ListView_GetItemCount(hwndList);
  101. if (!iCount)
  102. return false;
  103. for (int i=0;i<iCount;i++)
  104. {
  105. UINT state = 0;
  106. if ((iItem < 0 && i == 0) || (i == iItem))
  107. state = LVIS_FOCUSED | LVIS_SELECTED;
  108. ListView_SetItemState( hwndList, i, state, (LVIS_FOCUSED|LVIS_SELECTED));
  109. }
  110. return true;
  111. }
  112. HICON CChooseDeviceDialog::LoadDeviceIcon( CDeviceInfo *pdi )
  113. {
  114. CSimpleStringWide strwClassId;
  115. LONG nDeviceType;
  116. HICON hIconLarge = NULL;
  117. if (pdi->GetProperty( WIA_DIP_UI_CLSID, strwClassId ) &&
  118. pdi->GetProperty( WIA_DIP_DEV_TYPE, nDeviceType ))
  119. {
  120. WiaUiExtensionHelper::GetDeviceIcons(CSimpleBStr(strwClassId), nDeviceType, NULL, &hIconLarge );
  121. }
  122. return hIconLarge;
  123. }
  124. /*
  125. * Add a device to the list view control. We use the LPARAM in the list control
  126. * to store each interface pointer and any other per-device data we need
  127. */
  128. LRESULT CChooseDeviceDialog::OnInitDialog( WPARAM, LPARAM lParam )
  129. {
  130. m_pChooseDeviceDialogParams = (CChooseDeviceDialogParams*)lParam;
  131. if (!m_pChooseDeviceDialogParams || !m_pChooseDeviceDialogParams->pSelectDeviceDlg || !m_pChooseDeviceDialogParams->pDeviceList)
  132. {
  133. EndDialog( m_hWnd, E_INVALIDARG );
  134. return 0;
  135. }
  136. SendMessage( m_hWnd, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_DEFAULT))));
  137. //
  138. // Create the icon image list
  139. //
  140. HIMAGELIST hLargeDeviceIcons = ImageList_Create( GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_MASK|PrintScanUtil::CalculateImageListColorDepth(), 5, 5 );
  141. //
  142. // Set the image lists for the device list
  143. //
  144. if (hLargeDeviceIcons)
  145. {
  146. SendDlgItemMessage( m_hWnd, IDC_DEVICELIST, LVM_SETIMAGELIST, LVSIL_NORMAL, (LPARAM)hLargeDeviceIcons );
  147. }
  148. //
  149. // Reduce flicker
  150. //
  151. ListView_SetExtendedListViewStyleEx( GetDlgItem(m_hWnd, IDC_DEVICELIST), LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER );
  152. //
  153. // Create the large title
  154. //
  155. m_hBigFont = WiaUiUtil::CreateFontWithPointSizeFromWindow( GetDlgItem(m_hWnd,IDC_BIG_TITLE), 14, false, false );
  156. if (m_hBigFont)
  157. {
  158. SendDlgItemMessage( m_hWnd, IDC_BIG_TITLE, WM_SETFONT, reinterpret_cast<WPARAM>(m_hBigFont), MAKELPARAM(TRUE,0));
  159. }
  160. //
  161. // Register for device connection and disconnection events
  162. //
  163. CGenericWiaEventHandler::RegisterForWiaEvent( NULL, WIA_EVENT_DEVICE_DISCONNECTED, &m_pDisconnectEvent, m_hWnd, PWM_WIA_EVENT );
  164. CGenericWiaEventHandler::RegisterForWiaEvent( NULL, WIA_EVENT_DEVICE_CONNECTED, &m_pConnectEvent, m_hWnd, PWM_WIA_EVENT );
  165. AddDevices();
  166. SetSelectedItem(FindItemMatch(m_pChooseDeviceDialogParams->pSelectDeviceDlg->pwszInitialDeviceId));
  167. UpdateDeviceInformation();
  168. WiaUiUtil::CenterWindow(m_hWnd,m_pChooseDeviceDialogParams->pSelectDeviceDlg->hwndParent);
  169. SetForegroundWindow( m_hWnd );
  170. return 0;
  171. }
  172. LRESULT CChooseDeviceDialog::OnDblClkDeviceList( WPARAM, LPARAM )
  173. {
  174. SendMessage( m_hWnd, WM_COMMAND, MAKEWPARAM(IDOK,0), 0 );
  175. return 0;
  176. }
  177. LRESULT CChooseDeviceDialog::OnItemChangedDeviceList( WPARAM, LPARAM )
  178. {
  179. UpdateDeviceInformation();
  180. return 0;
  181. }
  182. LRESULT CChooseDeviceDialog::OnItemDeletedDeviceList( WPARAM, LPARAM lParam )
  183. {
  184. //
  185. // Get the notification information for this message
  186. //
  187. NMLISTVIEW *pNmListView = reinterpret_cast<NMLISTVIEW*>(lParam);
  188. if (pNmListView)
  189. {
  190. //
  191. // Get the lParam, which is a CDeviceInfo *
  192. //
  193. CDeviceInfo *pDeviceInfo = reinterpret_cast<CDeviceInfo*>(pNmListView->lParam);
  194. if (pDeviceInfo)
  195. {
  196. //
  197. // Free it
  198. //
  199. delete pDeviceInfo;
  200. }
  201. }
  202. return 0;
  203. }
  204. /*
  205. * Handle WM_NOTIFY messages.
  206. */
  207. LRESULT CChooseDeviceDialog::OnNotify( WPARAM wParam, LPARAM lParam )
  208. {
  209. SC_BEGIN_NOTIFY_MESSAGE_HANDLERS()
  210. {
  211. SC_HANDLE_NOTIFY_MESSAGE_CONTROL( NM_DBLCLK, IDC_DEVICELIST, OnDblClkDeviceList );
  212. SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_ITEMCHANGED, IDC_DEVICELIST, OnItemChangedDeviceList );
  213. SC_HANDLE_NOTIFY_MESSAGE_CONTROL( LVN_DELETEITEM, IDC_DEVICELIST, OnItemDeletedDeviceList );
  214. }
  215. SC_END_NOTIFY_MESSAGE_HANDLERS();
  216. }
  217. /*
  218. * Handle WM_DESTROY message, and free all the memory associated with this dialog
  219. */
  220. LRESULT CChooseDeviceDialog::OnDestroy( WPARAM, LPARAM )
  221. {
  222. if (m_hBigFont)
  223. {
  224. DeleteObject( m_hBigFont );
  225. m_hBigFont = NULL;
  226. }
  227. //
  228. // Clear the image list and list view. This should be unnecessary, but BoundsChecker
  229. // complains if I don't do it.
  230. //
  231. HWND hWndList = GetDlgItem( m_hWnd, IDC_DEVICELIST );
  232. if (hWndList)
  233. {
  234. //
  235. // Remove all of the list view's items
  236. //
  237. ListView_DeleteAllItems( hWndList );
  238. //
  239. // Destroy the list view's image list
  240. //
  241. HIMAGELIST hImgList = ListView_SetImageList( hWndList, NULL, LVSIL_NORMAL );
  242. if (hImgList)
  243. {
  244. ImageList_Destroy(hImgList);
  245. }
  246. }
  247. return 0;
  248. }
  249. /*
  250. * Return the index of the first selected item in the list control
  251. */
  252. int CChooseDeviceDialog::GetFirstSelectedDevice(void)
  253. {
  254. HWND hwndList = GetDlgItem( m_hWnd, IDC_DEVICELIST );
  255. if (!hwndList)
  256. return -1;
  257. int iCount = ListView_GetItemCount(hwndList);
  258. if (!iCount)
  259. return -1;
  260. for (int i=0;i<iCount;i++)
  261. if (ListView_GetItemState(hwndList,i,LVIS_FOCUSED) & LVIS_FOCUSED)
  262. return i;
  263. return -1;
  264. }
  265. void CChooseDeviceDialog::OnProperties( WPARAM, LPARAM )
  266. {
  267. WIA_PUSHFUNCTION(TEXT("CChooseDeviceDialog::OnProperties"));
  268. int iSelIndex = GetFirstSelectedDevice();
  269. if (iSelIndex < 0)
  270. {
  271. WIA_ERROR((TEXT("GetFirstSelectedDevice failed")));
  272. return;
  273. }
  274. CDeviceInfo *pDevInfo = GetDeviceInfoFromList(iSelIndex);
  275. if (!pDevInfo)
  276. {
  277. WIA_ERROR((TEXT("GetDeviceInfoFromList")));
  278. return;
  279. }
  280. HRESULT hr;
  281. CSimpleStringWide strDeviceId;
  282. if (pDevInfo->GetProperty( WIA_DIP_DEV_ID, strDeviceId ))
  283. {
  284. CSimpleStringWide strName;
  285. if (pDevInfo->GetProperty( WIA_DIP_DEV_NAME, strName ))
  286. {
  287. CComPtr<IWiaItem> pRootItem;
  288. hr = CreateDeviceIfNecessary( pDevInfo, m_hWnd, &pRootItem, NULL );
  289. if (SUCCEEDED(hr))
  290. {
  291. CSimpleString strPropertyPageTitle;
  292. strPropertyPageTitle.Format( IDS_DEVICE_PROPPAGE_TITLE, g_hInstance, CSimpleStringConvert::NaturalString(strName).String() );
  293. hr = WiaUiUtil::SystemPropertySheet( g_hInstance, m_hWnd, pRootItem, strPropertyPageTitle );
  294. }
  295. }
  296. else
  297. {
  298. WIA_ERROR((TEXT("Unable to get property WIA_DIP_DEV_NAME")));
  299. hr = E_FAIL;
  300. }
  301. }
  302. else
  303. {
  304. WIA_ERROR((TEXT("Unable to get property WIA_DIP_DEV_ID")));
  305. hr = E_FAIL;
  306. }
  307. if (!SUCCEEDED(hr))
  308. {
  309. MessageBox( m_hWnd, CSimpleString( IDS_SELDLG_PROPSHEETERROR, g_hInstance ), CSimpleString( IDS_SELDLG_ERROR_TITLE, g_hInstance ), MB_ICONINFORMATION );
  310. WIA_PRINTHRESULT((hr,TEXT("Unable to display property sheet")));
  311. }
  312. }
  313. void CChooseDeviceDialog::OnOk( WPARAM, LPARAM )
  314. {
  315. WIA_PUSHFUNCTION(TEXT("CChooseDeviceDialog::OnOk"));
  316. int iSelIndex = GetFirstSelectedDevice();
  317. WIA_TRACE((TEXT("Selected item: %d\n"), iSelIndex ));
  318. if (iSelIndex < 0)
  319. return;
  320. CDeviceInfo *pDevInfo = GetDeviceInfoFromList(iSelIndex);
  321. if (!pDevInfo)
  322. return;
  323. WIA_TRACE((TEXT("pDevInfo: %08X\n"), pDevInfo ));
  324. CComPtr<IWiaItem> pRootItem;
  325. HRESULT hr = CreateDeviceIfNecessary( pDevInfo,
  326. m_pChooseDeviceDialogParams->pSelectDeviceDlg->hwndParent,
  327. m_pChooseDeviceDialogParams->pSelectDeviceDlg->ppWiaItemRoot,
  328. m_pChooseDeviceDialogParams->pSelectDeviceDlg->pbstrDeviceID );
  329. EndDialog(m_hWnd,hr);
  330. }
  331. void CChooseDeviceDialog::OnCancel( WPARAM, LPARAM )
  332. {
  333. EndDialog(m_hWnd,S_FALSE);
  334. }
  335. /*
  336. * WM_COMMAND handler. IDOK causes the DevInfo interface pointer to be stored in the
  337. * dialog info structure for use elsewhere. Then we delete and zero out that item's
  338. * LPARAM so it won't get deleted in WM_DESTROY.
  339. */
  340. LRESULT CChooseDeviceDialog::OnCommand( WPARAM wParam, LPARAM lParam )
  341. {
  342. SC_BEGIN_COMMAND_HANDLERS()
  343. {
  344. SC_HANDLE_COMMAND( IDOK, OnOk );
  345. SC_HANDLE_COMMAND( IDCANCEL, OnCancel );
  346. SC_HANDLE_COMMAND( IDC_SELDLG_PROPERTIES, OnProperties );
  347. }
  348. SC_END_COMMAND_HANDLERS();
  349. }
  350. /*
  351. * Shortcut to get the LPARAM (CDeviceInfo*) from a given list control item
  352. */
  353. CChooseDeviceDialog::CDeviceInfo *CChooseDeviceDialog::GetDeviceInfoFromList( int iIndex )
  354. {
  355. HWND hwndList = GetDlgItem( m_hWnd, IDC_DEVICELIST );
  356. if (!hwndList)
  357. return NULL;
  358. LV_ITEM lvItem;
  359. ::ZeroMemory(&lvItem,sizeof(LV_ITEM));
  360. lvItem.mask = LVIF_PARAM;
  361. lvItem.iItem = iIndex;
  362. if (!ListView_GetItem( hwndList, &lvItem ))
  363. return NULL;
  364. return ((CDeviceInfo*)lvItem.lParam);
  365. }
  366. /*
  367. * Set the description strings for the currently selected device.
  368. */
  369. void CChooseDeviceDialog::UpdateDeviceInformation(void)
  370. {
  371. CSimpleStringWide strVendorDescription;
  372. CSimpleStringWide strDeviceDescription;
  373. int iIndex = GetFirstSelectedDevice();
  374. if (iIndex < 0)
  375. {
  376. EnableWindow( GetDlgItem(m_hWnd,IDOK), FALSE );
  377. EnableWindow( GetDlgItem(m_hWnd,IDC_SELDLG_PROPERTIES), FALSE );
  378. }
  379. else
  380. {
  381. EnableWindow( GetDlgItem(m_hWnd,IDOK), TRUE );
  382. EnableWindow( GetDlgItem(m_hWnd,IDC_SELDLG_PROPERTIES), TRUE );
  383. CDeviceInfo *pDevInfo = GetDeviceInfoFromList( iIndex );
  384. if (pDevInfo)
  385. {
  386. (void)pDevInfo->GetProperty( WIA_DIP_VEND_DESC, strVendorDescription );
  387. (void)pDevInfo->GetProperty( WIA_DIP_DEV_DESC, strDeviceDescription );
  388. }
  389. }
  390. CSimpleStringConvert::NaturalString(strVendorDescription).SetWindowText( GetDlgItem( m_hWnd, IDC_VENDORSTRING ) );
  391. CSimpleStringConvert::NaturalString(strDeviceDescription).SetWindowText( GetDlgItem( m_hWnd, IDC_DESCRIPTIONSTRING ) );
  392. }
  393. /*
  394. * Add a device to the list view control. We use the LPARAM in the list control
  395. * to store each interface pointer and any other per-device data we need
  396. */
  397. BOOL CChooseDeviceDialog::AddDevice( IWiaPropertyStorage *pIWiaPropertyStorage, int iDevNo )
  398. {
  399. //
  400. // Assume failure
  401. //
  402. BOOL bResult = FALSE;
  403. CDeviceInfo *pDeviceInfo = new CDeviceInfo;
  404. if (pDeviceInfo)
  405. {
  406. CSimpleStringWide strFriendlyName, strServerName;
  407. pDeviceInfo->Initialize(pIWiaPropertyStorage);
  408. pDeviceInfo->GetProperty( WIA_DIP_DEV_NAME, strFriendlyName );
  409. pDeviceInfo->GetProperty( WIA_DIP_SERVER_NAME, strServerName );
  410. //
  411. // Load the icon, and add it to the image list
  412. //
  413. HICON hIcon = LoadDeviceIcon( pDeviceInfo );
  414. if (hIcon)
  415. {
  416. HIMAGELIST hNormalImageList = ListView_GetImageList( GetDlgItem( m_hWnd, IDC_DEVICELIST ), LVSIL_NORMAL );
  417. if (hNormalImageList)
  418. {
  419. int iIconIndex = ImageList_AddIcon( hNormalImageList, hIcon );
  420. //
  421. // Get the device's name
  422. //
  423. CSimpleString strNaturalFriendlyName = CSimpleStringConvert::NaturalString(strFriendlyName);
  424. CSimpleString strNaturalServerName = CSimpleStringConvert::NaturalString(strServerName);
  425. //
  426. // Perpare the LV_ITEM struct to add it to the list view
  427. //
  428. LV_ITEM lvItem;
  429. ::ZeroMemory(&lvItem,sizeof(LV_ITEM));
  430. lvItem.lParam = reinterpret_cast<LPARAM>(pDeviceInfo);
  431. lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  432. lvItem.iItem = iDevNo;
  433. //
  434. // Append the server name, if there is one
  435. //
  436. if (strServerName.Length() && CSimpleStringConvert::NaturalString(strServerName) != CSimpleString(TEXT("local")))
  437. {
  438. strNaturalFriendlyName += CSimpleString(TEXT(" ("));
  439. strNaturalFriendlyName += strNaturalServerName;
  440. strNaturalFriendlyName += CSimpleString(TEXT(")"));
  441. }
  442. lvItem.pszText = (LPTSTR)strNaturalFriendlyName.String();
  443. lvItem.cchTextMax = strNaturalFriendlyName.Length() + 1;
  444. lvItem.iImage = iIconIndex;
  445. //
  446. // Add it to the list view
  447. //
  448. bResult = (ListView_InsertItem( GetDlgItem( m_hWnd, IDC_DEVICELIST ), &lvItem ) >= 0);
  449. }
  450. //
  451. // Free the icon
  452. //
  453. DestroyIcon( hIcon );
  454. }
  455. //
  456. // If we couldn't add the item for some reason, free the deviceinfo struct
  457. //
  458. if (!bResult)
  459. {
  460. delete pDeviceInfo;
  461. }
  462. }
  463. return bResult;
  464. }
  465. /*
  466. * Enumerate devices and add each to the list
  467. */
  468. bool CChooseDeviceDialog::AddDevices(void)
  469. {
  470. CWaitCursor wc;
  471. for (int i=0;i<m_pChooseDeviceDialogParams->pDeviceList->Size();i++)
  472. {
  473. AddDevice( m_pChooseDeviceDialogParams->pDeviceList->operator[](i), i );
  474. }
  475. return true;
  476. }
  477. HRESULT CChooseDeviceDialog::CreateDeviceIfNecessary( CDeviceInfo *pDevInfo, HWND hWndParent, IWiaItem **ppRootItem, BSTR *pbstrDeviceId )
  478. {
  479. if (!pDevInfo)
  480. {
  481. return E_POINTER;
  482. }
  483. HRESULT hr = S_OK;
  484. CSimpleStringWide strDeviceId;
  485. if (pDevInfo->GetProperty( WIA_DIP_DEV_ID, strDeviceId ))
  486. {
  487. if (pDevInfo->RootItem())
  488. {
  489. if (ppRootItem)
  490. {
  491. *ppRootItem = pDevInfo->RootItem();
  492. (*ppRootItem)->AddRef();
  493. }
  494. if (pbstrDeviceId)
  495. {
  496. *pbstrDeviceId = SysAllocString( strDeviceId );
  497. if (!pbstrDeviceId)
  498. {
  499. hr = E_OUTOFMEMORY;
  500. }
  501. }
  502. }
  503. else
  504. {
  505. CComPtr<IWiaDevMgr> pWiaDevMgr;
  506. hr = CoCreateInstance( CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)&pWiaDevMgr );
  507. if (SUCCEEDED(hr))
  508. {
  509. hr = CreateWiaDevice( pWiaDevMgr, pDevInfo->WiaPropertyStorage(), hWndParent, ppRootItem, pbstrDeviceId );
  510. if (SUCCEEDED(hr))
  511. {
  512. if (ppRootItem)
  513. {
  514. pDevInfo->RootItem(*ppRootItem);
  515. }
  516. }
  517. }
  518. }
  519. }
  520. else
  521. {
  522. hr = E_FAIL;
  523. WIA_ERROR((TEXT("Unable to get property WIA_DIP_DEV_ID")));
  524. }
  525. return hr;
  526. }
  527. // Static helper function for creating a device
  528. HRESULT CChooseDeviceDialog::CreateWiaDevice( IWiaDevMgr *pWiaDevMgr, IWiaPropertyStorage *pWiaPropertyStorage, HWND hWndParent, IWiaItem **ppWiaRootItem, BSTR *pbstrDeviceId )
  529. {
  530. WIA_PUSH_FUNCTION((TEXT("CChooseDeviceDialog::CreateWiaDevice")));
  531. //
  532. // Validate parameters
  533. //
  534. if (!pWiaPropertyStorage || !pWiaDevMgr)
  535. {
  536. return(E_INVALIDARG);
  537. }
  538. //
  539. // Get the device ID
  540. //
  541. CSimpleStringWide strDeviceId;
  542. if (!PropStorageHelpers::GetProperty( pWiaPropertyStorage, WIA_DIP_DEV_ID, strDeviceId ))
  543. {
  544. return(E_INVALIDARG);
  545. }
  546. WIA_TRACE((TEXT("DeviceID: %ws"), strDeviceId.String()));
  547. //
  548. // Assume success
  549. //
  550. HRESULT hr = S_OK;
  551. //
  552. // It is OK to have a NULL item, that means we won't be creating the device
  553. //
  554. if (ppWiaRootItem)
  555. {
  556. //
  557. // Initialize the device pointer to NULL
  558. //
  559. *ppWiaRootItem = NULL;
  560. //
  561. // Get the friendly name for the status dialog
  562. //
  563. CSimpleStringWide strwFriendlyName;
  564. if (!PropStorageHelpers::GetProperty( pWiaPropertyStorage, WIA_DIP_DEV_NAME, strwFriendlyName ))
  565. {
  566. return(E_INVALIDARG);
  567. }
  568. WIA_TRACE((TEXT("DeviceName: %ws"), strwFriendlyName.String()));
  569. //
  570. // Convert the device name to ANSI if needed
  571. //
  572. CSimpleString strFriendlyName = CSimpleStringConvert::NaturalString(strwFriendlyName);
  573. //
  574. // Get the device type for the status dialog
  575. //
  576. LONG nDeviceType;
  577. if (!PropStorageHelpers::GetProperty( pWiaPropertyStorage, WIA_DIP_DEV_TYPE, nDeviceType ))
  578. {
  579. return(E_INVALIDARG);
  580. }
  581. WIA_TRACE((TEXT("DeviceType: %08X"), nDeviceType));
  582. //
  583. // Create the progress dialog
  584. //
  585. CComPtr<IWiaProgressDialog> pWiaProgressDialog;
  586. hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaProgressDialog, (void**)&pWiaProgressDialog );
  587. if (SUCCEEDED(hr))
  588. {
  589. //
  590. // Figure out which animation to use
  591. //
  592. int nAnimationType = WIA_PROGRESSDLG_ANIM_CAMERA_COMMUNICATE;
  593. if (StiDeviceTypeScanner == GET_STIDEVICE_TYPE(nDeviceType))
  594. {
  595. nAnimationType = WIA_PROGRESSDLG_ANIM_SCANNER_COMMUNICATE;
  596. }
  597. else if (StiDeviceTypeStreamingVideo == GET_STIDEVICE_TYPE(nDeviceType))
  598. {
  599. nAnimationType = WIA_PROGRESSDLG_ANIM_VIDEO_COMMUNICATE;
  600. }
  601. //
  602. // Initialize the progress dialog
  603. //
  604. pWiaProgressDialog->Create( hWndParent, nAnimationType|WIA_PROGRESSDLG_NO_PROGRESS|WIA_PROGRESSDLG_NO_CANCEL|WIA_PROGRESSDLG_NO_TITLE );
  605. pWiaProgressDialog->SetTitle( CSimpleStringConvert::WideString(CSimpleString(IDS_SELECT_PROGDLG_TITLE,g_hInstance)));
  606. pWiaProgressDialog->SetMessage( CSimpleStringConvert::WideString(CSimpleString().Format(IDS_SELECT_PROGDLG_MESSAGE,g_hInstance,strFriendlyName.String())));
  607. //
  608. // Show the progress dialog
  609. //
  610. pWiaProgressDialog->Show();
  611. //
  612. // Create the device
  613. //
  614. WIA_TRACE((TEXT("Calling pWiaDevMgr->CreateDevice")));
  615. hr = pWiaDevMgr->CreateDevice( CSimpleBStr(strDeviceId), ppWiaRootItem );
  616. WIA_PRINTHRESULT((hr,TEXT("pWiaDevMgr->CreateDevice returned")));
  617. //
  618. // Tell the wait dialog to go away
  619. //
  620. pWiaProgressDialog->Destroy();
  621. }
  622. }
  623. //
  624. // If everything is still OK, and the caller wants a device ID, store it.
  625. //
  626. if (SUCCEEDED(hr) && pbstrDeviceId)
  627. {
  628. *pbstrDeviceId = SysAllocString( strDeviceId );
  629. if (!pbstrDeviceId)
  630. {
  631. hr = E_OUTOFMEMORY;
  632. }
  633. }
  634. WIA_PRINTHRESULT((hr,TEXT("CChooseDeviceDialog::CreateWiaDevice returned")));
  635. return(hr);
  636. }
  637. LRESULT CChooseDeviceDialog::OnWiaEvent( WPARAM wParam, LPARAM lParam )
  638. {
  639. WIA_PUSHFUNCTION(TEXT("CAcquisitionManagerControllerWindow::OnEventNotification"));
  640. CGenericWiaEventHandler::CEventMessage *pEventMessage = reinterpret_cast<CGenericWiaEventHandler::CEventMessage *>(lParam);
  641. if (pEventMessage)
  642. {
  643. //
  644. // If this is the connect event, and it matches the allowed device types, add the device to the list
  645. //
  646. if (pEventMessage->EventId() == WIA_EVENT_DEVICE_CONNECTED)
  647. {
  648. IWiaPropertyStorage *pWiaPropertyStorage = NULL;
  649. if (SUCCEEDED(WiaUiUtil::GetDeviceInfoFromId( pEventMessage->DeviceId(), &pWiaPropertyStorage )) && pWiaPropertyStorage)
  650. {
  651. LONG nDeviceType;
  652. if (PropStorageHelpers::GetProperty( pWiaPropertyStorage, WIA_DIP_DEV_TYPE, nDeviceType ))
  653. {
  654. if (m_pChooseDeviceDialogParams->pSelectDeviceDlg->nDeviceType == StiDeviceTypeDefault || (m_pChooseDeviceDialogParams->pSelectDeviceDlg->nDeviceType == GET_STIDEVICE_TYPE(nDeviceType)))
  655. {
  656. AddDevice( pWiaPropertyStorage, ListView_GetItemCount( GetDlgItem( m_hWnd, IDC_DEVICELIST )));
  657. }
  658. else
  659. {
  660. pWiaPropertyStorage->Release();
  661. }
  662. }
  663. else
  664. {
  665. pWiaPropertyStorage->Release();
  666. }
  667. }
  668. }
  669. //
  670. // If this is the disconnect event, remove it from the list
  671. //
  672. else if (pEventMessage->EventId() == WIA_EVENT_DEVICE_DISCONNECTED)
  673. {
  674. int nItemIndex = FindItemMatch( pEventMessage->DeviceId() );
  675. if (nItemIndex >= 0)
  676. {
  677. WIA_TRACE((TEXT("Removing device %ws (%d)"), pEventMessage->DeviceId().String(), nItemIndex ));
  678. int nSelectedItem = GetFirstSelectedDevice();
  679. ListView_DeleteItem( GetDlgItem( m_hWnd, IDC_DEVICELIST ), nItemIndex );
  680. int nItemCount = ListView_GetItemCount(GetDlgItem( m_hWnd, IDC_DEVICELIST ));
  681. if (nItemCount)
  682. {
  683. if (nSelectedItem == nItemIndex)
  684. {
  685. nSelectedItem = nItemCount-1;
  686. }
  687. SetSelectedItem( nSelectedItem );
  688. }
  689. }
  690. }
  691. //
  692. // Delete the message
  693. //
  694. delete pEventMessage;
  695. }
  696. //
  697. // Update all of the controls
  698. //
  699. UpdateDeviceInformation();
  700. return HANDLED_EVENT_MESSAGE;
  701. }
  702. LRESULT CChooseDeviceDialog::OnSysColorChange( WPARAM wParam, LPARAM lParam )
  703. {
  704. SendDlgItemMessage( m_hWnd, IDC_DEVICELIST, WM_SYSCOLORCHANGE, wParam, lParam );
  705. return 0;
  706. }
  707. LRESULT CChooseDeviceDialog::OnHelp( WPARAM wParam, LPARAM lParam )
  708. {
  709. return WiaHelp::HandleWmHelp( wParam, lParam, g_HelpIDs );
  710. }
  711. LRESULT CChooseDeviceDialog::OnContextMenu( WPARAM wParam, LPARAM lParam )
  712. {
  713. return WiaHelp::HandleWmContextMenu( wParam, lParam, g_HelpIDs );
  714. }
  715. /*
  716. * Main dialog proc
  717. */
  718. INT_PTR CALLBACK CChooseDeviceDialog::DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  719. {
  720. SC_BEGIN_DIALOG_MESSAGE_HANDLERS(CChooseDeviceDialog)
  721. {
  722. SC_HANDLE_DIALOG_MESSAGE( WM_INITDIALOG, OnInitDialog );
  723. SC_HANDLE_DIALOG_MESSAGE( WM_COMMAND, OnCommand );
  724. SC_HANDLE_DIALOG_MESSAGE( WM_DESTROY, OnDestroy );
  725. SC_HANDLE_DIALOG_MESSAGE( WM_NOTIFY, OnNotify );
  726. SC_HANDLE_DIALOG_MESSAGE( PWM_WIA_EVENT, OnWiaEvent );
  727. SC_HANDLE_DIALOG_MESSAGE( WM_HELP, OnHelp );
  728. SC_HANDLE_DIALOG_MESSAGE( WM_CONTEXTMENU, OnContextMenu );
  729. SC_HANDLE_DIALOG_MESSAGE( WM_SYSCOLORCHANGE, OnSysColorChange );
  730. }
  731. SC_END_DIALOG_MESSAGE_HANDLERS();
  732. }