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.

603 lines
16 KiB

  1. // DataCallback.cpp: implementation of the CDataCallback class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "WIATest.h"
  6. #include "DataCallback.h"
  7. #define IT_MSG_DATA_HEADER 0x0001
  8. #define IT_MSG_DATA 0x0002
  9. #define IT_MSG_STATUS 0x0003
  10. #define IT_MSG_TERMINATION 0x0004
  11. // #define _DEBUGCALLBACK
  12. #ifdef _DEBUG
  13. #undef THIS_FILE
  14. static char THIS_FILE[]=__FILE__;
  15. #define new DEBUG_NEW
  16. #endif
  17. /**************************************************************************\
  18. * CWiaDataCallback::QueryInterface()
  19. *
  20. * QI for IWiadataCallback Interface
  21. *
  22. *
  23. * Arguments:
  24. *
  25. * iid - Interface ID
  26. * ppv - Callback Interface pointer
  27. *
  28. * Return Value:
  29. *
  30. * none
  31. *
  32. * History:
  33. *
  34. * 2/14/1999 Original Version
  35. *
  36. \**************************************************************************/
  37. HRESULT _stdcall CWiaDataCallback::QueryInterface(const IID& iid, void** ppv)
  38. {
  39. *ppv = NULL;
  40. if (iid == IID_IUnknown || iid == IID_IWiaDataCallback)
  41. *ppv = (IWiaDataCallback*) this;
  42. else
  43. return E_NOINTERFACE;
  44. AddRef();
  45. return S_OK;
  46. }
  47. /**************************************************************************\
  48. * CWiaDataCallback::AddRef()
  49. *
  50. * Increment the Ref count
  51. *
  52. *
  53. * Arguments:
  54. *
  55. * none
  56. *
  57. * Return Value:
  58. *
  59. * ULONG - current ref count
  60. *
  61. * History:
  62. *
  63. * 2/14/1999 Original Version
  64. *
  65. \**************************************************************************/
  66. ULONG _stdcall CWiaDataCallback::AddRef()
  67. {
  68. InterlockedIncrement((long*) &m_cRef);
  69. return m_cRef;
  70. }
  71. /**************************************************************************\
  72. * CWiaDataCallback::Release()
  73. *
  74. * Release the callback Interface
  75. *
  76. *
  77. * Arguments:
  78. *
  79. * none
  80. *
  81. * Return Value:
  82. *
  83. * ULONG - Current Ref count
  84. *
  85. * History:
  86. *
  87. * 2/14/1999 Original Version
  88. *
  89. \**************************************************************************/
  90. ULONG _stdcall CWiaDataCallback::Release()
  91. {
  92. ULONG ulRefCount = m_cRef - 1;
  93. if (InterlockedDecrement((long*) &m_cRef) == 0)
  94. {
  95. delete this;
  96. return 0;
  97. }
  98. return ulRefCount;
  99. }
  100. /**************************************************************************\
  101. * CWiaDataCallback::CWiaDataCallback()
  102. *
  103. * Constructor for callback class
  104. *
  105. *
  106. * Arguments:
  107. *
  108. * none
  109. *
  110. * Return Value:
  111. *
  112. * none
  113. *
  114. * History:
  115. *
  116. * 2/14/1999 Original Version
  117. *
  118. \**************************************************************************/
  119. CWiaDataCallback::CWiaDataCallback()
  120. {
  121. m_cRef = 0;
  122. m_pBuffer = NULL;
  123. m_BytesTransfered = 0;
  124. m_hPreviewWnd = NULL;
  125. }
  126. /**************************************************************************\
  127. * CWiaDataCallback::~CWiaDataCallback()
  128. *
  129. * Destructor for Callback class
  130. *
  131. *
  132. * Arguments:
  133. *
  134. * none
  135. *
  136. * Return Value:
  137. *
  138. * none
  139. *
  140. * History:
  141. *
  142. * 2/14/1999 Original Version
  143. *
  144. \**************************************************************************/
  145. CWiaDataCallback::~CWiaDataCallback()
  146. {
  147. if (m_pBuffer != NULL)
  148. {
  149. LocalFree(m_pBuffer);
  150. m_pBuffer = NULL;
  151. }
  152. // destroy progress dlg
  153. m_pMainFrm->SetProgressText(TEXT("Ready"));
  154. m_pMainFrm->UpdateProgress(50);
  155. m_pMainFrm->DestroyProgressCtrl();
  156. }
  157. /**************************************************************************\
  158. * CWiaDataCallback::Initialize()
  159. *
  160. * Initializes Progress control.
  161. *
  162. *
  163. * Arguments:
  164. *
  165. * none
  166. *
  167. * Return Value:
  168. *
  169. * none
  170. *
  171. * History:
  172. *
  173. * 2/14/1999 Original Version
  174. *
  175. \**************************************************************************/
  176. HRESULT _stdcall CWiaDataCallback::Initialize(HWND hPreviewWnd)
  177. {
  178. CWIATestApp* pApp = (CWIATestApp*)AfxGetApp();
  179. m_pMainFrm = (CMainFrame*)pApp->GetMainWnd();
  180. if (m_pMainFrm != NULL)
  181. {
  182. m_pMainFrm->InitializeProgressCtrl("Starting Transfer");
  183. }
  184. m_hPreviewWnd = hPreviewWnd;
  185. m_lPageCount = 0;
  186. return S_OK;
  187. }
  188. /**************************************************************************\
  189. * CWiaDataCallback::BandedDataCallback()
  190. *
  191. * Callback member which handles Banded Data transfers
  192. *
  193. *
  194. * Arguments:
  195. *
  196. * lMessage - callback message
  197. * lStatus - additional message information
  198. * lPercentComplete - current percent complete status
  199. * lOffset - amount of data offset (bytes)
  200. * lLength - amount of data read (bytes)
  201. * lReserved - not used
  202. * lResLength - not used
  203. * pbBuffer - Data header information
  204. *
  205. * Return Value:
  206. *
  207. * status
  208. *
  209. * History:
  210. *
  211. * 2/14/1999 Original Version
  212. *
  213. \**************************************************************************/
  214. HRESULT _stdcall CWiaDataCallback::BandedDataCallback(
  215. LONG lMessage,
  216. LONG lStatus,
  217. LONG lPercentComplete,
  218. LONG lOffset,
  219. LONG lLength,
  220. LONG lReserved,
  221. LONG lResLength,
  222. BYTE* pbBuffer)
  223. {
  224. char szDBG[MAX_PATH];
  225. static BOOL bMorePages = FALSE;
  226. switch (lMessage)
  227. {
  228. case IT_MSG_DATA_HEADER:
  229. {
  230. PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER)pbBuffer;
  231. m_MemBlockSize = pHeader->lBufferSize;
  232. //
  233. // If the Buffer is 0, then alloc a 64k chunk (default)
  234. //
  235. if(m_MemBlockSize <= 0)
  236. m_MemBlockSize = 65535;
  237. m_pBuffer = (PBYTE)LocalAlloc(LPTR,m_MemBlockSize);
  238. m_BytesTransfered = 0;
  239. m_cFormat = pHeader->guidFormatID;
  240. #ifdef _DEBUGCALLBACK
  241. sprintf(szDBG,"Reading Header information\n");
  242. OutputDebugString(szDBG);
  243. sprintf(szDBG,"Header info:\n");
  244. OutputDebugString(szDBG);
  245. sprintf(szDBG," lBufferSize = %li\n",pHeader->lBufferSize);
  246. OutputDebugString(szDBG);
  247. sprintf(szDBG," lFormat = %li\n",pHeader->lFormat);
  248. OutputDebugString(szDBG);
  249. sprintf(szDBG," BytesTransferred = %li\n",m_BytesTransfered);
  250. OutputDebugString(szDBG);
  251. #endif
  252. }
  253. break;
  254. case IT_MSG_DATA:
  255. {
  256. if (m_pBuffer != NULL)
  257. {
  258. if(bMorePages/*m_cFormat == CF_MULTI_TIFF*/){
  259. //
  260. // Display current page count + 1, because Page count is zero based.
  261. //
  262. sprintf(szDBG,"Page(%d) %d%% Complete..",(m_lPageCount + 1), lPercentComplete);
  263. }
  264. else
  265. sprintf(szDBG,"%d%% Complete..",lPercentComplete);
  266. m_pMainFrm->SetProgressText(szDBG);
  267. m_pMainFrm->UpdateProgress(lPercentComplete);
  268. m_BytesTransfered += lLength;
  269. if(m_BytesTransfered >= m_MemBlockSize){
  270. //
  271. // Alloc more memory for transfer buffer
  272. //
  273. m_MemBlockSize += (lLength * 2);
  274. m_pBuffer = (PBYTE)LocalReAlloc(m_pBuffer,m_MemBlockSize,LMEM_MOVEABLE);
  275. }
  276. #ifdef _DEBUGCALLBACK
  277. sprintf(szDBG," Memory BLOCK size = %li\n",m_MemBlockSize);
  278. OutputDebugString(szDBG);
  279. sprintf(szDBG," writing %li\n",lLength);
  280. OutputDebugString(szDBG);
  281. sprintf(szDBG," lOffset = %li, lLength = %li, BytesTransferred = %li\n",lOffset,lLength,m_BytesTransfered);
  282. OutputDebugString(szDBG);
  283. #endif
  284. memcpy(m_pBuffer + lOffset, pbBuffer, lLength);
  285. //
  286. // Paint preview window during callback
  287. //
  288. // WiaImgFmt_UNDEFINED
  289. // ???? m_cFormat == WiaImgFmt_BMP)
  290. if(m_cFormat == WiaImgFmt_MEMORYBMP)
  291. PaintPreviewWindow(lOffset);
  292. else if (m_cFormat == WiaImgFmt_TIFF) {
  293. if (lPercentComplete == 100) {
  294. OutputDebugString("----------------------------------> Paint a Page\n");
  295. }
  296. }
  297. }
  298. }
  299. break;
  300. case IT_MSG_STATUS:
  301. {
  302. if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE)
  303. {
  304. m_pMainFrm->SetProgressText(TEXT("Transfer from device"));
  305. m_pMainFrm->UpdateProgress(lPercentComplete);
  306. }
  307. else if (lStatus & IT_STATUS_PROCESSING_DATA)
  308. {
  309. m_pMainFrm->SetProgressText(TEXT("Processing Data"));
  310. m_pMainFrm->UpdateProgress(lPercentComplete);
  311. }
  312. else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT)
  313. {
  314. m_pMainFrm->SetProgressText(TEXT("Transfer to Client"));
  315. m_pMainFrm->UpdateProgress(lPercentComplete);
  316. }
  317. }
  318. break;
  319. case IT_MSG_NEW_PAGE:
  320. bMorePages = TRUE;
  321. PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER)pbBuffer;
  322. m_lPageCount = pHeader->lPageCount;
  323. sprintf(szDBG,"IT_MSG_NEW_PAGE, page count: %d\n", pHeader->lPageCount);
  324. OutputDebugString(szDBG);
  325. break;
  326. }
  327. return S_OK;
  328. }
  329. /**************************************************************************\
  330. * CWiaDataCallback::PaintPreviewWindow()
  331. *
  332. * Paint buffer to preview window
  333. *
  334. *
  335. * Arguments:
  336. *
  337. * lOffset - Data offset
  338. *
  339. * Return Value:
  340. *
  341. * void
  342. *
  343. * History:
  344. *
  345. * 2/14/1999 Original Version
  346. *
  347. \**************************************************************************/
  348. void CWiaDataCallback::PaintPreviewWindow(long lOffset)
  349. {
  350. if (m_hPreviewWnd != NULL) {
  351. HDC hdc = NULL;
  352. HDC hdcm = NULL;
  353. LPBITMAPINFO pbmi = NULL;
  354. LPBITMAPINFO pbmih = NULL;
  355. PBYTE pDib = NULL;
  356. HBITMAP hBitmap = NULL;
  357. BITMAP bm;
  358. hdc = GetDC(m_hPreviewWnd);
  359. if(hdc != NULL){
  360. hdcm = CreateCompatibleDC(hdc);
  361. if(hdcm != NULL){
  362. pbmi = (LPBITMAPINFO)m_pBuffer;
  363. if (pbmi != NULL) {
  364. hBitmap = CreateDIBSection(hdc,pbmi,DIB_RGB_COLORS,(void **)&pDib,NULL,0);
  365. if (hBitmap != NULL) {
  366. memset(pDib,255,pbmi->bmiHeader.biSizeImage); // white preview backgound..
  367. memcpy(pDib,m_pBuffer + sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * pbmi->bmiHeader.biClrUsed),lOffset);
  368. GetObject(hBitmap,sizeof(BITMAP),(LPSTR)&bm);
  369. SelectObject(hdcm,hBitmap);
  370. RECT ImageRect;
  371. RECT WindowRect;
  372. ImageRect.top = 0;
  373. ImageRect.left = 0;
  374. ImageRect.right = bm.bmWidth;
  375. ImageRect.bottom = bm.bmHeight;
  376. GetWindowRect(m_hPreviewWnd,&WindowRect);
  377. ScreenRectToClientRect(m_hPreviewWnd,&WindowRect);
  378. ScaleBitmapToDC(hdc,hdcm,&WindowRect,&ImageRect);
  379. DeleteObject(hBitmap);
  380. }
  381. }
  382. DeleteDC(hdcm);
  383. }
  384. DeleteDC(hdc);
  385. }
  386. }
  387. }
  388. /**************************************************************************\
  389. * CWiaDataCallback::ScreenRectToClientRect()
  390. *
  391. * Converts a RECT into Client coordinates
  392. *
  393. *
  394. * Arguments:
  395. *
  396. * hWnd - Client Window handle
  397. * pRect - converted LPRECT
  398. *
  399. * Return Value:
  400. *
  401. * void
  402. *
  403. * History:
  404. *
  405. * 2/14/1999 Original Version
  406. *
  407. \**************************************************************************/
  408. void CWiaDataCallback::ScreenRectToClientRect(HWND hWnd,LPRECT pRect)
  409. {
  410. POINT PtConvert;
  411. PtConvert.x = pRect->left;
  412. PtConvert.y = pRect->top;
  413. //
  414. // convert upper left point
  415. //
  416. ScreenToClient(hWnd,&PtConvert);
  417. pRect->left = PtConvert.x;
  418. pRect->top = PtConvert.y;
  419. PtConvert.x = pRect->right;
  420. PtConvert.y = pRect->bottom;
  421. //
  422. // convert lower right point
  423. //
  424. ScreenToClient(hWnd,&PtConvert);
  425. pRect->right = PtConvert.x;
  426. pRect->bottom = PtConvert.y;
  427. pRect->bottom-=1;
  428. pRect->left+=1;
  429. pRect->right-=1;
  430. pRect->top+=1;
  431. }
  432. /**************************************************************************\
  433. * CWiaDataCallback::ScaleBitmapToDC()
  434. *
  435. * Draws a BITMAP to the target DC
  436. *
  437. *
  438. * Arguments:
  439. *
  440. * hDC - Target DC
  441. * hDCM - Source DC
  442. * lpDCRect - DC window rect
  443. * lpDIBRect - DIB's rect
  444. *
  445. * Return Value:
  446. *
  447. * void
  448. *
  449. * History:
  450. *
  451. * 2/14/1999 Original Version
  452. *
  453. \**************************************************************************/
  454. void CWiaDataCallback::ScaleBitmapToDC(HDC hDC, HDC hDCM, LPRECT lpDCRect, LPRECT lpDIBRect)
  455. {
  456. // BitBlt(hDC,0,0,lpDIBRect->right,lpDIBRect->bottom,hDCM,0,0,SRCCOPY);
  457. float lWidthVal = 1;
  458. float lHeightVal = 1;
  459. // Make sure to use the stretching mode best for color pictures
  460. ::SetStretchBltMode(hDC, COLORONCOLOR);
  461. // Determine whether to call StretchDIBits() or SetDIBitsToDevice()
  462. BOOL bSuccess;
  463. if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) &&
  464. (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect)))
  465. bSuccess = ::BitBlt (hDC, // hDC
  466. lpDCRect->left, // DestX
  467. lpDCRect->top, // DestY
  468. RECTWIDTH(lpDCRect), // nDestWidth
  469. RECTHEIGHT(lpDCRect), // nDestHeight
  470. hDCM,
  471. 0,
  472. 0,
  473. SRCCOPY);
  474. else {
  475. //Window width becomes smaller than original image width
  476. if (RECTWIDTH(lpDIBRect) > lpDCRect->right - lpDCRect->left) {
  477. lWidthVal = (float)(lpDCRect->right - lpDCRect->left)/RECTWIDTH(lpDIBRect);
  478. }
  479. //Window height becomes smaller than original image height
  480. if (RECTHEIGHT(lpDIBRect) > lpDCRect->bottom - lpDCRect->top) {
  481. lHeightVal = (float)(lpDCRect->bottom - lpDCRect->top)/RECTHEIGHT(lpDIBRect);
  482. }
  483. long ScaledWidth = (int)(RECTWIDTH(lpDIBRect) * min(lWidthVal,lHeightVal));
  484. long ScaledHeight = (int)(RECTHEIGHT(lpDIBRect) * min(lWidthVal,lHeightVal));
  485. bSuccess = ::StretchBlt(hDC, // hDC
  486. lpDCRect->left, // DestX
  487. lpDCRect->top, // DestY
  488. ScaledWidth, // nDestWidth
  489. ScaledHeight, // nDestHeight
  490. hDCM,
  491. /*lpDIBRect->left*/0, // SrcX
  492. /*lpDIBRect->top*/0, // SrcY
  493. RECTWIDTH(lpDIBRect), // wSrcWidth
  494. RECTHEIGHT(lpDIBRect), // wSrcHeight
  495. SRCCOPY); // dwROP
  496. // update outline areas
  497. // Invalidated right side rect
  498. RECT WindowRect;
  499. WindowRect.top = lpDCRect->top;
  500. WindowRect.left = lpDCRect->left + ScaledWidth;
  501. WindowRect.right = lpDCRect->right;
  502. WindowRect.bottom = lpDCRect->bottom;
  503. HBRUSH hBrush = CreateSolidBrush(GetBkColor(hDC));
  504. FillRect(hDC,&WindowRect,hBrush);
  505. // Invalidated bottom rect
  506. WindowRect.top = lpDCRect->top + ScaledHeight;
  507. WindowRect.left = lpDCRect->left;
  508. WindowRect.right = lpDCRect->left + ScaledWidth;
  509. WindowRect.bottom = lpDCRect->bottom;
  510. FillRect(hDC,&WindowRect,hBrush);
  511. DeleteObject(hBrush);
  512. }
  513. }
  514. /**************************************************************************\
  515. * CWiaDataCallback::GetDataPtr()
  516. *
  517. * Returns the memory acquired during a transfer
  518. *
  519. *
  520. * Arguments:
  521. *
  522. * none
  523. *
  524. * Return Value:
  525. *
  526. * BYTE* pBuffer - memory block
  527. *
  528. * History:
  529. *
  530. * 2/14/1999 Original Version
  531. *
  532. \**************************************************************************/
  533. // GetDataPtr
  534. BYTE* _stdcall CWiaDataCallback::GetDataPtr()
  535. {
  536. return m_pBuffer;
  537. }