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.

356 lines
12 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: SCANITEM.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 10/7/1999
  12. *
  13. * DESCRIPTION:
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include <vwiaset.h>
  19. CScannerItem::CScannerItem(void)
  20. : m_dwIWiaItemCookie(0)
  21. {
  22. m_AspectRatio.cx = m_AspectRatio.cy = 0;
  23. }
  24. CScannerItem::CScannerItem( const CScannerItem &other )
  25. : m_dwIWiaItemCookie(0)
  26. {
  27. m_AspectRatio.cx = m_AspectRatio.cy = 0;
  28. Assign(other);
  29. }
  30. CScannerItem::CScannerItem( IWiaItem *pIWiaItem )
  31. : m_dwIWiaItemCookie(0)
  32. {
  33. m_AspectRatio.cx = m_AspectRatio.cy = 0;
  34. Initialize( pIWiaItem );
  35. }
  36. CScannerItem::~CScannerItem(void)
  37. {
  38. Destroy();
  39. }
  40. CComPtr<IWiaItem> CScannerItem::Item(void) const
  41. {
  42. return(m_pIWiaItem);
  43. }
  44. SIZE CScannerItem::AspectRatio(void) const
  45. {
  46. return(m_AspectRatio);
  47. }
  48. DWORD CScannerItem::Cookie(void) const
  49. {
  50. return(m_dwIWiaItemCookie);
  51. }
  52. CScannerItem &CScannerItem::Assign( const CScannerItem &other )
  53. {
  54. WIA_PUSHFUNCTION(TEXT("CScannerItem::Assign"));
  55. if (&other == this)
  56. return(*this);
  57. Initialize( other.Item() );
  58. return(*this);
  59. }
  60. bool CScannerItem::operator==( const CScannerItem &other )
  61. {
  62. return(m_pIWiaItem.p == other.Item().p);
  63. }
  64. CScannerItem &CScannerItem::operator=( const CScannerItem &other )
  65. {
  66. return(Assign(other));
  67. }
  68. HRESULT CScannerItem::Destroy(void)
  69. {
  70. WIA_PUSHFUNCTION(TEXT("CScannerItem::Destroy"));
  71. HRESULT hr = E_FAIL;
  72. if (m_dwIWiaItemCookie)
  73. {
  74. CComPtr<IGlobalInterfaceTable> pGlobalInterfaceTable;
  75. hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)&pGlobalInterfaceTable );
  76. if (SUCCEEDED(hr))
  77. {
  78. WIA_TRACE((TEXT("Calling RevokeInterfaceFromGlobal on %08X"), m_dwIWiaItemCookie ));
  79. hr = pGlobalInterfaceTable->RevokeInterfaceFromGlobal( m_dwIWiaItemCookie );
  80. }
  81. m_dwIWiaItemCookie = 0;
  82. }
  83. m_pIWiaItem = NULL;
  84. return(hr);
  85. }
  86. HRESULT CScannerItem::Initialize( IWiaItem *pIWiaItem )
  87. {
  88. WIA_PUSHFUNCTION(TEXT("CScannerItem::Initialize"));
  89. Destroy();
  90. HRESULT hr = E_FAIL;
  91. IWiaPropertyStorage *pIWiaPropertyStorage;
  92. if (pIWiaItem)
  93. {
  94. m_pIWiaItem = pIWiaItem;
  95. CComPtr<IGlobalInterfaceTable> pGlobalInterfaceTable;
  96. hr = CoCreateInstance( CLSID_StdGlobalInterfaceTable, NULL, CLSCTX_INPROC_SERVER, IID_IGlobalInterfaceTable, (void **)&pGlobalInterfaceTable );
  97. if (SUCCEEDED(hr))
  98. {
  99. hr = pGlobalInterfaceTable->RegisterInterfaceInGlobal( m_pIWiaItem, IID_IWiaItem, &m_dwIWiaItemCookie );
  100. if (SUCCEEDED(hr))
  101. {
  102. hr = m_pIWiaItem->QueryInterface(IID_IWiaPropertyStorage, (void**) &pIWiaPropertyStorage);
  103. if (SUCCEEDED(hr))
  104. {
  105. hr = m_SavedPropertyStream.AssignFromWiaItem(m_pIWiaItem);
  106. if (SUCCEEDED(hr))
  107. {
  108. IWiaItem *pRootItem = NULL;
  109. hr = m_pIWiaItem->GetRootItem(&pRootItem);
  110. if (SUCCEEDED(hr))
  111. {
  112. LONG lBedSizeX, lBedSizeY;
  113. if (PropStorageHelpers::GetProperty( pRootItem, WIA_DPS_HORIZONTAL_BED_SIZE, lBedSizeX ) &&
  114. PropStorageHelpers::GetProperty( pRootItem, WIA_DPS_VERTICAL_BED_SIZE, lBedSizeY ))
  115. {
  116. m_AspectRatio.cx = lBedSizeX;
  117. m_AspectRatio.cy = lBedSizeY;
  118. }
  119. pRootItem->Release();
  120. }
  121. }
  122. pIWiaPropertyStorage->Release();
  123. }
  124. }
  125. }
  126. }
  127. if (!SUCCEEDED(hr))
  128. {
  129. Destroy();
  130. }
  131. return(hr);
  132. }
  133. bool CScannerItem::GetAspectRatio( SIZE &sizeAspectRatio )
  134. {
  135. WIA_PUSHFUNCTION(TEXT("CScannerItem::GetAspectRatio"));
  136. if (m_AspectRatio.cx && m_AspectRatio.cy)
  137. {
  138. sizeAspectRatio = m_AspectRatio;
  139. return(true);
  140. }
  141. return(false);
  142. }
  143. bool CScannerItem::ApplyCurrentPreviewWindowSettings( HWND hWndPreview )
  144. {
  145. WIA_PUSHFUNCTION(TEXT("CScannerItem::ApplyCurrentPreviewWindowSettings"));
  146. SIZE sizeCurrentRes, sizeFullRes;
  147. SIZE sizeExtent;
  148. POINT ptOrigin;
  149. //
  150. // Get the current resolution
  151. //
  152. if (PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_XRES, sizeCurrentRes.cx ) &&
  153. PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_YRES, sizeCurrentRes.cy ))
  154. {
  155. //
  156. // Compute the full page resolution of the item
  157. //
  158. if (GetFullResolution( sizeCurrentRes, sizeFullRes ))
  159. {
  160. //
  161. // Set the resolution in the preview control
  162. //
  163. SendMessage( hWndPreview, PWM_SETRESOLUTION, 0, (LPARAM)&sizeFullRes );
  164. //
  165. // Get the origin and extent
  166. //
  167. SendMessage( hWndPreview, PWM_GETSELORIGIN, MAKEWPARAM(0,0), (LPARAM)&ptOrigin );
  168. SendMessage( hWndPreview, PWM_GETSELEXTENT, MAKEWPARAM(0,0), (LPARAM)&sizeExtent );
  169. WIA_TRACE(( TEXT("Current DPI: (%d,%d), Full Bed Res: (%d,%d), Origin: (%d,%d), Extent: (%d,%d)"), sizeCurrentRes.cx, sizeCurrentRes.cy, sizeFullRes.cx, sizeFullRes.cy, ptOrigin.x, ptOrigin.y, sizeExtent.cx, sizeExtent.cy ));
  170. //
  171. // Set the origin and extents. We don't set them directly, because they might not be a correct multiple
  172. //
  173. CValidWiaSettings::SetNumericPropertyOnBoundary( m_pIWiaItem, WIA_IPS_XPOS, ptOrigin.x );
  174. CValidWiaSettings::SetNumericPropertyOnBoundary( m_pIWiaItem, WIA_IPS_YPOS, ptOrigin.y );
  175. CValidWiaSettings::SetNumericPropertyOnBoundary( m_pIWiaItem, WIA_IPS_XEXTENT, sizeExtent.cx );
  176. CValidWiaSettings::SetNumericPropertyOnBoundary( m_pIWiaItem, WIA_IPS_YEXTENT, sizeExtent.cy );
  177. return(true);
  178. }
  179. }
  180. return(false);
  181. }
  182. /* Calculate the maximum scan size using the give DPI */
  183. bool CScannerItem::GetFullResolution( const SIZE &sizeResolutionPerInch, SIZE &sizeRes )
  184. {
  185. WIA_PUSHFUNCTION(TEXT("CScannerItem::GetFullResolution"));
  186. CComPtr<IWiaItem> pRootItem;
  187. if (SUCCEEDED(m_pIWiaItem->GetRootItem(&pRootItem)) && pRootItem)
  188. {
  189. LONG lBedSizeX, lBedSizeY, nPaperSource;
  190. if (PropStorageHelpers::GetProperty( pRootItem, WIA_DPS_DOCUMENT_HANDLING_SELECT, static_cast<LONG>(nPaperSource)) && nPaperSource & FEEDER)
  191. {
  192. if (PropStorageHelpers::GetProperty( pRootItem, WIA_DPS_HORIZONTAL_SHEET_FEED_SIZE, lBedSizeX ) &&
  193. PropStorageHelpers::GetProperty( pRootItem, WIA_DPS_VERTICAL_SHEET_FEED_SIZE, lBedSizeY ))
  194. {
  195. sizeRes.cx = WiaUiUtil::MulDivNoRound( sizeResolutionPerInch.cx, lBedSizeX, 1000 );
  196. sizeRes.cy = WiaUiUtil::MulDivNoRound( sizeResolutionPerInch.cy, lBedSizeY, 1000 );
  197. return(true);
  198. }
  199. }
  200. if (PropStorageHelpers::GetProperty( pRootItem, WIA_DPS_HORIZONTAL_BED_SIZE, lBedSizeX ) &&
  201. PropStorageHelpers::GetProperty( pRootItem, WIA_DPS_VERTICAL_BED_SIZE, lBedSizeY ))
  202. {
  203. sizeRes.cx = WiaUiUtil::MulDivNoRound( sizeResolutionPerInch.cx, lBedSizeX, 1000 );
  204. sizeRes.cy = WiaUiUtil::MulDivNoRound( sizeResolutionPerInch.cy, lBedSizeY, 1000 );
  205. return(true);
  206. }
  207. }
  208. return(false);
  209. }
  210. void CScannerItem::Cancel(void)
  211. {
  212. m_CancelEvent.Signal();
  213. }
  214. bool CScannerItem::CalculatePreviewResolution( SIZE &sizeResolution )
  215. {
  216. const LONG nDesiredResolution = 50;
  217. PropStorageHelpers::CPropertyRange XResolutionRange, YResolutionRange;
  218. if (PropStorageHelpers::GetPropertyRange( m_pIWiaItem, WIA_IPS_XRES, XResolutionRange ) &&
  219. PropStorageHelpers::GetPropertyRange( m_pIWiaItem, WIA_IPS_YRES, YResolutionRange ))
  220. {
  221. sizeResolution.cx = WiaUiUtil::GetMinimum<LONG>( XResolutionRange.nMin, nDesiredResolution, XResolutionRange.nStep );
  222. sizeResolution.cy = WiaUiUtil::GetMinimum<LONG>( YResolutionRange.nMin, nDesiredResolution, YResolutionRange.nStep );
  223. return(true);
  224. }
  225. else
  226. {
  227. CSimpleDynamicArray<LONG> XResolutionList, YResolutionList;
  228. if (PropStorageHelpers::GetPropertyList( m_pIWiaItem, WIA_IPS_XRES, XResolutionList ) &&
  229. PropStorageHelpers::GetPropertyList( m_pIWiaItem, WIA_IPS_YRES, YResolutionList ))
  230. {
  231. for (int i=0;i<XResolutionList.Size();i++)
  232. {
  233. sizeResolution.cx = XResolutionList[i];
  234. if (sizeResolution.cx >= nDesiredResolution)
  235. break;
  236. }
  237. for (i=0;i<YResolutionList.Size();i++)
  238. {
  239. sizeResolution.cy = YResolutionList[i];
  240. if (sizeResolution.cy >= nDesiredResolution)
  241. break;
  242. }
  243. return(true);
  244. }
  245. }
  246. return(false);
  247. }
  248. /*
  249. * Scan: Prepare scan parameters and spawn the scanning thread.
  250. */
  251. HANDLE CScannerItem::Scan( HWND hWndPreview, HWND hWndNotify )
  252. {
  253. WIA_PUSHFUNCTION(TEXT("CScannerItem::Scan"));
  254. POINT ptOrigin;
  255. SIZE sizeExtent;
  256. SIZE sizeResolution;
  257. if (hWndPreview)
  258. {
  259. ptOrigin.x = ptOrigin.y = 0;
  260. if (!CalculatePreviewResolution(sizeResolution))
  261. {
  262. WIA_ERROR((TEXT("Unable to calculate the preview resolution")));
  263. return(NULL);
  264. }
  265. if (!GetFullResolution(sizeResolution,sizeExtent))
  266. {
  267. WIA_ERROR((TEXT("Unable to calculate the preview resolution size")));
  268. return(NULL);
  269. }
  270. }
  271. else
  272. {
  273. if (!PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_XRES, sizeResolution.cx ) ||
  274. !PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_YRES, sizeResolution.cy ) ||
  275. !PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_XPOS, ptOrigin.x) ||
  276. !PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_YPOS, ptOrigin.y) ||
  277. !PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_XEXTENT, sizeExtent.cx) ||
  278. !PropStorageHelpers::GetProperty( m_pIWiaItem, WIA_IPS_YEXTENT, sizeExtent.cy))
  279. {
  280. return(NULL);
  281. }
  282. }
  283. m_CancelEvent.Reset();
  284. HANDLE hScan = CScanPreviewThread::Scan(
  285. m_dwIWiaItemCookie,
  286. hWndPreview,
  287. hWndNotify,
  288. ptOrigin,
  289. sizeResolution,
  290. sizeExtent,
  291. m_CancelEvent
  292. );
  293. return(hScan);
  294. }
  295. HANDLE CScannerItem::Scan( HWND hWndNotify, GUID guidFormat, const CSimpleStringWide &strFilename )
  296. {
  297. return CScanToFileThread::Scan( m_dwIWiaItemCookie, hWndNotify, guidFormat, strFilename );
  298. }
  299. bool CScannerItem::SetIntent( int nIntent )
  300. {
  301. WIA_PUSHFUNCTION(TEXT("CScannerItem::SetIntent"));
  302. CWaitCursor wc;
  303. // Restore the properties to their initial pristine settings first
  304. if (SUCCEEDED(m_SavedPropertyStream.ApplyToWiaItem(m_pIWiaItem)))
  305. {
  306. return(PropStorageHelpers::SetProperty( m_pIWiaItem, WIA_IPS_CUR_INTENT, nIntent ) &&
  307. PropStorageHelpers::SetProperty( m_pIWiaItem, WIA_IPS_CUR_INTENT, 0 ));
  308. }
  309. return false;
  310. }
  311. CSimpleEvent CScannerItem::CancelEvent(void) const
  312. {
  313. return(m_CancelEvent);
  314. }