Source code of Windows XP (NT5)
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.

2867 lines
78 KiB

  1. // WIA.cpp: implementation of the CWIA class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CWIA.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. /**************************************************************************\
  15. * CWIA::CWIA
  16. *
  17. * Constructor for WIA object
  18. *
  19. *
  20. * Arguments:
  21. *
  22. * none
  23. *
  24. * Return Value:
  25. *
  26. * none
  27. *
  28. * History:
  29. *
  30. * 4/20/1999 Original Version
  31. *
  32. \**************************************************************************/
  33. CWIA::CWIA()
  34. {
  35. //
  36. // initialize members
  37. //
  38. m_pIWiaDevMgr = NULL;
  39. m_pRootIWiaItem = NULL;
  40. m_pDIB = NULL;
  41. m_FileName = "image.bmp";
  42. m_bMessageBoxReport = TRUE;
  43. m_ApplicationName = "WIA - Error Return";
  44. //
  45. // Initialize the Enumerator POSITIONS
  46. //
  47. m_CurrentActiveTreeListPosition = NULL;
  48. m_CurrentDeviceListPosition = NULL;
  49. m_CurrentFormatEtcListPosition = NULL;
  50. m_CurrentItemProperyInfoListPosition = NULL;
  51. m_hPreviewWnd = NULL;
  52. }
  53. /**************************************************************************\
  54. * CWIA::~CWIA()
  55. *
  56. * Destructor, deletes allocated lists, and Releases Interface pointers
  57. *
  58. *
  59. * Arguments:
  60. *
  61. * none
  62. *
  63. * Return Value:
  64. *
  65. * none
  66. *
  67. * History:
  68. *
  69. * 4/20/1999 Original Version
  70. *
  71. \**************************************************************************/
  72. CWIA::~CWIA()
  73. {
  74. //
  75. // delete all Lists, and release Interface pointers
  76. //
  77. Cleanup();
  78. }
  79. /**************************************************************************\
  80. * CWIA::StressStatus
  81. *
  82. * Reports status to user via status list box
  83. *
  84. * Arguments:
  85. *
  86. * status - CString value to be displayed in the list box
  87. *
  88. * Return Value:
  89. *
  90. * void
  91. *
  92. * History:
  93. *
  94. * 2/14/1999 Original Version
  95. *
  96. \**************************************************************************/
  97. void CWIA::StressStatus(CString status)
  98. {
  99. OutputDebugString(status + "\n");
  100. }
  101. /**************************************************************************\
  102. * CWIA::StressStatus
  103. *
  104. * Reports status, and hResult to user via status list box
  105. *
  106. * Arguments:
  107. *
  108. * status - CString value to be displayed in the list box
  109. * hResult - hResult to be translated
  110. *
  111. * Return Value:
  112. *
  113. * void
  114. *
  115. * History:
  116. *
  117. * 2/14/1999 Original Version
  118. *
  119. \**************************************************************************/
  120. void CWIA::StressStatus(CString status, HRESULT hResult)
  121. {
  122. CString msg;
  123. ULONG ulLen = MAX_PATH;
  124. LPTSTR pMsgBuf = (char*)LocalAlloc(LPTR,MAX_PATH);
  125. //
  126. // attempt to handle WIA custom errors first
  127. //
  128. switch (hResult) {
  129. case WIA_ERROR_GENERAL_ERROR:
  130. sprintf(pMsgBuf,"There was a general device failure.");
  131. break;
  132. case WIA_ERROR_PAPER_JAM:
  133. sprintf(pMsgBuf,"The paper path is jammed.");
  134. break;
  135. case WIA_ERROR_PAPER_EMPTY:
  136. sprintf(pMsgBuf,"There are no documents in the input tray to scan.");
  137. break;
  138. case WIA_ERROR_PAPER_PROBLEM:
  139. sprintf(pMsgBuf,"There is a general problem with an input document.");
  140. break;
  141. case WIA_ERROR_OFFLINE:
  142. sprintf(pMsgBuf,"The device is offline.");
  143. break;
  144. case WIA_ERROR_BUSY:
  145. sprintf(pMsgBuf,"The device is busy.");
  146. break;
  147. case WIA_ERROR_WARMING_UP:
  148. sprintf(pMsgBuf,"The device is warming up.");
  149. break;
  150. case WIA_ERROR_USER_INTERVENTION:
  151. sprintf(pMsgBuf,"The user has paused or stopped the device.");
  152. break;
  153. case WIA_ERROR_ITEM_DELETED:
  154. sprintf(pMsgBuf,"An operation has been performed on a deleted item.");
  155. break;
  156. case WIA_ERROR_DEVICE_COMMUNICATION:
  157. sprintf(pMsgBuf,"There is a problem communicating with the device.");
  158. break;
  159. case WIA_ERROR_INVALID_COMMAND:
  160. sprintf(pMsgBuf,"An invalid command has been issued.");
  161. break;
  162. default:
  163. //
  164. // free temp buffer, because FormatMessage() will allocate it for me
  165. //
  166. LocalFree(pMsgBuf);
  167. ulLen = 0;
  168. ulLen = ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  169. NULL, hResult, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  170. (LPTSTR)&pMsgBuf, 0, NULL);
  171. break;
  172. }
  173. if (ulLen) {
  174. msg = pMsgBuf;
  175. msg.TrimRight();
  176. LocalFree(pMsgBuf);
  177. } else {
  178. // use sprintf to write to buffer instead of .Format member of
  179. // CString. This conversion works better for HEX
  180. char buffer[255];
  181. sprintf(buffer,"hResult = 0x%08X",hResult);
  182. msg = buffer;
  183. }
  184. StressStatus(status + ", " + msg);
  185. if (m_bMessageBoxReport)
  186. MessageBox(NULL,status + ", " + msg,m_ApplicationName,MB_OK|MB_ICONINFORMATION);
  187. }
  188. /**************************************************************************\
  189. * CWIA::ReadPropStr
  190. *
  191. * Reads a BSTR value of a target property
  192. *
  193. *
  194. * Arguments:
  195. *
  196. * propid - property ID
  197. * pIWiaPropStg - property storage
  198. * pbstr - returned BSTR read from property
  199. *
  200. * Return Value:
  201. *
  202. * status
  203. *
  204. * History:
  205. *
  206. * 2/14/1999 Original Version
  207. *
  208. \**************************************************************************/
  209. HRESULT CWIA::ReadPropStr(PROPID propid,IWiaPropertyStorage *pIWiaPropStg,BSTR *pbstr)
  210. {
  211. HRESULT hResult = S_OK;
  212. PROPSPEC PropSpec[1];
  213. PROPVARIANT PropVar[1];
  214. UINT cbSize = 0;
  215. *pbstr = NULL;
  216. memset(PropVar, 0, sizeof(PropVar));
  217. PropSpec[0].ulKind = PRSPEC_PROPID;
  218. PropSpec[0].propid = propid;
  219. hResult = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
  220. if (SUCCEEDED(hResult)) {
  221. if (PropVar[0].pwszVal) {
  222. *pbstr = SysAllocString(PropVar[0].pwszVal);
  223. } else {
  224. *pbstr = SysAllocString(L"");
  225. }
  226. if (*pbstr == NULL) {
  227. StressStatus("* ReadPropStr, SysAllocString failed");
  228. hResult = E_OUTOFMEMORY;
  229. }
  230. PropVariantClear(PropVar);
  231. } else {
  232. CString msg;
  233. msg.Format("* ReadPropStr, ReadMultiple of propid: %d, Failed", propid);
  234. StressStatus(msg);
  235. }
  236. return hResult;
  237. }
  238. /**************************************************************************\
  239. * CWIA::WritePropStr
  240. *
  241. * Writes a BSTR value to a target property
  242. *
  243. *
  244. * Arguments:
  245. *
  246. * propid - property ID
  247. * pIWiaPropStg - property storage
  248. * pbstr - BSTR to write to target property
  249. *
  250. * Return Value:
  251. *
  252. * status
  253. *
  254. * History:
  255. *
  256. * 2/14/1999 Original Version
  257. *
  258. \**************************************************************************/
  259. HRESULT CWIA::WritePropStr(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, BSTR bstr)
  260. {
  261. HRESULT hResult = S_OK;
  262. PROPSPEC propspec[1];
  263. PROPVARIANT propvar[1];
  264. propspec[0].ulKind = PRSPEC_PROPID;
  265. propspec[0].propid = propid;
  266. propvar[0].vt = VT_BSTR;
  267. propvar[0].pwszVal = bstr;
  268. hResult = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
  269. return hResult;
  270. }
  271. /**************************************************************************\
  272. * CWIA::WritePropLong
  273. *
  274. * Writes a LONG value of a target property
  275. *
  276. *
  277. * Arguments:
  278. *
  279. * propid - property ID
  280. * pIWiaPropStg - property storage
  281. * lVal - LONG to be written to target property
  282. *
  283. * Return Value:
  284. *
  285. * status
  286. *
  287. * History:
  288. *
  289. * 2/14/1999 Original Version
  290. *
  291. \**************************************************************************/
  292. HRESULT CWIA::WritePropLong(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, LONG lVal)
  293. {
  294. HRESULT hResult;
  295. PROPSPEC propspec[1];
  296. PROPVARIANT propvar[1];
  297. propspec[0].ulKind = PRSPEC_PROPID;
  298. propspec[0].propid = propid;
  299. propvar[0].vt = VT_I4;
  300. propvar[0].lVal = lVal;
  301. hResult = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
  302. return hResult;
  303. }
  304. /**************************************************************************\
  305. * CWIA::ReadPropLong
  306. *
  307. * Reads a long value from a target property
  308. *
  309. *
  310. * Arguments:
  311. *
  312. * propid - property ID
  313. * pIWiaPropStg - property storage
  314. * plval - returned long read from property
  315. *
  316. * Return Value:
  317. *
  318. * status
  319. *
  320. * History:
  321. *
  322. * 2/14/1999 Original Version
  323. *
  324. \**************************************************************************/
  325. HRESULT CWIA::ReadPropLong(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, LONG *plval)
  326. {
  327. HRESULT hResult = S_OK;
  328. PROPSPEC PropSpec[1];
  329. PROPVARIANT PropVar[1];
  330. UINT cbSize = 0;
  331. memset(PropVar, 0, sizeof(PropVar));
  332. PropSpec[0].ulKind = PRSPEC_PROPID;
  333. PropSpec[0].propid = propid;
  334. hResult = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
  335. if (SUCCEEDED(hResult)) {
  336. *plval = PropVar[0].lVal;
  337. }
  338. return hResult;
  339. }
  340. /**************************************************************************\
  341. * CWIA::WritePropGUID
  342. *
  343. * Writes a GUID value of a target property
  344. *
  345. *
  346. * Arguments:
  347. *
  348. * propid - property ID
  349. * pIWiaPropStg - property storage
  350. * guidVal - GUID to be written to target property
  351. *
  352. * Return Value:
  353. *
  354. * status
  355. *
  356. * History:
  357. *
  358. * 2/14/1999 Original Version
  359. *
  360. \**************************************************************************/
  361. HRESULT CWIA::WritePropGUID(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, GUID guidVal)
  362. {
  363. HRESULT hResult;
  364. PROPSPEC propspec[1];
  365. PROPVARIANT propvar[1];
  366. propspec[0].ulKind = PRSPEC_PROPID;
  367. propspec[0].propid = propid;
  368. propvar[0].vt = VT_CLSID;
  369. propvar[0].puuid = &guidVal;
  370. hResult = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
  371. return hResult;
  372. }
  373. /**************************************************************************\
  374. * CWIA::MoveTempFile()
  375. *
  376. * Copies the temporary file created by WIA to a new location, and
  377. * deletes the old temp file after copy is complete
  378. *
  379. *
  380. * Arguments:
  381. *
  382. * pTempFileName - Temporary file created by WIA
  383. * pTargetFileName - New file
  384. *
  385. * Return Value:
  386. *
  387. * status
  388. *
  389. * History:
  390. *
  391. * 6/10/1999 Original Version
  392. *
  393. \**************************************************************************/
  394. BOOL CWIA::MoveTempFile(LPWSTR pwszTempFileName, LPCTSTR szTargetFileName)
  395. {
  396. char buffer[MAX_PATH];
  397. sprintf(buffer,"%ws",pwszTempFileName);
  398. if(CopyFile(buffer,szTargetFileName,FALSE)){
  399. DeleteFile(buffer);
  400. }
  401. else{
  402. StressStatus(" Failed to copy temp file..");
  403. return FALSE;
  404. }
  405. return TRUE;
  406. }
  407. /**************************************************************************\
  408. * CWIA::IsValidItem
  409. *
  410. * Determines if the item is valid is disconnected, or destroyed
  411. *
  412. *
  413. * Arguments:
  414. *
  415. * pIWiaItem - target item
  416. *
  417. *
  418. * Return Value:
  419. *
  420. * status
  421. *
  422. * History:
  423. *
  424. * 2/14/1999 Original Version
  425. *
  426. \**************************************************************************/
  427. BOOL CWIA::IsValidItem(IWiaItem *pIWiaItem)
  428. {
  429. LONG lType = 0;
  430. pIWiaItem->GetItemType(&lType);
  431. if(lType & WiaItemTypeDisconnected)
  432. return FALSE;
  433. if(lType & WiaItemTypeDeleted)
  434. return FALSE;
  435. return TRUE;
  436. }
  437. /**************************************************************************\
  438. * CWIA::DoIWiaDataBandedTransfer
  439. *
  440. * Executes an IWiaData Transfer on an item
  441. *
  442. *
  443. * Arguments:
  444. *
  445. * pIWiaItem - target item
  446. * Tymed - TYMED value
  447. * ClipboardFormat - current clipboard format
  448. *
  449. * Return Value:
  450. *
  451. * status
  452. *
  453. * History:
  454. *
  455. * 2/14/1999 Original Version
  456. *
  457. \**************************************************************************/
  458. HRESULT CWIA::DoIWiaDataBandedTransfer(IWiaItem *pIWiaItem, DWORD Tymed, GUID ClipboardFormat)
  459. {
  460. HRESULT hResult = S_OK;
  461. //
  462. // Check Item pointer
  463. //
  464. if (pIWiaItem == NULL) {
  465. StressStatus("* pIWiaItem is NULL");
  466. return S_FALSE;
  467. }
  468. if(!IsValidItem(pIWiaItem)) {
  469. StressStatus("* pIWiaItem is invalid");
  470. return S_FALSE;
  471. }
  472. //
  473. // set the two properties (TYMED, and CF_ )
  474. //
  475. IWiaPropertyStorage *pIWiaPropStg;
  476. PROPSPEC PropSpec;
  477. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  478. if (hResult != S_OK) {
  479. StressStatus("* pIWiaItem->QueryInterface() Failed",hResult);
  480. return hResult;
  481. } else {
  482. //
  483. // Write property value for TYMED
  484. //
  485. PropSpec.propid = WIA_IPA_TYMED;
  486. hResult = WritePropLong(WIA_IPA_TYMED,pIWiaPropStg,Tymed);
  487. if (SUCCEEDED(hResult))
  488. StressStatus("tymed Successfully written");
  489. else
  490. StressStatus("* WritePropLong(WIA_IPA_TYMED) Failed",hResult);
  491. //
  492. // Write property value for SUPPORTED WIA FORMAT
  493. //
  494. hResult = WritePropGUID(WIA_IPA_FORMAT,pIWiaPropStg,ClipboardFormat);
  495. if (hResult == S_OK)
  496. StressStatus("Format Successfully written");
  497. else
  498. StressStatus("* WritePropLong(WIA_IPA_FORMAT) Failed",hResult);
  499. }
  500. StressStatus("Executing an idtGetBandedData Transfer...");
  501. CWaitCursor cwc;
  502. if (pIWiaItem == NULL) {
  503. StressStatus("* pIWiaItem is NULL");
  504. return S_FALSE;
  505. }
  506. //
  507. // get IWiaDatatransfer interface
  508. //
  509. IWiaDataTransfer *pIBandTran = NULL;
  510. hResult = pIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIBandTran);
  511. if (SUCCEEDED(hResult)) {
  512. //
  513. // create Banded callback
  514. //
  515. IWiaDataCallback* pIWiaDataCallback = NULL;
  516. CWiaDataCallback* pCBandedCB = new CWiaDataCallback();
  517. if (pCBandedCB) {
  518. hResult = pCBandedCB->QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback);
  519. if (hResult == S_OK) {
  520. WIA_DATA_TRANSFER_INFO wiaDataTransInfo;
  521. pCBandedCB->Initialize(m_hPreviewWnd);
  522. ZeroMemory(&wiaDataTransInfo, sizeof(WIA_DATA_TRANSFER_INFO));
  523. wiaDataTransInfo.ulSize = sizeof(WIA_DATA_TRANSFER_INFO);
  524. wiaDataTransInfo.ulBufferSize = (GetMinBufferSize(pIWiaItem) * 4);
  525. hResult = pIBandTran->idtGetBandedData(&wiaDataTransInfo, pIWiaDataCallback);
  526. pIBandTran->Release();
  527. if (hResult == S_OK) {
  528. //
  529. // Display data (only BMP, and single page TIFF supported so far for display..)
  530. //
  531. /*if (ClipboardFormat == WiaImgFmt_UNDEFINED)
  532. return "WiaImgFmt_UNDEFINED";
  533. else if (ClipboardFormat == WiaImgFmt_MEMORYBMP)
  534. return "WiaImgFmt_MEMORYBMP";*/
  535. if (ClipboardFormat == WiaImgFmt_BMP)
  536. m_pDIB->ReadFromHGLOBAL(pCBandedCB->GetDataPtr(),BMP_IMAGE);
  537. else if (ClipboardFormat == WiaImgFmt_MEMORYBMP)
  538. m_pDIB->ReadFromHGLOBAL(pCBandedCB->GetDataPtr(),BMP_IMAGE);
  539. /*else if (ClipboardFormat == WiaImgFmt_EMF)
  540. return "WiaImgFmt_EMF";
  541. else if (ClipboardFormat == WiaImgFmt_WMF)
  542. return "WiaImgFmt_WMF";
  543. else if (ClipboardFormat == WiaImgFmt_JPEG)
  544. return "WiaImgFmt_JPEG";
  545. else if (ClipboardFormat == WiaImgFmt_PNG)
  546. return "WiaImgFmt_PNG";
  547. else if (ClipboardFormat == WiaImgFmt_GIF)
  548. return "WiaImgFmt_GIF";*/
  549. else if (ClipboardFormat == WiaImgFmt_TIFF)
  550. m_pDIB->ReadFromHGLOBAL(pCBandedCB->GetDataPtr(),TIFF_IMAGE);
  551. /*else if (ClipboardFormat == WiaImgFmt_EXIF)
  552. return "WiaImgFmt_EXIF";
  553. else if (ClipboardFormat == WiaImgFmt_PHOTOCD)
  554. return "WiaImgFmt_PHOTOCD";
  555. else if (ClipboardFormat == WiaImgFmt_FLASHPIX)
  556. return "WiaImgFmt_FLASHPIX";
  557. else
  558. return "** UNKNOWN **";*/
  559. StressStatus("IWiaData Transfer.(CALLBACK)..Success");
  560. } else
  561. StressStatus("* idtGetBandedData() Failed", hResult);
  562. pCBandedCB->Release();
  563. } else
  564. StressStatus("* pCBandedCB->QueryInterface(IID_IWiaDataCallback) Failed", hResult);
  565. } else
  566. StressStatus("* pCBandedCB failed to create..");
  567. } else
  568. StressStatus("* pIWiaItem->QueryInterface(IID_IWiaDataTransfer) Failed", hResult);
  569. return hResult;
  570. }
  571. /**************************************************************************\
  572. * CWIA::GetMinBufferSize
  573. *
  574. * Returns the minimum buffer size for an Item transfer
  575. *
  576. *
  577. * Arguments:
  578. *
  579. * none
  580. *
  581. * Return Value:
  582. *
  583. * buffer size
  584. *
  585. * History:
  586. *
  587. * 6/21/1999 Original Version
  588. *
  589. \**************************************************************************/
  590. long CWIA::GetMinBufferSize(IWiaItem *pIWiaItem)
  591. {
  592. HRESULT hResult = S_OK;
  593. long MINBufferSize = 65535;
  594. IWiaPropertyStorage* pIWiaPropStg = NULL;
  595. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  596. if (SUCCEEDED(hResult)) {
  597. if (pIWiaPropStg != NULL) {
  598. hResult = ReadPropLong(WIA_IPA_MIN_BUFFER_SIZE,pIWiaPropStg,&MINBufferSize);
  599. if (SUCCEEDED(hResult)) {
  600. // whoopie!
  601. }
  602. //
  603. // Release IWiaPropertyStorage
  604. //
  605. pIWiaPropStg->Release();
  606. }
  607. }
  608. return MINBufferSize;
  609. }
  610. /**************************************************************************\
  611. * CWIA::SetPreviewWindow
  612. *
  613. * Sets the target painting preview window
  614. *
  615. *
  616. * Arguments:
  617. *
  618. * hWnd - Handle to preview window
  619. *
  620. * Return Value:
  621. *
  622. * void
  623. *
  624. * History:
  625. *
  626. * 2/14/1999 Original Version
  627. *
  628. \**************************************************************************/
  629. void CWIA::SetPreviewWindow(HWND hPreviewWindow)
  630. {
  631. m_hPreviewWnd = hPreviewWindow;
  632. }
  633. /**************************************************************************\
  634. * CWIA::DoIWiaDataGetDataTransfer
  635. *
  636. * Executes an IWiaData Transfer on an item
  637. *
  638. *
  639. * Arguments:
  640. *
  641. * pIWiaItem - target item
  642. * Tymed - TYMED value
  643. * ClipboardFormat - current clipboard format
  644. *
  645. * Return Value:
  646. *
  647. * status
  648. *
  649. * History:
  650. *
  651. * 2/14/1999 Original Version
  652. *
  653. \**************************************************************************/
  654. HRESULT CWIA::DoIWiaDataGetDataTransfer(IWiaItem *pIWiaItem, DWORD Tymed, GUID ClipboardFormat)
  655. {
  656. HRESULT hResult = S_OK;
  657. //
  658. // Check Item pointer
  659. //
  660. if (pIWiaItem == NULL) {
  661. StressStatus("* pIWiaItem is NULL");
  662. return S_FALSE;
  663. }
  664. if(!IsValidItem(pIWiaItem)) {
  665. StressStatus("* pIWiaItem is invalid");
  666. return S_FALSE;
  667. }
  668. //
  669. // set the two properties (TYMED, and CF_ )
  670. //
  671. IWiaPropertyStorage *pIWiaPropStg;
  672. PROPSPEC PropSpec;
  673. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  674. if (hResult != S_OK) {
  675. StressStatus("* pIWiaItem->QueryInterface() Failed",hResult);
  676. return hResult;
  677. } else {
  678. //
  679. // Write property value for TYMED
  680. //
  681. PropSpec.propid = WIA_IPA_TYMED;
  682. hResult = WritePropLong(WIA_IPA_TYMED,pIWiaPropStg,Tymed);
  683. if (SUCCEEDED(hResult))
  684. StressStatus("tymed Successfully written");
  685. else
  686. StressStatus("* WritePropLong(WIA_IPA_TYMED) Failed",hResult);
  687. //
  688. // Write property value for SUPPORTED WIA FORMAT
  689. //
  690. hResult = WritePropGUID(WIA_IPA_FORMAT,pIWiaPropStg,ClipboardFormat);
  691. if (hResult == S_OK)
  692. StressStatus("Format Successfully written");
  693. else
  694. StressStatus("* WritePropLong(WIA_IPA_FORMAT) Failed",hResult);
  695. }
  696. StressStatus("Executing an IWiaData Transfer...");
  697. // get IWiaDatatransfer interface
  698. IWiaDataTransfer *pIBandTran = NULL;
  699. hResult = pIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIBandTran);
  700. if (SUCCEEDED(hResult)) {
  701. STGMEDIUM StgMedium;
  702. StgMedium.tymed = Tymed;
  703. StgMedium.lpszFileName = NULL;
  704. StgMedium.pUnkForRelease = NULL;
  705. StgMedium.hGlobal = NULL;
  706. //
  707. // create Data callback
  708. //
  709. IWiaDataCallback* pIWiaDataCallback = NULL;
  710. CWiaDataCallback* pCWiaDataCB = new CWiaDataCallback();
  711. if (pCWiaDataCB) {
  712. hResult = pCWiaDataCB->QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback);
  713. if (hResult == S_OK) {
  714. pCWiaDataCB->Initialize();
  715. hResult = pIBandTran->idtGetData(&StgMedium,pIWiaDataCallback);
  716. pIBandTran->Release();
  717. pCWiaDataCB->Release();
  718. if (SUCCEEDED(hResult)) {
  719. if (Tymed == TYMED_HGLOBAL)
  720. MessageBox(NULL,"HGLOBAL SHOULD BE REMOVED","WIATEST BUSTED!",MB_OK);
  721. else if (Tymed == TYMED_FILE) {
  722. //
  723. // Rename file using set file name from UI
  724. //
  725. if (MoveTempFile(StgMedium.lpszFileName,m_FileName)) {
  726. StressStatus("IWiaData Transfer ( Saving " + m_FileName + " )");
  727. //
  728. // Display data (only BMP, and single page TIFF supported so far for display..)
  729. //
  730. /*if (ClipboardFormat == WiaImgFmt_UNDEFINED)
  731. return "WiaImgFmt_UNDEFINED";
  732. else if (ClipboardFormat == WiaImgFmt_MEMORYBMP)
  733. return "WiaImgFmt_MEMORYBMP";*/
  734. if (ClipboardFormat == WiaImgFmt_BMP)
  735. m_pDIB->ReadFromBMPFile(m_FileName);
  736. /*else if (ClipboardFormat == WiaImgFmt_EMF)
  737. return "WiaImgFmt_EMF";
  738. else if (ClipboardFormat == WiaImgFmt_WMF)
  739. return "WiaImgFmt_WMF";
  740. else if (ClipboardFormat == WiaImgFmt_JPEG)
  741. return "WiaImgFmt_JPEG";
  742. else if (ClipboardFormat == WiaImgFmt_PNG)
  743. return "WiaImgFmt_PNG";
  744. else if (ClipboardFormat == WiaImgFmt_GIF)
  745. return "WiaImgFmt_GIF";*/
  746. else if (ClipboardFormat == WiaImgFmt_TIFF)
  747. m_pDIB->ReadFromTIFFFile(m_FileName);
  748. /*else if (ClipboardFormat == WiaImgFmt_EXIF)
  749. return "WiaImgFmt_EXIF";
  750. else if (ClipboardFormat == WiaImgFmt_PHOTOCD)
  751. return "WiaImgFmt_PHOTOCD";
  752. else if (ClipboardFormat == WiaImgFmt_FLASHPIX)
  753. return "WiaImgFmt_FLASHPIX";
  754. else
  755. return "** UNKNOWN **";*/
  756. }
  757. }
  758. ReleaseStgMedium(&StgMedium);
  759. } else
  760. StressStatus("* idtGetData() Failed",hResult);
  761. } else
  762. StressStatus("* pCWiaDataCB->QueryInterface(IID_IWiaDataCallback)",hResult);
  763. } else
  764. StressStatus("* pCWiaDataCB failed to create..");
  765. } else
  766. StressStatus("* pIWiaItem->QueryInterface(IID_IWiaDataTransfer) Failed",hResult);
  767. return hResult;
  768. }
  769. /**************************************************************************\
  770. * CWIA::DoGetImageDlg()
  771. *
  772. * Execute an Image transfer using the WIA Default User Interface
  773. *
  774. *
  775. * Arguments:
  776. *
  777. * hParentWnd - Parent Window
  778. * DeviceType - device type (scanner, camera etc..)
  779. * Flags - special Flags
  780. * Intent - Current Intent
  781. * Tymed - TYMED value
  782. * ClipboardFormat - current clipboard format
  783. *
  784. * Return Value:
  785. *
  786. * status
  787. *
  788. * History:
  789. *
  790. * 2/14/1999 Original Version
  791. *
  792. \**************************************************************************/
  793. HRESULT CWIA::DoGetImageDlg(HWND hParentWnd, long DeviceType,long Flags,long Intent, long Tymed, GUID ClipboardFormat)
  794. {
  795. HRESULT hResult = S_OK;
  796. if(!IsValidItem(m_pRootIWiaItem)) {
  797. StressStatus("* pRootIWiaItem is invalid");
  798. return S_FALSE;
  799. }
  800. STGMEDIUM StgMedium;
  801. WIA_FORMAT_INFO format;
  802. DVTARGETDEVICE dvDev;
  803. // Fill in the storage medium spec and get the image.
  804. memset(&StgMedium, 0, sizeof(STGMEDIUM));
  805. memset(&dvDev,0,sizeof(DVTARGETDEVICE));
  806. memset(&format,0,sizeof(WIA_FORMAT_INFO));
  807. dvDev.tdSize = sizeof(DVTARGETDEVICE);
  808. hResult = m_pIWiaDevMgr->GetImageDlg(hParentWnd,DeviceType,Flags,Intent,m_pRootIWiaItem,m_FileName.AllocSysString(),&ClipboardFormat);
  809. if (hResult == S_OK) {
  810. if (Tymed == TYMED_HGLOBAL) {
  811. MessageBox(NULL,"HGLOBAL SHOULD BE REMOVED","WIATEST BUSTED!",MB_OK);
  812. } else if (Tymed == TYMED_FILE) {
  813. StressStatus("GetImageDlg Transfer ( Saving " + m_FileName + " )");
  814. //
  815. // Display data (only BMP, and single page TIFF supported so far for display..)
  816. //
  817. if (ClipboardFormat == WiaImgFmt_BMP)
  818. m_pDIB->ReadFromBMPFile(m_FileName);
  819. else if (ClipboardFormat == WiaImgFmt_TIFF)
  820. m_pDIB->ReadFromTIFFFile(m_FileName);
  821. }
  822. ReleaseStgMedium(&StgMedium);
  823. } else if (hResult == S_FALSE) {
  824. StressStatus("* User canceled Dialog");
  825. } else
  826. StressStatus("* pIWiaDevMgr->GetImageDlg() Failed", hResult);
  827. return hResult;
  828. }
  829. /**************************************************************************\
  830. * CWIA::CreateWIADeviceManager()
  831. *
  832. * Creates the IWiaDevMgr for WIA operations
  833. *
  834. * Arguments:
  835. *
  836. * none
  837. *
  838. * Return Value:
  839. *
  840. * status
  841. *
  842. * History:
  843. *
  844. * 2/14/1999 Original Version
  845. *
  846. \**************************************************************************/
  847. HRESULT CWIA::CreateWIADeviceManager()
  848. {
  849. HRESULT hResult = S_OK;
  850. if (m_pIWiaDevMgr != NULL)
  851. m_pIWiaDevMgr->Release();
  852. hResult = CoCreateInstance(CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER,
  853. IID_IWiaDevMgr,(void**)&m_pIWiaDevMgr);
  854. if (hResult != S_OK)
  855. StressStatus("* CoCreateInstance failed - m_pIWiaDevMgr not created");
  856. else
  857. StressStatus("CoCreateInstance Successful - m_pIWiaDevMgr created");
  858. return hResult;
  859. }
  860. /**************************************************************************\
  861. * CWIA::Initialize()
  862. *
  863. * Called by the application to Initialize the WIA object, resulting in
  864. * Device manager creation, and a Device Enumeration.
  865. * The DIB data pointer is also initialized.
  866. *
  867. * Arguments:
  868. *
  869. * none
  870. *
  871. * Return Value:
  872. *
  873. * status
  874. *
  875. * History:
  876. *
  877. * 2/14/1999 Original Version
  878. *
  879. \**************************************************************************/
  880. HRESULT CWIA::Initialize()
  881. {
  882. HRESULT hResult = S_OK;
  883. hResult = ::OleInitialize(NULL);
  884. if (FAILED(hResult))
  885. return hResult;
  886. //
  887. // create a WIA device manager
  888. //
  889. hResult = CreateWIADeviceManager();
  890. if (FAILED(hResult))
  891. return hResult;
  892. //
  893. // enumerate WIA devices
  894. //
  895. hResult = EnumerateAllWIADevices();
  896. if (FAILED(hResult))
  897. return hResult;
  898. //
  899. // new DIB data pointer
  900. //
  901. if (m_pDIB == NULL)
  902. m_pDIB = new CDib;
  903. return hResult;
  904. }
  905. /**************************************************************************\
  906. * CWIA::Cleanup()
  907. *
  908. * Deletes allocated Enumerator lists, and releases all Interface pointers
  909. *
  910. * Arguments:
  911. *
  912. * none
  913. *
  914. * Return Value:
  915. *
  916. * void
  917. *
  918. * History:
  919. *
  920. * 2/14/1999 Original Version
  921. *
  922. \**************************************************************************/
  923. void CWIA::Cleanup()
  924. {
  925. //
  926. // Free IWiaItem* list (Active Tree list)
  927. //
  928. DeleteActiveTreeList();
  929. //
  930. // Free DeviceID list (Device list)
  931. //
  932. DeleteWIADeviceList();
  933. //
  934. // Free Supported Formats list (FormatEtc list)
  935. //
  936. DeleteSupportedFormatList();
  937. //
  938. // Free Property Info list (Item Property Info list)
  939. //
  940. DeleteItemPropertyInfoList();
  941. //
  942. // release WIA Device Manager
  943. //
  944. if (m_pIWiaDevMgr)
  945. m_pIWiaDevMgr->Release();
  946. //
  947. // delete dib pointer, if exists
  948. //
  949. if (m_pDIB != NULL)
  950. delete m_pDIB;
  951. ::OleUninitialize();
  952. }
  953. /**************************************************************************\
  954. * CWIA::EnumeratAllWIADevices()
  955. *
  956. * Enumerates all WIA devices, and creates a list of WIADEVICENODES
  957. * A device node contains - DeviceID, used for Device creation
  958. * Device Name, used for display only
  959. * Server Name, used for display only
  960. *
  961. * Arguments:
  962. *
  963. * none
  964. *
  965. * Return Value:
  966. *
  967. * status
  968. *
  969. * History:
  970. *
  971. * 2/14/1999 Original Version
  972. *
  973. \**************************************************************************/
  974. HRESULT CWIA::EnumerateAllWIADevices()
  975. {
  976. HRESULT hResult = S_OK;
  977. LONG cItemRoot = 0;
  978. BOOL bRet = FALSE;
  979. IEnumWIA_DEV_INFO *pWiaEnumDevInfo;
  980. int DeviceIndex = 0;
  981. DeleteWIADeviceList();
  982. //
  983. // attempt to enumerate WIA devices
  984. //
  985. if (m_pIWiaDevMgr)
  986. hResult = m_pIWiaDevMgr->EnumDeviceInfo(0,&pWiaEnumDevInfo);
  987. else {
  988. StressStatus("* m_pIWiaDevMgr->EnumDeviceInfo() failed", hResult);
  989. return hResult;
  990. }
  991. if (hResult == S_OK) {
  992. do {
  993. IWiaPropertyStorage *pIWiaPropStg;
  994. hResult = pWiaEnumDevInfo->Next(1,&pIWiaPropStg, NULL);
  995. if (hResult == S_OK) {
  996. PROPSPEC PropSpec[3];
  997. PROPVARIANT PropVar[3];
  998. memset(PropVar,0,sizeof(PropVar));
  999. PropSpec[0].ulKind = PRSPEC_PROPID;
  1000. PropSpec[0].propid = WIA_DIP_DEV_ID;
  1001. PropSpec[1].ulKind = PRSPEC_PROPID;
  1002. PropSpec[1].propid = WIA_DIP_DEV_NAME;
  1003. PropSpec[2].ulKind = PRSPEC_PROPID;
  1004. PropSpec[2].propid = WIA_DIP_SERVER_NAME;
  1005. hResult = pIWiaPropStg->ReadMultiple(sizeof(PropSpec)/sizeof(PROPSPEC),
  1006. PropSpec,
  1007. PropVar);
  1008. if (hResult == S_OK) {
  1009. IWiaItem *pWiaItemRoot = NULL;
  1010. //
  1011. // create a new WIADevice node
  1012. //
  1013. WIADEVICENODE* pWIADevice = new WIADEVICENODE;
  1014. pWIADevice->bstrDeviceID = ::SysAllocString(PropVar[0].bstrVal);
  1015. pWIADevice->bstrDeviceName = ::SysAllocString(PropVar[1].bstrVal);
  1016. pWIADevice->bstrServerName = ::SysAllocString(PropVar[2].bstrVal);
  1017. m_WIADeviceList.AddTail(pWIADevice);
  1018. StressStatus((CString)pWIADevice->bstrDeviceName + " located on ( " + (CString)pWIADevice->bstrServerName + " ) server found");
  1019. DeviceIndex++;
  1020. FreePropVariantArray(sizeof(PropSpec)/sizeof(PROPSPEC),PropVar);
  1021. } else
  1022. StressStatus("* pIWiaPropStg->ReadMultiple() Failed", hResult);
  1023. cItemRoot++;
  1024. }
  1025. } while (hResult == S_OK);
  1026. }
  1027. //
  1028. // No devices found during enumeration?
  1029. //
  1030. if (DeviceIndex == 0)
  1031. StressStatus("* No WIA Devices Found");
  1032. return hResult;
  1033. }
  1034. /**************************************************************************\
  1035. * CWIA::EnumerateSupportedFormats()
  1036. *
  1037. * Enumerates the supported WIAFormatInfo for the target Root Item
  1038. *
  1039. * Arguments:
  1040. *
  1041. * pIRootItem - Target Root Item for enumeration
  1042. *
  1043. * Return Value:
  1044. *
  1045. * status
  1046. *
  1047. * History:
  1048. *
  1049. * 2/14/1999 Original Version
  1050. *
  1051. \**************************************************************************/
  1052. HRESULT CWIA::EnumerateSupportedFormats(IWiaItem* pIRootItem)
  1053. {
  1054. if(!IsValidItem(pIRootItem)) {
  1055. StressStatus("* pIRootItem is invalid");
  1056. return S_FALSE;
  1057. }
  1058. DeleteSupportedFormatList();
  1059. HRESULT hResult = S_OK;
  1060. IWiaDataTransfer *pIWiaDataTransfer = NULL;
  1061. hResult = pIRootItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer);
  1062. if (hResult == S_OK) {
  1063. IEnumWIA_FORMAT_INFO *pIEnumWIA_FORMAT_INFO;
  1064. WIA_FORMAT_INFO pfe;
  1065. int i = 0;
  1066. WIA_FORMAT_INFO *pSupportedFormat = NULL;
  1067. hResult = pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO(&pIEnumWIA_FORMAT_INFO);
  1068. if (SUCCEEDED(hResult)) {
  1069. do {
  1070. //
  1071. // enumerate supported format structs
  1072. //
  1073. hResult = pIEnumWIA_FORMAT_INFO->Next(1, &pfe, NULL);
  1074. if (hResult == S_OK) {
  1075. pSupportedFormat = new WIA_FORMAT_INFO;
  1076. memcpy(pSupportedFormat,&pfe,sizeof(WIA_FORMAT_INFO));
  1077. //
  1078. // Add supported format to the supported format list
  1079. //
  1080. m_SupportedFormatList.AddTail(pSupportedFormat);
  1081. } else {
  1082. if (FAILED(hResult)) {
  1083. StressStatus("* pIEnumWIA_FORMAT_INFO->Next Failed",hResult);
  1084. return hResult;
  1085. }
  1086. }
  1087. } while (hResult == S_OK);
  1088. //
  1089. // Release supported format enumerator interface
  1090. //
  1091. pIEnumWIA_FORMAT_INFO->Release();
  1092. //
  1093. // Release data transfer interface
  1094. //
  1095. pIWiaDataTransfer->Release();
  1096. } else
  1097. StressStatus("* EnumWIAFormatInfo Failed",hResult);
  1098. }
  1099. return hResult;
  1100. }
  1101. /**************************************************************************\
  1102. * CWIA::DeleteActiveTreeList()
  1103. *
  1104. * Deletes the active Tree list which contains Item Interface pointers,
  1105. * including the ROOT item. All Items are Released before the list is
  1106. * destroyed.
  1107. *
  1108. * Arguments:
  1109. *
  1110. * none
  1111. *
  1112. * Return Value:
  1113. *
  1114. * void
  1115. *
  1116. * History:
  1117. *
  1118. * 2/14/1999 Original Version
  1119. *
  1120. \**************************************************************************/
  1121. void CWIA::DeleteActiveTreeList()
  1122. {
  1123. if (m_ActiveTreeList.GetCount() == 0)
  1124. return;
  1125. POSITION Position = m_ActiveTreeList.GetHeadPosition();
  1126. IWiaItem* pIWiaItem = NULL;
  1127. while (Position) {
  1128. WIAITEMTREENODE* pWiaItemTreeNode = (WIAITEMTREENODE*)m_ActiveTreeList.GetNext(Position);
  1129. pIWiaItem = pWiaItemTreeNode->pIWiaItem;
  1130. pIWiaItem->Release();
  1131. //delete pWiaItemTreeNode;
  1132. }
  1133. m_ActiveTreeList.RemoveAll();
  1134. }
  1135. /**************************************************************************\
  1136. * CWIA::DeleteWIADeviceList()
  1137. *
  1138. * Deletes the Device list of WIADEVICENODES.
  1139. *
  1140. * Arguments:
  1141. *
  1142. * none
  1143. *
  1144. * Return Value:
  1145. *
  1146. * void
  1147. *
  1148. * History:
  1149. *
  1150. * 2/14/1999 Original Version
  1151. *
  1152. \**************************************************************************/
  1153. void CWIA::DeleteWIADeviceList()
  1154. {
  1155. if (m_WIADeviceList.GetCount() == 0)
  1156. return;
  1157. POSITION Position = m_WIADeviceList.GetHeadPosition();
  1158. while (Position) {
  1159. WIADEVICENODE* pWiaDeviceNode = (WIADEVICENODE*)m_WIADeviceList.GetNext(Position);
  1160. ::SysFreeString(pWiaDeviceNode->bstrDeviceID);
  1161. ::SysFreeString(pWiaDeviceNode->bstrDeviceName);
  1162. ::SysFreeString(pWiaDeviceNode->bstrServerName);
  1163. delete pWiaDeviceNode;
  1164. }
  1165. m_WIADeviceList.RemoveAll();
  1166. }
  1167. /**************************************************************************\
  1168. * CWIA::DeleteItemPropertyInfoList()
  1169. *
  1170. * Deletes the WIAITEMINFONODE list.
  1171. *
  1172. * Arguments:
  1173. *
  1174. * none
  1175. *
  1176. * Return Value:
  1177. *
  1178. * void
  1179. *
  1180. * History:
  1181. *
  1182. * 2/14/1999 Original Version
  1183. *
  1184. \**************************************************************************/
  1185. void CWIA::DeleteItemPropertyInfoList()
  1186. {
  1187. if (m_ItemPropertyInfoList.GetCount() == 0)
  1188. return;
  1189. POSITION Position = m_ItemPropertyInfoList.GetHeadPosition();
  1190. while (Position) {
  1191. WIAITEMINFONODE* pWiaItemInfoNode = (WIAITEMINFONODE*)m_ItemPropertyInfoList.GetNext(Position);
  1192. ::SysFreeString(pWiaItemInfoNode->bstrPropertyName);
  1193. PropVariantClear(&pWiaItemInfoNode->PropVar);
  1194. delete pWiaItemInfoNode;
  1195. }
  1196. m_ItemPropertyInfoList.RemoveAll();
  1197. }
  1198. /**************************************************************************\
  1199. * CWIA::DeleteSupportedFormatList()
  1200. *
  1201. * Deletes the FORMATECT list.
  1202. *
  1203. * Arguments:
  1204. *
  1205. * none
  1206. *
  1207. * Return Value:
  1208. *
  1209. * none
  1210. *
  1211. * History:
  1212. *
  1213. * 2/14/1999 Original Version
  1214. *
  1215. \**************************************************************************/
  1216. void CWIA::DeleteSupportedFormatList()
  1217. {
  1218. if (m_SupportedFormatList.GetCount() == 0)
  1219. return;
  1220. POSITION Position = m_SupportedFormatList.GetHeadPosition();
  1221. while (Position) {
  1222. WIA_FORMAT_INFO* pWIAFormatInfo = (WIA_FORMAT_INFO*)m_SupportedFormatList.GetNext(Position);
  1223. delete pWIAFormatInfo;
  1224. }
  1225. m_SupportedFormatList.RemoveAll();
  1226. }
  1227. /**************************************************************************\
  1228. * CWIA::GetWIADeviceCount()
  1229. *
  1230. * Return the number of Enumerated WIA Devices. (list item count)
  1231. *
  1232. * Arguments:
  1233. *
  1234. * none
  1235. *
  1236. * Return Value:
  1237. *
  1238. * long - Number of WIA Devices
  1239. *
  1240. * History:
  1241. *
  1242. * 2/14/1999 Original Version
  1243. *
  1244. \**************************************************************************/
  1245. long CWIA::GetWIADeviceCount()
  1246. {
  1247. return (long)m_WIADeviceList.GetCount();
  1248. }
  1249. /**************************************************************************\
  1250. * CWIA::SetFileName()
  1251. *
  1252. * Sets the Filename for a TYMED_FILE transfer
  1253. *
  1254. * Arguments:
  1255. *
  1256. * none
  1257. *
  1258. * Return Value:
  1259. *
  1260. * void
  1261. *
  1262. * History:
  1263. *
  1264. * 2/14/1999 Original Version
  1265. *
  1266. \**************************************************************************/
  1267. void CWIA::SetFileName(CString Filename)
  1268. {
  1269. m_FileName = Filename;
  1270. }
  1271. /**************************************************************************\
  1272. * CWIA::Auto_ResetItemEnumerator()
  1273. *
  1274. * Resets the ActiveTreeList position pointer to the top for a top-down
  1275. * enumeration by an application.
  1276. *
  1277. * Arguments:
  1278. *
  1279. * none
  1280. *
  1281. * Return Value:
  1282. *
  1283. * none
  1284. *
  1285. * History:
  1286. *
  1287. * 2/14/1999 Original Version
  1288. *
  1289. \**************************************************************************/
  1290. void CWIA::Auto_ResetItemEnumerator()
  1291. {
  1292. m_CurrentActiveTreeListPosition = m_ActiveTreeList.GetHeadPosition();
  1293. }
  1294. /**************************************************************************\
  1295. * CWIA::Auto_GetNextItem()
  1296. *
  1297. * Returns a IWiaItem* pointer, next Item in the ActiveTreeList
  1298. *
  1299. * Arguments:
  1300. *
  1301. * none
  1302. *
  1303. * Return Value:
  1304. *
  1305. * IWiaItem* - IWiaItem Interface pointer
  1306. *
  1307. * History:
  1308. *
  1309. * 2/14/1999 Original Version
  1310. *
  1311. \**************************************************************************/
  1312. IWiaItem* CWIA::Auto_GetNextItem()
  1313. {
  1314. IWiaItem* pIWiaItem = NULL;
  1315. if (m_CurrentItemProperyInfoListPosition) {
  1316. WIAITEMTREENODE* pWiaItemTreeNode = (WIAITEMTREENODE*)m_ActiveTreeList.GetNext(m_CurrentActiveTreeListPosition);
  1317. pIWiaItem = pWiaItemTreeNode->pIWiaItem;
  1318. }
  1319. return pIWiaItem;
  1320. }
  1321. /**************************************************************************\
  1322. * CWIA::Auto_ResetDeviceEnumerator()
  1323. *
  1324. * Resets the Device List position pointer to the top for a top-down
  1325. * enumeration by an application.
  1326. *
  1327. * Arguments:
  1328. *
  1329. * none
  1330. *
  1331. * Return Value:
  1332. *
  1333. * void
  1334. *
  1335. * History:
  1336. *
  1337. * 2/14/1999 Original Version
  1338. *
  1339. \**************************************************************************/
  1340. void CWIA::Auto_ResetDeviceEnumerator()
  1341. {
  1342. m_CurrentDeviceListPosition = m_WIADeviceList.GetHeadPosition();
  1343. }
  1344. /**************************************************************************\
  1345. * CWIA::Auto_GetNextDevice()
  1346. *
  1347. * Returns a WIADEVICENODE* pointer, next Device in the WIA Device List
  1348. *
  1349. * Arguments:
  1350. *
  1351. * none
  1352. *
  1353. * Return Value:
  1354. *
  1355. * WIADEVICENODE* - Wia Device Node pointer
  1356. *
  1357. * History:
  1358. *
  1359. * 2/14/1999 Original Version
  1360. *
  1361. \**************************************************************************/
  1362. WIADEVICENODE* CWIA::Auto_GetNextDevice()
  1363. {
  1364. WIADEVICENODE* pWiaDeviceNode = NULL;
  1365. if (m_CurrentDeviceListPosition)
  1366. pWiaDeviceNode = (WIADEVICENODE*)m_WIADeviceList.GetNext(m_CurrentDeviceListPosition);
  1367. return pWiaDeviceNode;
  1368. }
  1369. /**************************************************************************\
  1370. * CWIA::Auto_GetNextFormatEtc()
  1371. *
  1372. * Returns a WIA_FORMAT_INFO* pointer, next WIAFormatInfo in the supported WIAFormatInfo List
  1373. *
  1374. * Arguments:
  1375. *
  1376. * none
  1377. *
  1378. * Return Value:
  1379. *
  1380. * WIA_FORMAT_INFO* - WIAFormatInfo pointer
  1381. *
  1382. * History:
  1383. *
  1384. * 2/14/1999 Original Version
  1385. *
  1386. \**************************************************************************/
  1387. WIA_FORMAT_INFO* CWIA::Auto_GetNextFormatEtc()
  1388. {
  1389. WIA_FORMAT_INFO* pWIAFormatInfo = NULL;
  1390. if (m_CurrentFormatEtcListPosition)
  1391. WIA_FORMAT_INFO* pWIAFormatInfo = (WIA_FORMAT_INFO*)m_SupportedFormatList.GetNext(m_CurrentFormatEtcListPosition);
  1392. return pWIAFormatInfo;
  1393. }
  1394. /**************************************************************************\
  1395. * CWIA::Auto_ResetFormatEtcEnumerator()
  1396. *
  1397. * Resets the Supported Format Etc List position pointer to the top for a top-down
  1398. * enumeration by an application.
  1399. *
  1400. * Arguments:
  1401. *
  1402. * none
  1403. *
  1404. * Return Value:
  1405. *
  1406. * none
  1407. *
  1408. * History:
  1409. *
  1410. * 2/14/1999 Original Version
  1411. *
  1412. \**************************************************************************/
  1413. void CWIA::Auto_ResetFormatEtcEnumerator()
  1414. {
  1415. m_CurrentFormatEtcListPosition = m_SupportedFormatList.GetHeadPosition();
  1416. }
  1417. /**************************************************************************\
  1418. * CWIA::CreateWIADevice()
  1419. *
  1420. * Creates a WIA Device, Initializing the WIA object to operate on that
  1421. * device. Initialization includes the following:
  1422. * Destruction of Old Items tree.
  1423. * Destruction of old supported formats
  1424. * Recreation of Items tree.
  1425. * Recreation of supported formats
  1426. *
  1427. * Arguments:
  1428. *
  1429. * none
  1430. *
  1431. * Return Value:
  1432. *
  1433. * status
  1434. *
  1435. * History:
  1436. *
  1437. * 2/14/1999 Original Version
  1438. *
  1439. \**************************************************************************/
  1440. HRESULT CWIA::CreateWIADevice(BSTR bstrDeviceID)
  1441. {
  1442. //
  1443. // clean up old lists
  1444. //
  1445. DeleteActiveTreeList();
  1446. DeleteSupportedFormatList();
  1447. HRESULT hResult = S_OK;
  1448. hResult = m_pIWiaDevMgr->CreateDevice(bstrDeviceID, &m_pRootIWiaItem);
  1449. if (SUCCEEDED(hResult)) {
  1450. hResult = EnumerateAllItems(m_pRootIWiaItem);
  1451. if (FAILED(hResult))
  1452. StressStatus("* EnumerateAllItems Failed",hResult);
  1453. hResult = EnumerateSupportedFormats(m_pRootIWiaItem);
  1454. if (FAILED(hResult))
  1455. StressStatus("* EnumerateSupportedFormats Failed",hResult);
  1456. } else if (hResult == WAIT_TIMEOUT) {
  1457. for (int TryCount = 1;TryCount <=5;TryCount++) {
  1458. int msWait = ((rand() % 100) + 10);
  1459. Sleep(msWait);
  1460. hResult = m_pIWiaDevMgr->CreateDevice(bstrDeviceID, &m_pRootIWiaItem);
  1461. if (SUCCEEDED(hResult)) {
  1462. TryCount = 6;
  1463. hResult = EnumerateAllItems(m_pRootIWiaItem);
  1464. if (FAILED(hResult))
  1465. StressStatus("* EnumerateAllItems Failed",hResult);
  1466. hResult = EnumerateSupportedFormats(m_pRootIWiaItem);
  1467. if (FAILED(hResult))
  1468. StressStatus("* EnumerateSupportedFormats Failed",hResult);
  1469. }
  1470. }
  1471. } else
  1472. StressStatus("* CreateDevice Failed",hResult);
  1473. return hResult;
  1474. }
  1475. /**************************************************************************\
  1476. * CWIA::GetWIAItemCount()
  1477. *
  1478. * Returns the number of Items for the current device
  1479. *
  1480. * Arguments:
  1481. *
  1482. * none
  1483. *
  1484. * Return Value:
  1485. *
  1486. * long - number of items
  1487. *
  1488. * History:
  1489. *
  1490. * 2/14/1999 Original Version
  1491. *
  1492. \**************************************************************************/
  1493. long CWIA::GetWIAItemCount()
  1494. {
  1495. return (long)m_ActiveTreeList.GetCount();
  1496. }
  1497. /**************************************************************************\
  1498. * CWIA::Auto_GetNextItemPropertyInfo()
  1499. *
  1500. * Returns the next WIAITEMINFONODE pointer in the Property information list
  1501. *
  1502. * Arguments:
  1503. *
  1504. * none
  1505. *
  1506. * Return Value:
  1507. *
  1508. * WIAITEMINFONODE* - WIA Item node pointer
  1509. *
  1510. * History:
  1511. *
  1512. * 2/14/1999 Original Version
  1513. *
  1514. \**************************************************************************/
  1515. WIAITEMINFONODE* CWIA:: Auto_GetNextItemPropertyInfo()
  1516. {
  1517. WIAITEMINFONODE* pWiaItemPropertyInfoNode = NULL;
  1518. if (m_CurrentItemProperyInfoListPosition)
  1519. pWiaItemPropertyInfoNode = (WIAITEMINFONODE*)m_ItemPropertyInfoList.GetNext(m_CurrentItemProperyInfoListPosition);
  1520. return pWiaItemPropertyInfoNode;
  1521. }
  1522. /**************************************************************************\
  1523. * CWIA::Auto_ResetItemPropertyInfoEnumerator()
  1524. *
  1525. * Resets the Item Property enumerator to the Head of the
  1526. * Item Property list
  1527. *
  1528. * Arguments:
  1529. *
  1530. * none
  1531. *
  1532. * Return Value:
  1533. *
  1534. * void
  1535. *
  1536. * History:
  1537. *
  1538. * 2/14/1999 Original Version
  1539. *
  1540. \**************************************************************************/
  1541. void CWIA:: Auto_ResetItemPropertyInfoEnumerator()
  1542. {
  1543. m_CurrentItemProperyInfoListPosition = m_ItemPropertyInfoList.GetHeadPosition();
  1544. }
  1545. /**************************************************************************\
  1546. * CWIA::GetItemPropertyInfoCount()
  1547. *
  1548. * returns the number of Properties for the current Item
  1549. *
  1550. * Arguments:
  1551. *
  1552. * none
  1553. *
  1554. * Return Value:
  1555. *
  1556. * long - Number of properties for the current item
  1557. *
  1558. * History:
  1559. *
  1560. * 2/14/1999 Original Version
  1561. *
  1562. \**************************************************************************/
  1563. long CWIA::GetWIAItemProperyInfoCount()
  1564. {
  1565. return (long)m_ItemPropertyInfoList.GetCount();
  1566. }
  1567. /**************************************************************************\
  1568. * CWIA::CreateItemPropertyInformationList()
  1569. *
  1570. * Constructs a list of WIAITEMINFONODEs that contain information about
  1571. * the target item.
  1572. * A Item Property info node contains - PropSpec, used for read/writes
  1573. * PropVar, used for read/write
  1574. * bstrPropertyName, used for display only
  1575. * AccessFlags, access rights/flags
  1576. *
  1577. * Arguments:
  1578. *
  1579. * pIWiaItem - target item
  1580. *
  1581. * Return Value:
  1582. *
  1583. * status
  1584. *
  1585. * History:
  1586. *
  1587. * 2/14/1999 Original Version
  1588. *
  1589. \**************************************************************************/
  1590. HRESULT CWIA::CreateItemPropertyInformationList(IWiaItem *pIWiaItem)
  1591. {
  1592. if(!IsValidItem(pIWiaItem)) {
  1593. StressStatus("* pIWiaItem is invalid");
  1594. return S_FALSE;
  1595. }
  1596. DeleteItemPropertyInfoList();
  1597. HRESULT hResult = S_OK;
  1598. IWiaPropertyStorage *pIWiaPropStg = NULL;
  1599. if (pIWiaItem == NULL)
  1600. return E_FAIL;
  1601. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  1602. if (hResult == S_OK) {
  1603. //
  1604. // Start Enumeration
  1605. //
  1606. IEnumSTATPROPSTG *pIPropEnum;
  1607. hResult = pIWiaPropStg->Enum(&pIPropEnum);
  1608. if (hResult == S_OK) {
  1609. STATPROPSTG StatPropStg;
  1610. do {
  1611. hResult = pIPropEnum->Next(1,&StatPropStg, NULL);
  1612. if (hResult == S_OK) {
  1613. if (StatPropStg.lpwstrName != NULL) {
  1614. //
  1615. // read property value
  1616. //
  1617. WIAITEMINFONODE* pWiaItemInfoNode = new WIAITEMINFONODE;
  1618. memset(pWiaItemInfoNode,0,sizeof(WIAITEMINFONODE));
  1619. pWiaItemInfoNode->bstrPropertyName = ::SysAllocString(StatPropStg.lpwstrName);
  1620. pWiaItemInfoNode->PropSpec.ulKind = PRSPEC_PROPID;
  1621. pWiaItemInfoNode->PropSpec.propid = StatPropStg.propid;
  1622. hResult = pIWiaPropStg->ReadMultiple(1,&pWiaItemInfoNode->PropSpec,&pWiaItemInfoNode->PropVar);
  1623. if (hResult == S_OK) {
  1624. PROPVARIANT AttrPropVar; // not used at this time
  1625. hResult = pIWiaPropStg->GetPropertyAttributes(1, &pWiaItemInfoNode->PropSpec,&pWiaItemInfoNode->AccessFlags,&AttrPropVar);
  1626. if (hResult != S_OK) {
  1627. StressStatus("* pIWiaItem->GetPropertyAttributes() Failed",hResult);
  1628. hResult = S_OK; // do this to continue property traversal
  1629. }
  1630. m_ItemPropertyInfoList.AddTail(pWiaItemInfoNode);
  1631. } else
  1632. StressStatus("* ReadMultiple Failed",hResult);
  1633. } else {
  1634. CString msg;
  1635. msg.Format("* Property with NULL name, propid = %li\n",StatPropStg.propid);
  1636. StressStatus(msg);
  1637. }
  1638. }
  1639. //
  1640. // clean up property name
  1641. //
  1642. CoTaskMemFree(StatPropStg.lpwstrName);
  1643. } while (hResult == S_OK);
  1644. }
  1645. if (pIPropEnum != NULL)
  1646. pIPropEnum->Release();
  1647. if (pIWiaPropStg != NULL)
  1648. pIWiaPropStg->Release();
  1649. }
  1650. return S_OK;
  1651. }
  1652. /**************************************************************************\
  1653. * CWIA::ReEnumeratetems()
  1654. *
  1655. * ReCreates an Active Tree list of all items using the target Root Item
  1656. *
  1657. * Arguments:
  1658. *
  1659. * none
  1660. *
  1661. * Return Value:
  1662. *
  1663. * status
  1664. *
  1665. * History:
  1666. *
  1667. * 2/14/1999 Original Version
  1668. *
  1669. \**************************************************************************/
  1670. HRESULT CWIA::ReEnumerateItems()
  1671. {
  1672. HRESULT hResult = S_OK;
  1673. if (m_ActiveTreeList.GetCount() == 0)
  1674. return E_FAIL;
  1675. POSITION Position = m_ActiveTreeList.GetHeadPosition();
  1676. //
  1677. // skip root item
  1678. //
  1679. m_ActiveTreeList.GetNext(Position);
  1680. IWiaItem* pIWiaItem = NULL;
  1681. while (Position) {
  1682. WIAITEMTREENODE* pWiaItemTreeNode = (WIAITEMTREENODE*)m_ActiveTreeList.GetNext(Position);
  1683. pIWiaItem = pWiaItemTreeNode->pIWiaItem;
  1684. pIWiaItem->Release();
  1685. }
  1686. hResult = EnumerateAllItems(m_pRootIWiaItem);
  1687. return hResult;
  1688. }
  1689. /**************************************************************************\
  1690. * CWIA::EnumerateAllItems()
  1691. *
  1692. * Creates an Active Tree list of all items using the target Root Item
  1693. *
  1694. * Arguments:
  1695. *
  1696. * pRootItem - target root item
  1697. *
  1698. * Return Value:
  1699. *
  1700. * status
  1701. *
  1702. * History:
  1703. *
  1704. * 2/14/1999 Original Version
  1705. *
  1706. \**************************************************************************/
  1707. HRESULT CWIA::EnumerateAllItems(IWiaItem *pIRootItem)
  1708. {
  1709. HRESULT hResult = S_OK;
  1710. if(!IsValidItem(pIRootItem)) {
  1711. StressStatus("* pIRootItem is invalid");
  1712. return S_FALSE;
  1713. }
  1714. IEnumWiaItem* pEnumItem = NULL;
  1715. IWiaItem* pIWiaItem = NULL;
  1716. WIAITEMTREENODE* pWiaItemTreeNode = NULL;
  1717. int ParentID = 0;
  1718. //
  1719. // clean existing list
  1720. //
  1721. m_ActiveTreeList.RemoveAll();
  1722. if (pIRootItem != NULL) {
  1723. // add Root to list
  1724. pWiaItemTreeNode = (WIAITEMTREENODE*)GlobalAlloc(GPTR,sizeof(WIAITEMTREENODE));
  1725. pWiaItemTreeNode->pIWiaItem = pIRootItem;
  1726. pWiaItemTreeNode->ParentID = ParentID;
  1727. m_ActiveTreeList.AddTail(pWiaItemTreeNode);
  1728. hResult = pIRootItem->EnumChildItems(&pEnumItem);
  1729. //
  1730. // we have children so continue to enumerate them
  1731. //
  1732. if (hResult == S_OK && pEnumItem != NULL) {
  1733. EnumNextLevel(pEnumItem,ParentID);
  1734. pEnumItem->Release();
  1735. }
  1736. } else {
  1737. //
  1738. // pRootItem is NULL!!
  1739. //
  1740. StressStatus("* pRootItem is NULL");
  1741. return E_INVALIDARG;
  1742. }
  1743. return hResult;
  1744. }
  1745. /**************************************************************************\
  1746. * CWIA::EnumNextLevel()
  1747. *
  1748. * Continues the Active Tree list creation of all items using a target Root Item
  1749. *
  1750. * Arguments:
  1751. *
  1752. * pEnumItem - Item Enumerator
  1753. * ParentID - Parent ID (Recursive tracking for display only)
  1754. *
  1755. * Return Value:
  1756. *
  1757. * status
  1758. *
  1759. * History:
  1760. *
  1761. * 2/14/1999 Original Version
  1762. *
  1763. \**************************************************************************/
  1764. HRESULT CWIA::EnumNextLevel(IEnumWiaItem *pEnumItem,int ParentID)
  1765. {
  1766. IWiaItem *pIWiaItem;
  1767. long lType;
  1768. HRESULT hResult;
  1769. WIAITEMTREENODE* pWiaItemTreeNode = NULL;
  1770. while (pEnumItem->Next(1,&pIWiaItem,NULL) == S_OK) {
  1771. if (pIWiaItem != NULL) {
  1772. pWiaItemTreeNode = (WIAITEMTREENODE*)GlobalAlloc(GPTR,sizeof(WIAITEMTREENODE));
  1773. pWiaItemTreeNode->pIWiaItem = pIWiaItem;
  1774. pWiaItemTreeNode->ParentID = ParentID;
  1775. m_ActiveTreeList.AddTail(pWiaItemTreeNode);
  1776. } else
  1777. return E_FAIL;
  1778. // find out if the item is a folder, if it is,
  1779. // recursive enumerate
  1780. pIWiaItem->GetItemType(&lType);
  1781. if (lType & WiaItemTypeFolder) {
  1782. IEnumWiaItem *pEnumNext;
  1783. hResult = pIWiaItem->EnumChildItems(&pEnumNext);
  1784. if (hResult == S_OK) {
  1785. EnumNextLevel(pEnumNext,ParentID + 1);
  1786. pEnumNext->Release();
  1787. }
  1788. }
  1789. }
  1790. return S_OK;
  1791. }
  1792. /**************************************************************************\
  1793. * CWIA::GetItemTreeList()
  1794. *
  1795. * Returns a pointer to the Active Tree list containing all items.
  1796. * note: Some Applications need to make list operations using previously
  1797. * stored POSITIONS in the list. Applications should not destroy
  1798. * this list. The WIA object controls the destruction.
  1799. *
  1800. * Arguments:
  1801. *
  1802. * none
  1803. *
  1804. * Return Value:
  1805. *
  1806. * CPtrList* - pointer to the Active Tree list
  1807. *
  1808. * History:
  1809. *
  1810. * 2/14/1999 Original Version
  1811. *
  1812. \**************************************************************************/
  1813. CPtrList* CWIA::GetItemTreeList()
  1814. {
  1815. return &m_ActiveTreeList;
  1816. }
  1817. /**************************************************************************\
  1818. * CWIA::GetRootIWiaItem()
  1819. *
  1820. * Returns the Root item for the current WIA session
  1821. *
  1822. * Arguments:
  1823. *
  1824. * pRootItem - target root item
  1825. *
  1826. * Return Value:
  1827. *
  1828. * IWiaItem* pRootItem;
  1829. *
  1830. * History:
  1831. *
  1832. * 2/14/1999 Original Version
  1833. *
  1834. \**************************************************************************/
  1835. IWiaItem* CWIA::GetRootIWiaItem()
  1836. {
  1837. return m_pRootIWiaItem;
  1838. }
  1839. /**************************************************************************\
  1840. * CWIA::IsRoot()
  1841. *
  1842. * Checks the POSITION against with the Head POSITION in the list.
  1843. * if the POSITIONS match then it's the Root Item.
  1844. *
  1845. * Arguments:
  1846. *
  1847. * Position - Position to test
  1848. *
  1849. * Return Value:
  1850. *
  1851. * status
  1852. *
  1853. * History:
  1854. *
  1855. * 2/14/1999 Original Version
  1856. *
  1857. \**************************************************************************/
  1858. BOOL CWIA::IsRoot(POSITION Position)
  1859. {
  1860. if (m_ActiveTreeList.GetHeadPosition() == Position)
  1861. return TRUE;
  1862. else
  1863. return FALSE;
  1864. }
  1865. /**************************************************************************\
  1866. * CWIA::IsFolder()
  1867. *
  1868. * Checks the item at the target POSITION about it's type.
  1869. *
  1870. * Arguments:
  1871. *
  1872. * Position - Position to test
  1873. *
  1874. * Return Value:
  1875. *
  1876. * status
  1877. *
  1878. * History:
  1879. *
  1880. * 2/14/1999 Original Version
  1881. *
  1882. \**************************************************************************/
  1883. BOOL CWIA::IsFolder(POSITION Position)
  1884. {
  1885. IWiaItem* pIWiaItem = NULL;
  1886. long lVal = 0;
  1887. if (Position) {
  1888. WIAITEMTREENODE* pWiaItemTreeNode = (WIAITEMTREENODE*)m_ActiveTreeList.GetAt(Position);
  1889. pIWiaItem = pWiaItemTreeNode->pIWiaItem;
  1890. }
  1891. if (pIWiaItem != NULL) {
  1892. IWiaPropertyStorage *pIWiaPropStg;
  1893. HRESULT hResult = S_OK;
  1894. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  1895. if (hResult == S_OK) {
  1896. //
  1897. // read Item's Type
  1898. //
  1899. hResult = ReadPropLong(WIA_IPA_ITEM_FLAGS, pIWiaPropStg, &lVal);
  1900. if (hResult != S_OK)
  1901. StressStatus("* ReadPropLong(WIA_IPA_ITEM_FLAGS) Failed",hResult);
  1902. else
  1903. pIWiaPropStg->Release();
  1904. if (lVal == WiaItemTypeFolder) {
  1905. return TRUE;
  1906. } else {
  1907. return FALSE;
  1908. }
  1909. }
  1910. } else
  1911. return FALSE;
  1912. return FALSE;
  1913. }
  1914. /**************************************************************************\
  1915. * CWIA::GetAt()
  1916. *
  1917. * Returns the WIAITEMTREENODE* at the target position
  1918. *
  1919. * Arguments:
  1920. *
  1921. * Position - target Position
  1922. *
  1923. * Return Value:
  1924. *
  1925. * WIAITEMTREENODE* pWiaItemTreeNode - requested node
  1926. *
  1927. * History:
  1928. *
  1929. * 2/14/1999 Original Version
  1930. *
  1931. \**************************************************************************/
  1932. WIAITEMTREENODE* CWIA::GetAt(POSITION Position)
  1933. {
  1934. POSITION TestPosition = m_ActiveTreeList.GetHeadPosition();
  1935. if (TestPosition == Position)
  1936. return(m_ActiveTreeList.GetAt(Position));
  1937. while (TestPosition) {
  1938. m_ActiveTreeList.GetNext(TestPosition);
  1939. if (TestPosition == Position)
  1940. return(m_ActiveTreeList.GetAt(Position));
  1941. }
  1942. return NULL;
  1943. }
  1944. /**************************************************************************\
  1945. * CWIA::GetRootItemType()
  1946. *
  1947. * Returns the Root item's type
  1948. *
  1949. * Arguments:
  1950. *
  1951. * none
  1952. *
  1953. * Return Value:
  1954. *
  1955. * Root Item's Type (device type)
  1956. *
  1957. * History:
  1958. *
  1959. * 2/14/1999 Original Version
  1960. *
  1961. \**************************************************************************/
  1962. int CWIA::GetRootItemType()
  1963. {
  1964. long lVal = 0;
  1965. if (m_pRootIWiaItem != NULL) {
  1966. IWiaPropertyStorage *pIWiaPropStg;
  1967. HRESULT hResult = S_OK;
  1968. hResult = m_pRootIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
  1969. if (hResult == S_OK) {
  1970. //
  1971. // read Root Item's Type
  1972. //
  1973. hResult = ReadPropLong(WIA_DIP_DEV_TYPE, pIWiaPropStg, &lVal);
  1974. if (hResult != S_OK)
  1975. StressStatus("* ReadPropLong(WIA_DIP_DEV_TYPE) Failed",hResult);
  1976. else
  1977. pIWiaPropStg->Release();
  1978. }
  1979. }
  1980. return(GET_STIDEVICE_TYPE(lVal));
  1981. }
  1982. /**************************************************************************\
  1983. * CWIA::RemoveAt()
  1984. *
  1985. * Removes the WIAITEMTREENODE* at the target position
  1986. *
  1987. * Arguments:
  1988. *
  1989. * Position - target Position
  1990. *
  1991. * Return Value:
  1992. *
  1993. * void
  1994. *
  1995. * History:
  1996. *
  1997. * 2/14/1999 Original Version
  1998. *
  1999. \**************************************************************************/
  2000. void CWIA::RemoveAt(POSITION Position)
  2001. {
  2002. m_ActiveTreeList.RemoveAt(Position);
  2003. }
  2004. /**************************************************************************\
  2005. * CWIA::GetDIB()
  2006. *
  2007. * Returns the CDIB pointer for display
  2008. *
  2009. * Arguments:
  2010. *
  2011. * none
  2012. *
  2013. * Return Value:
  2014. *
  2015. * CDib* - Pointer to a CDIB object
  2016. *
  2017. * History:
  2018. *
  2019. * 2/14/1999 Original Version
  2020. *
  2021. \**************************************************************************/
  2022. CDib* CWIA::GetDIB()
  2023. {
  2024. return m_pDIB;
  2025. }
  2026. /**************************************************************************\
  2027. * CWIA::GetSupportedFormatList()
  2028. *
  2029. * Returns a pointer to the supported format list
  2030. *
  2031. * Arguments:
  2032. *
  2033. * none
  2034. *
  2035. * Return Value:
  2036. *
  2037. * CPtrList* - pointer to Supported FormatEtc list
  2038. *
  2039. * History:
  2040. *
  2041. * 2/14/1999 Original Version
  2042. *
  2043. \**************************************************************************/
  2044. CPtrList* CWIA::GetSupportedFormatList()
  2045. {
  2046. return &m_SupportedFormatList;
  2047. }
  2048. /**************************************************************************\
  2049. * CWIA::RegisterForConnectEvents()
  2050. *
  2051. * Registers an application for Connect events only
  2052. *
  2053. * Arguments:
  2054. *
  2055. * pConnectEventCB - pointer to a callback
  2056. *
  2057. * Return Value:
  2058. *
  2059. * status
  2060. *
  2061. * History:
  2062. *
  2063. * 2/14/1999 Original Version
  2064. *
  2065. \**************************************************************************/
  2066. HRESULT CWIA::RegisterForConnectEvents(CEventCallback* pConnectEventCB)
  2067. {
  2068. HRESULT hResult = S_OK;
  2069. IWiaEventCallback* pIWiaEventCallback = NULL;
  2070. IUnknown* pIUnkRelease;
  2071. // register connected event
  2072. pConnectEventCB->Initialize(ID_WIAEVENT_CONNECT);
  2073. pConnectEventCB->QueryInterface(IID_IWiaEventCallback,(void **)&pIWiaEventCallback);
  2074. GUID guidConnect = WIA_EVENT_DEVICE_CONNECTED;
  2075. hResult = m_pIWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
  2076. NULL,
  2077. &guidConnect,
  2078. pIWiaEventCallback,
  2079. &pIUnkRelease);
  2080. pConnectEventCB->m_pIUnkRelease = pIUnkRelease;
  2081. return hResult;
  2082. }
  2083. /**************************************************************************\
  2084. * CWIA::UnRegisterForConnectEvents()
  2085. *
  2086. * UnRegisters an application from Connect events only.
  2087. * note: callback interface is released, and deleted by
  2088. * this routine.
  2089. *
  2090. * Arguments:
  2091. *
  2092. * pConnectEventCB - pointer to a callback
  2093. *
  2094. * Return Value:
  2095. *
  2096. * status
  2097. *
  2098. * History:
  2099. *
  2100. * 2/14/1999 Original Version
  2101. *
  2102. \**************************************************************************/
  2103. HRESULT CWIA::UnRegisterForConnectEvents(CEventCallback* pConnectEventCB)
  2104. {
  2105. if (pConnectEventCB) {
  2106. //IWiaEventCallback* pIWiaEventCallback = NULL;
  2107. //pConnectEventCB->QueryInterface(IID_IWiaEventCallback,(void **)&pIWiaEventCallback);
  2108. //
  2109. // unregister connected
  2110. //GUID guidConnect = WIA_EVENT_DEVICE_CONNECTED;
  2111. //hResult = m_pIWiaDevMgr->RegisterEventCallbackInterface(WIA_UNREGISTER_EVENT_CALLBACK,
  2112. // NULL,
  2113. // &guidConnect,
  2114. // pIWiaEventCallback);
  2115. //if (hResult == S_OK)
  2116. // StressStatus("ConnectEventCB unregistered successfully...");
  2117. //else
  2118. // StressStatus("* ConnectEventCB failed to unregister..",hResult);
  2119. pConnectEventCB->m_pIUnkRelease->Release();
  2120. pConnectEventCB->m_pIUnkRelease = NULL;
  2121. pConnectEventCB->Release();
  2122. }
  2123. return S_OK;
  2124. }
  2125. /**************************************************************************\
  2126. * CWIA::RegisterForDisConnectEvents()
  2127. *
  2128. * Registers an application for disconnect events only
  2129. *
  2130. * Arguments:
  2131. *
  2132. * pDisConnectEventCB - pointer to a callback
  2133. *
  2134. * Return Value:
  2135. *
  2136. * status
  2137. *
  2138. * History:
  2139. *
  2140. * 2/14/1999 Original Version
  2141. *
  2142. \**************************************************************************/
  2143. HRESULT CWIA::RegisterForDisConnectEvents(CEventCallback* pDisConnectEventCB)
  2144. {
  2145. HRESULT hResult = S_OK;
  2146. IWiaEventCallback* pIWiaEventCallback = NULL;
  2147. IUnknown* pIUnkRelease;
  2148. // register disconnected event
  2149. pDisConnectEventCB->Initialize(ID_WIAEVENT_DISCONNECT);
  2150. pDisConnectEventCB->QueryInterface(IID_IWiaEventCallback,(void **)&pIWiaEventCallback);
  2151. GUID guidDisconnect = WIA_EVENT_DEVICE_DISCONNECTED;
  2152. hResult = m_pIWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
  2153. NULL,
  2154. &guidDisconnect,
  2155. pIWiaEventCallback,
  2156. &pIUnkRelease);
  2157. pDisConnectEventCB->m_pIUnkRelease = pIUnkRelease;
  2158. return hResult;
  2159. }
  2160. /**************************************************************************\
  2161. * CWIA::UnRegisterForDisConnectEvents()
  2162. *
  2163. * UnRegisters an application from disconnect events only.
  2164. * note: callback interface is released, and deleted by
  2165. * this routine.
  2166. *
  2167. * Arguments:
  2168. *
  2169. * pDisConnectEventCB - pointer to a callback
  2170. *
  2171. * Return Value:
  2172. *
  2173. * status
  2174. *
  2175. * History:
  2176. *
  2177. * 2/14/1999 Original Version
  2178. *
  2179. \**************************************************************************/
  2180. HRESULT CWIA::UnRegisterForDisConnectEvents(CEventCallback* pDisConnectEventCB)
  2181. {
  2182. if (pDisConnectEventCB) {
  2183. //IWiaEventCallback* pIWiaEventCallback = NULL;
  2184. //pDisConnectEventCB->QueryInterface(IID_IWiaEventCallback,(void **)&pIWiaEventCallback);
  2185. //
  2186. //// unregister disconnected
  2187. //GUID guidDisconnect = WIA_EVENT_DEVICE_DISCONNECTED;
  2188. //hResult = m_pIWiaDevMgr->RegisterEventCallbackInterface(WIA_UNREGISTER_EVENT_CALLBACK,
  2189. // NULL,
  2190. // &guidDisconnect,
  2191. // pIWiaEventCallback);
  2192. //if (hResult == S_OK)
  2193. // StressStatus("DisConnectEventCB unregistered successfully...");
  2194. //else
  2195. // StressStatus("* DisConnectEventCB failed to unregister..",hResult);
  2196. pDisConnectEventCB->m_pIUnkRelease->Release();
  2197. pDisConnectEventCB->m_pIUnkRelease = NULL;
  2198. pDisConnectEventCB->Release();
  2199. }
  2200. return S_OK;
  2201. }
  2202. /**************************************************************************\
  2203. * CWIA::Shutdown()
  2204. *
  2205. * Forces a temporary shut down of the WIA object
  2206. *
  2207. * Arguments:
  2208. *
  2209. * none
  2210. *
  2211. * Return Value:
  2212. *
  2213. * void
  2214. *
  2215. * History:
  2216. *
  2217. * 2/14/1999 Original Version
  2218. *
  2219. \**************************************************************************/
  2220. void CWIA::Shutdown()
  2221. {
  2222. //
  2223. // Free IWiaItem* list (Active Tree list)
  2224. //
  2225. DeleteActiveTreeList();
  2226. //
  2227. // Free DeviceID list (Device list)
  2228. //
  2229. DeleteWIADeviceList();
  2230. //
  2231. // Free Supported Formats list (FormatEtc list)
  2232. //
  2233. DeleteSupportedFormatList();
  2234. //
  2235. // release WIA Device Manager
  2236. //
  2237. if (m_pIWiaDevMgr) {
  2238. m_pIWiaDevMgr->Release();
  2239. m_pIWiaDevMgr = NULL;
  2240. }
  2241. }
  2242. /**************************************************************************\
  2243. * CWIA::Restart()
  2244. *
  2245. * Forces a reintialization from a Previous ShutDown() call
  2246. *
  2247. * Arguments:
  2248. *
  2249. * none
  2250. *
  2251. * Return Value:
  2252. *
  2253. * void
  2254. *
  2255. * History:
  2256. *
  2257. * 2/14/1999 Original Version
  2258. *
  2259. \**************************************************************************/
  2260. void CWIA::Restart()
  2261. {
  2262. HRESULT hResult = S_OK;
  2263. //
  2264. // create a WIA device manager
  2265. //
  2266. hResult = CreateWIADeviceManager();
  2267. if (FAILED(hResult))
  2268. StressStatus("* CreateWIADeviceManager Failed",hResult);
  2269. //
  2270. // enumerate WIA devices
  2271. //
  2272. hResult = EnumerateAllWIADevices();
  2273. if (FAILED(hResult))
  2274. StressStatus("* EnumerateAllWIADevices Failed",hResult);
  2275. }
  2276. /**************************************************************************\
  2277. * CWIA::EnableMessageBoxErrorReport()
  2278. *
  2279. * Enables, disables MessageBox reporting to the user
  2280. *
  2281. * Arguments:
  2282. *
  2283. * bEnable - (TRUE = enable) (FALSE = disable)
  2284. *
  2285. * Return Value:
  2286. *
  2287. * void
  2288. *
  2289. * History:
  2290. *
  2291. * 2/14/1999 Original Version
  2292. *
  2293. \**************************************************************************/
  2294. void CWIA::EnableMessageBoxErrorReport(BOOL bEnable)
  2295. {
  2296. m_bMessageBoxReport = bEnable;
  2297. }
  2298. /**************************************************************************\
  2299. * CWIA::SavePropStreamToFile()
  2300. *
  2301. * Saves a property stream from an IWiaItem to a file
  2302. *
  2303. * Arguments:
  2304. *
  2305. * pFileName - Property Stream file name
  2306. * pIWiaItem - Item, to save stream from
  2307. *
  2308. * Return Value:
  2309. *
  2310. * status
  2311. *
  2312. * History:
  2313. *
  2314. * 6/8/1999 Original Version
  2315. *
  2316. \**************************************************************************/
  2317. HRESULT CWIA::SavePropStreamToFile(char* pFileName, IWiaItem* pIWiaItem)
  2318. {
  2319. IStream *pIStrm = NULL;
  2320. CFile StreamFile;
  2321. CFileException Exception;
  2322. HRESULT hResult = S_OK;
  2323. IWiaPropertyStorage *pIWiaPropStg;
  2324. GUID guidCompatId;
  2325. if (pIWiaItem != NULL) {
  2326. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**) &pIWiaPropStg);
  2327. if (FAILED(hResult)) {
  2328. StressStatus("* QI for IWiaPropertySTorage Failed",hResult);
  2329. return hResult;
  2330. }
  2331. hResult = pIWiaPropStg->GetPropertyStream(&guidCompatId, &pIStrm);
  2332. if (SUCCEEDED(hResult)) {
  2333. //
  2334. // Save Property Stream to File (propstrm.wia). We choose to ignore the CompatID
  2335. //
  2336. //
  2337. // open file, this will create a new file every time (overwriting the original)
  2338. //
  2339. if ( StreamFile.Open(pFileName,CFile::modeCreate|CFile::modeWrite,&Exception)) {
  2340. //
  2341. // Get stream size.
  2342. //
  2343. ULARGE_INTEGER uliSize;
  2344. LARGE_INTEGER liOrigin = {0,0};
  2345. pIStrm->Seek(liOrigin, STREAM_SEEK_END, &uliSize);
  2346. DWORD dwSize = uliSize.u.LowPart;
  2347. if (dwSize) {
  2348. //
  2349. // write stream size in first 4 byte location
  2350. //
  2351. StreamFile.Write(&dwSize, sizeof(long));
  2352. //
  2353. // Read the stream data into a buffer.
  2354. //
  2355. PBYTE pBuf = (PBYTE) LocalAlloc(0, dwSize);
  2356. if (pBuf) {
  2357. pIStrm->Seek(liOrigin, STREAM_SEEK_SET, NULL);
  2358. ULONG ulRead;
  2359. pIStrm->Read(pBuf, dwSize, &ulRead);
  2360. //
  2361. // write stream to file
  2362. //
  2363. StreamFile.Write(pBuf, ulRead);
  2364. LocalFree(pBuf);
  2365. }
  2366. }
  2367. StreamFile.Close();
  2368. } else {
  2369. //
  2370. // Throw an Exception for Open Failure
  2371. //
  2372. AfxThrowFileException(Exception.m_cause);
  2373. }
  2374. pIStrm->Release();
  2375. } else {
  2376. StressStatus("* GetPropertyStream Failed",hResult);
  2377. }
  2378. pIWiaPropStg->Release();
  2379. }
  2380. return hResult;
  2381. }
  2382. /**************************************************************************\
  2383. * CWIA::ReadPropStreamFromFile()
  2384. *
  2385. * Reads a property stream from an a previously saved file
  2386. * and writes this stream to the pIWiaItem
  2387. *
  2388. * Arguments:
  2389. *
  2390. * pFileName - Property Stream file name
  2391. * pIWiaItem - Item, to save stream to
  2392. *
  2393. * Return Value:
  2394. *
  2395. * status
  2396. *
  2397. * History:
  2398. *
  2399. * 6/8/1999 Original Version
  2400. *
  2401. \**************************************************************************/
  2402. HRESULT CWIA::ReadPropStreamFromFile(char* pFileName, IWiaItem* pIWiaItem)
  2403. {
  2404. HGLOBAL hMem = NULL;
  2405. LPSTREAM pstmProp = NULL;
  2406. LPBYTE pStreamData = NULL;
  2407. CFile StreamFile;
  2408. CFileException Exception;
  2409. HRESULT hResult = S_OK;
  2410. IWiaPropertyStorage *pIWiaPropStg;
  2411. if (pIWiaItem != NULL) {
  2412. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**) &pIWiaPropStg);
  2413. if (FAILED(hResult)) {
  2414. StressStatus("* QI for IWiaPropertySTorage Failed",hResult);
  2415. return hResult;
  2416. }
  2417. //
  2418. // Open stream data file
  2419. //
  2420. if ( StreamFile.Open(pFileName,CFile::modeRead,&Exception)) {
  2421. //
  2422. // read the size of the stream from stream data file
  2423. //
  2424. DWORD dwSize = 0;
  2425. StreamFile.Read(&dwSize,sizeof(long));
  2426. if (dwSize) {
  2427. //
  2428. // allocate memory for hMem, which will be Locked to
  2429. // create pStreamData
  2430. //
  2431. hMem = GlobalAlloc(GMEM_MOVEABLE, dwSize);
  2432. if (hMem) {
  2433. pStreamData = (LPBYTE)GlobalLock(hMem);
  2434. if (pStreamData != NULL) {
  2435. //
  2436. // Read stored stream data from stream file
  2437. //
  2438. if (StreamFile.Read(pStreamData,dwSize) != dwSize) {
  2439. StressStatus("File contains different amount of data than specified by header...");
  2440. //
  2441. // clean up and bail
  2442. //
  2443. GlobalUnlock(hMem);
  2444. GlobalFree(pStreamData);
  2445. //
  2446. // close file
  2447. //
  2448. StreamFile.Close();
  2449. return E_FAIL;
  2450. } else {
  2451. //
  2452. // Create the hStream
  2453. //
  2454. hResult = CreateStreamOnHGlobal(hMem, TRUE, &pstmProp);
  2455. if (SUCCEEDED(hResult)) {
  2456. //
  2457. // Set stored property stream back to IWiaItem. Use
  2458. // GUID_NULL for CompatId since we didn't store it.
  2459. //
  2460. hResult = pIWiaPropStg->SetPropertyStream((GUID*) &GUID_NULL, pstmProp);
  2461. if (SUCCEEDED(hResult))
  2462. StressStatus("Stream was successfully written....");
  2463. else
  2464. StressStatus("* SetPropertyStream Failed",hResult);
  2465. //
  2466. // Release stream (IStream*)
  2467. //
  2468. pstmProp->Release();
  2469. } else{
  2470. StressStatus("* CreateStreamOnHGlobal() failed",hResult);
  2471. }
  2472. }
  2473. GlobalUnlock(hMem);
  2474. } else{
  2475. StressStatus("* GlobalLock() Failed");
  2476. }
  2477. } else{
  2478. StressStatus("* GlobalAlloc Failed");
  2479. }
  2480. } else {
  2481. StressStatus("* Stream size read from file was 0 bytes");
  2482. }
  2483. //
  2484. // close file
  2485. //
  2486. StreamFile.Close();
  2487. } else {
  2488. //
  2489. // Throw an Exception for Open Failure
  2490. //
  2491. AfxThrowFileException(Exception.m_cause);
  2492. }
  2493. pIWiaPropStg->Release();
  2494. }
  2495. return hResult;
  2496. }
  2497. /**************************************************************************\
  2498. * CWIA::GetSetPropStreamTest()
  2499. *
  2500. * Gets the property stream from the item, and
  2501. * Sets it back to the same item.
  2502. *
  2503. * Arguments:
  2504. *
  2505. * pIWiaItem - Item, to Test
  2506. *
  2507. * Return Value:
  2508. *
  2509. * status
  2510. *
  2511. * History:
  2512. *
  2513. * 6/8/1999 Original Version
  2514. *
  2515. \**************************************************************************/
  2516. HRESULT CWIA::GetSetPropStreamTest(IWiaItem* pIWiaItem)
  2517. {
  2518. HGLOBAL hStream = NULL;
  2519. LPSTREAM pstmProp = NULL;
  2520. CFile StreamFile;
  2521. CFileException Exception;
  2522. HRESULT hResult = S_OK;
  2523. IWiaPropertyStorage *pIWiaPropStg;
  2524. GUID guidCompatId;
  2525. if (pIWiaItem != NULL) {
  2526. hResult = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**) &pIWiaPropStg);
  2527. if (FAILED(hResult)) {
  2528. StressStatus("* QI for IWiaPropertySTorage Failed",hResult);
  2529. return hResult;
  2530. }
  2531. hResult = pIWiaPropStg->GetPropertyStream(&guidCompatId, &pstmProp);
  2532. if (SUCCEEDED(hResult)) {
  2533. hResult = pIWiaPropStg->SetPropertyStream(&guidCompatId, pstmProp);
  2534. if (SUCCEEDED(hResult))
  2535. MessageBox(NULL,"Successful GET - SET stream call","WIATest Debug Status",MB_OK);
  2536. else
  2537. StressStatus("* SetPropertyStream() Failed",hResult);
  2538. //
  2539. // Free the stream
  2540. //
  2541. pstmProp->Release();
  2542. } else
  2543. StressStatus("* GetPropertyStream() Failed",hResult);
  2544. pIWiaPropStg->Release();
  2545. }
  2546. return hResult;
  2547. }
  2548. /**************************************************************************\
  2549. * CWIA::AnalyzeItem()
  2550. *
  2551. * Runs the AnalyzeItem method from the specified IWiaItem.
  2552. *
  2553. * Arguments:
  2554. *
  2555. * pIWiaItem - Item, to run analysis on
  2556. *
  2557. * Return Value:
  2558. *
  2559. * status
  2560. *
  2561. * History:
  2562. *
  2563. * 01/13/2000 Original Version
  2564. *
  2565. \**************************************************************************/
  2566. HRESULT CWIA::AnalyzeItem(IWiaItem* pIWiaItem)
  2567. {
  2568. return pIWiaItem->AnalyzeItem(0);
  2569. }
  2570. /**************************************************************************\
  2571. * CWIA::CreateChildItem()
  2572. *
  2573. * Runs the CreateChildItem method from the specified IWiaItem.
  2574. *
  2575. * Arguments:
  2576. *
  2577. * pIWiaItem - Item, to run CreateChildItem on
  2578. *
  2579. * Return Value:
  2580. *
  2581. * status
  2582. *
  2583. * History:
  2584. *
  2585. * 01/13/2000 Original Version
  2586. *
  2587. \**************************************************************************/
  2588. HRESULT CWIA::CreateChildItem(IWiaItem *pIWiaItem)
  2589. {
  2590. HRESULT hr = E_FAIL;
  2591. IWiaItem *pNewIWiaItem = NULL;
  2592. IWiaPropertyStorage *pIWiaPropStg = NULL;
  2593. BSTR bstrName = NULL;
  2594. BSTR bstrFullName = NULL;
  2595. WCHAR wszName[MAX_PATH];
  2596. WCHAR wszFullName[MAX_PATH];
  2597. //
  2598. // Get the property storage so we can read the full item name.
  2599. //
  2600. hr = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,
  2601. (VOID**)&pIWiaPropStg);
  2602. if (SUCCEEDED(hr)) {
  2603. hr = ReadPropStr(WIA_IPA_FULL_ITEM_NAME,
  2604. pIWiaPropStg,
  2605. &bstrFullName);
  2606. if (SUCCEEDED(hr)) {
  2607. //
  2608. // Fill in the item name and full item name.
  2609. //
  2610. wcscpy(wszName, L"WiaTestItem");
  2611. wcscpy(wszFullName, bstrFullName);
  2612. wcscat(wszFullName, L"\\");
  2613. wcscat(wszFullName, wszName);
  2614. SysFreeString(bstrFullName);
  2615. bstrFullName = SysAllocString(wszFullName);
  2616. bstrName = SysAllocString(wszName);
  2617. if (bstrFullName && bstrName) {
  2618. hr = pIWiaItem->CreateChildItem(WiaItemTypeTransfer |
  2619. WiaItemTypeImage |
  2620. WiaItemTypeFile,
  2621. bstrName,
  2622. bstrFullName,
  2623. &pNewIWiaItem);
  2624. if (SUCCEEDED(hr)) {
  2625. //
  2626. // Release the newly created item which was returned
  2627. // to us.
  2628. //
  2629. pNewIWiaItem->Release();
  2630. } else {
  2631. StressStatus("* CreateChildItem call failed");
  2632. }
  2633. } else {
  2634. hr = E_OUTOFMEMORY;
  2635. StressStatus("* Could not allocate name strings");
  2636. }
  2637. } else {
  2638. StressStatus("* Could not read full item name");
  2639. }
  2640. pIWiaPropStg->Release();
  2641. } else {
  2642. StressStatus("* QI for IWiaPropertyStorage failed");
  2643. }
  2644. return hr;
  2645. }