|
|
// DataCallback.cpp: implementation of the CDataCallback class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "WIATest.h"
#include "DataCallback.h"
#define IT_MSG_DATA_HEADER 0x0001
#define IT_MSG_DATA 0x0002
#define IT_MSG_STATUS 0x0003
#define IT_MSG_TERMINATION 0x0004
// #define _DEBUGCALLBACK
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW
#endif
/**************************************************************************\
* CWiaDataCallback::QueryInterface() * * QI for IWiadataCallback Interface * * * Arguments: * * iid - Interface ID * ppv - Callback Interface pointer * * Return Value: * * none * * History: * * 2/14/1999 Original Version * \**************************************************************************/ HRESULT _stdcall CWiaDataCallback::QueryInterface(const IID& iid, void** ppv) { *ppv = NULL; if (iid == IID_IUnknown || iid == IID_IWiaDataCallback) *ppv = (IWiaDataCallback*) this; else return E_NOINTERFACE; AddRef(); return S_OK; }
/**************************************************************************\
* CWiaDataCallback::AddRef() * * Increment the Ref count * * * Arguments: * * none * * Return Value: * * ULONG - current ref count * * History: * * 2/14/1999 Original Version * \**************************************************************************/ ULONG _stdcall CWiaDataCallback::AddRef() { InterlockedIncrement((long*) &m_cRef); return m_cRef; }
/**************************************************************************\
* CWiaDataCallback::Release() * * Release the callback Interface * * * Arguments: * * none * * Return Value: * * ULONG - Current Ref count * * History: * * 2/14/1999 Original Version * \**************************************************************************/ ULONG _stdcall CWiaDataCallback::Release() { ULONG ulRefCount = m_cRef - 1; if (InterlockedDecrement((long*) &m_cRef) == 0) { delete this; return 0; } return ulRefCount; }
/**************************************************************************\
* CWiaDataCallback::CWiaDataCallback() * * Constructor for callback class * * * Arguments: * * none * * Return Value: * * none * * History: * * 2/14/1999 Original Version * \**************************************************************************/ CWiaDataCallback::CWiaDataCallback() { m_cRef = 0; m_pBuffer = NULL; m_BytesTransfered = 0; m_hPreviewWnd = NULL; }
/**************************************************************************\
* CWiaDataCallback::~CWiaDataCallback() * * Destructor for Callback class * * * Arguments: * * none * * Return Value: * * none * * History: * * 2/14/1999 Original Version * \**************************************************************************/ CWiaDataCallback::~CWiaDataCallback() { if (m_pBuffer != NULL) { LocalFree(m_pBuffer); m_pBuffer = NULL; } // destroy progress dlg
m_pMainFrm->SetProgressText(TEXT("Ready")); m_pMainFrm->UpdateProgress(50); m_pMainFrm->DestroyProgressCtrl(); }
/**************************************************************************\
* CWiaDataCallback::Initialize() * * Initializes Progress control. * * * Arguments: * * none * * Return Value: * * none * * History: * * 2/14/1999 Original Version * \**************************************************************************/ HRESULT _stdcall CWiaDataCallback::Initialize(HWND hPreviewWnd) { CWIATestApp* pApp = (CWIATestApp*)AfxGetApp(); m_pMainFrm = (CMainFrame*)pApp->GetMainWnd();
if (m_pMainFrm != NULL) { m_pMainFrm->InitializeProgressCtrl("Starting Transfer"); }
m_hPreviewWnd = hPreviewWnd; m_lPageCount = 0; return S_OK; }
/**************************************************************************\
* CWiaDataCallback::BandedDataCallback() * * Callback member which handles Banded Data transfers * * * Arguments: * * lMessage - callback message * lStatus - additional message information * lPercentComplete - current percent complete status * lOffset - amount of data offset (bytes) * lLength - amount of data read (bytes) * lReserved - not used * lResLength - not used * pbBuffer - Data header information * * Return Value: * * status * * History: * * 2/14/1999 Original Version * \**************************************************************************/ HRESULT _stdcall CWiaDataCallback::BandedDataCallback( LONG lMessage, LONG lStatus, LONG lPercentComplete, LONG lOffset, LONG lLength, LONG lReserved, LONG lResLength, BYTE* pbBuffer) {
char szDBG[MAX_PATH]; static BOOL bMorePages = FALSE; switch (lMessage) { case IT_MSG_DATA_HEADER: { PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER)pbBuffer; m_MemBlockSize = pHeader->lBufferSize;
//
// If the Buffer is 0, then alloc a 64k chunk (default)
//
if(m_MemBlockSize <= 0) m_MemBlockSize = 65535;
m_pBuffer = (PBYTE)LocalAlloc(LPTR,m_MemBlockSize); m_BytesTransfered = 0; m_cFormat = pHeader->guidFormatID;
#ifdef _DEBUGCALLBACK
sprintf(szDBG,"Reading Header information\n"); OutputDebugString(szDBG); sprintf(szDBG,"Header info:\n"); OutputDebugString(szDBG); sprintf(szDBG," lBufferSize = %li\n",pHeader->lBufferSize); OutputDebugString(szDBG); sprintf(szDBG," lFormat = %li\n",pHeader->lFormat); OutputDebugString(szDBG); sprintf(szDBG," BytesTransferred = %li\n",m_BytesTransfered); OutputDebugString(szDBG);
#endif
} break;
case IT_MSG_DATA: {
if (m_pBuffer != NULL) { if(bMorePages/*m_cFormat == CF_MULTI_TIFF*/){
//
// Display current page count + 1, because Page count is zero based.
//
sprintf(szDBG,"Page(%d) %d%% Complete..",(m_lPageCount + 1), lPercentComplete); } else sprintf(szDBG,"%d%% Complete..",lPercentComplete); m_pMainFrm->SetProgressText(szDBG); m_pMainFrm->UpdateProgress(lPercentComplete);
m_BytesTransfered += lLength; if(m_BytesTransfered >= m_MemBlockSize){
//
// Alloc more memory for transfer buffer
//
m_MemBlockSize += (lLength * 2); m_pBuffer = (PBYTE)LocalReAlloc(m_pBuffer,m_MemBlockSize,LMEM_MOVEABLE); }
#ifdef _DEBUGCALLBACK
sprintf(szDBG," Memory BLOCK size = %li\n",m_MemBlockSize); OutputDebugString(szDBG); sprintf(szDBG," writing %li\n",lLength); OutputDebugString(szDBG); sprintf(szDBG," lOffset = %li, lLength = %li, BytesTransferred = %li\n",lOffset,lLength,m_BytesTransfered); OutputDebugString(szDBG);
#endif
memcpy(m_pBuffer + lOffset, pbBuffer, lLength);
//
// Paint preview window during callback
//
// WiaImgFmt_UNDEFINED
// ???? m_cFormat == WiaImgFmt_BMP)
if(m_cFormat == WiaImgFmt_MEMORYBMP) PaintPreviewWindow(lOffset); else if (m_cFormat == WiaImgFmt_TIFF) { if (lPercentComplete == 100) { OutputDebugString("----------------------------------> Paint a Page\n"); } } } } break;
case IT_MSG_STATUS: { if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE) { m_pMainFrm->SetProgressText(TEXT("Transfer from device")); m_pMainFrm->UpdateProgress(lPercentComplete);
} else if (lStatus & IT_STATUS_PROCESSING_DATA) { m_pMainFrm->SetProgressText(TEXT("Processing Data")); m_pMainFrm->UpdateProgress(lPercentComplete);
} else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT) { m_pMainFrm->SetProgressText(TEXT("Transfer to Client")); m_pMainFrm->UpdateProgress(lPercentComplete); } } break;
case IT_MSG_NEW_PAGE: bMorePages = TRUE; PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER)pbBuffer; m_lPageCount = pHeader->lPageCount; sprintf(szDBG,"IT_MSG_NEW_PAGE, page count: %d\n", pHeader->lPageCount); OutputDebugString(szDBG); break; } return S_OK; }
/**************************************************************************\
* CWiaDataCallback::PaintPreviewWindow() * * Paint buffer to preview window * * * Arguments: * * lOffset - Data offset * * Return Value: * * void * * History: * * 2/14/1999 Original Version * \**************************************************************************/ void CWiaDataCallback::PaintPreviewWindow(long lOffset) { if (m_hPreviewWnd != NULL) {
HDC hdc = NULL; HDC hdcm = NULL; LPBITMAPINFO pbmi = NULL; LPBITMAPINFO pbmih = NULL; PBYTE pDib = NULL; HBITMAP hBitmap = NULL; BITMAP bm;
hdc = GetDC(m_hPreviewWnd); if(hdc != NULL){ hdcm = CreateCompatibleDC(hdc); if(hdcm != NULL){ pbmi = (LPBITMAPINFO)m_pBuffer; if (pbmi != NULL) { hBitmap = CreateDIBSection(hdc,pbmi,DIB_RGB_COLORS,(void **)&pDib,NULL,0);
if (hBitmap != NULL) { memset(pDib,255,pbmi->bmiHeader.biSizeImage); // white preview backgound..
memcpy(pDib,m_pBuffer + sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * pbmi->bmiHeader.biClrUsed),lOffset);
GetObject(hBitmap,sizeof(BITMAP),(LPSTR)&bm); SelectObject(hdcm,hBitmap);
RECT ImageRect; RECT WindowRect;
ImageRect.top = 0; ImageRect.left = 0; ImageRect.right = bm.bmWidth; ImageRect.bottom = bm.bmHeight;
GetWindowRect(m_hPreviewWnd,&WindowRect); ScreenRectToClientRect(m_hPreviewWnd,&WindowRect); ScaleBitmapToDC(hdc,hdcm,&WindowRect,&ImageRect);
DeleteObject(hBitmap); } } DeleteDC(hdcm); } DeleteDC(hdc); } } } /**************************************************************************\
* CWiaDataCallback::ScreenRectToClientRect() * * Converts a RECT into Client coordinates * * * Arguments: * * hWnd - Client Window handle * pRect - converted LPRECT * * Return Value: * * void * * History: * * 2/14/1999 Original Version * \**************************************************************************/ void CWiaDataCallback::ScreenRectToClientRect(HWND hWnd,LPRECT pRect) { POINT PtConvert;
PtConvert.x = pRect->left; PtConvert.y = pRect->top;
//
// convert upper left point
//
ScreenToClient(hWnd,&PtConvert);
pRect->left = PtConvert.x; pRect->top = PtConvert.y;
PtConvert.x = pRect->right; PtConvert.y = pRect->bottom;
//
// convert lower right point
//
ScreenToClient(hWnd,&PtConvert);
pRect->right = PtConvert.x; pRect->bottom = PtConvert.y;
pRect->bottom-=1; pRect->left+=1; pRect->right-=1; pRect->top+=1; }
/**************************************************************************\
* CWiaDataCallback::ScaleBitmapToDC() * * Draws a BITMAP to the target DC * * * Arguments: * * hDC - Target DC * hDCM - Source DC * lpDCRect - DC window rect * lpDIBRect - DIB's rect * * Return Value: * * void * * History: * * 2/14/1999 Original Version * \**************************************************************************/ void CWiaDataCallback::ScaleBitmapToDC(HDC hDC, HDC hDCM, LPRECT lpDCRect, LPRECT lpDIBRect) { // BitBlt(hDC,0,0,lpDIBRect->right,lpDIBRect->bottom,hDCM,0,0,SRCCOPY);
float lWidthVal = 1; float lHeightVal = 1;
// Make sure to use the stretching mode best for color pictures
::SetStretchBltMode(hDC, COLORONCOLOR);
// Determine whether to call StretchDIBits() or SetDIBitsToDevice()
BOOL bSuccess; if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) bSuccess = ::BitBlt (hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
hDCM, 0, 0, SRCCOPY); else { //Window width becomes smaller than original image width
if (RECTWIDTH(lpDIBRect) > lpDCRect->right - lpDCRect->left) { lWidthVal = (float)(lpDCRect->right - lpDCRect->left)/RECTWIDTH(lpDIBRect); } //Window height becomes smaller than original image height
if (RECTHEIGHT(lpDIBRect) > lpDCRect->bottom - lpDCRect->top) { lHeightVal = (float)(lpDCRect->bottom - lpDCRect->top)/RECTHEIGHT(lpDIBRect); } long ScaledWidth = (int)(RECTWIDTH(lpDIBRect) * min(lWidthVal,lHeightVal)); long ScaledHeight = (int)(RECTHEIGHT(lpDIBRect) * min(lWidthVal,lHeightVal)); bSuccess = ::StretchBlt(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
ScaledWidth, // nDestWidth
ScaledHeight, // nDestHeight
hDCM, /*lpDIBRect->left*/0, // SrcX
/*lpDIBRect->top*/0, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
SRCCOPY); // dwROP
// update outline areas
// Invalidated right side rect
RECT WindowRect; WindowRect.top = lpDCRect->top; WindowRect.left = lpDCRect->left + ScaledWidth; WindowRect.right = lpDCRect->right; WindowRect.bottom = lpDCRect->bottom;
HBRUSH hBrush = CreateSolidBrush(GetBkColor(hDC)); FillRect(hDC,&WindowRect,hBrush);
// Invalidated bottom rect
WindowRect.top = lpDCRect->top + ScaledHeight; WindowRect.left = lpDCRect->left; WindowRect.right = lpDCRect->left + ScaledWidth; WindowRect.bottom = lpDCRect->bottom;
FillRect(hDC,&WindowRect,hBrush); DeleteObject(hBrush); } }
/**************************************************************************\
* CWiaDataCallback::GetDataPtr() * * Returns the memory acquired during a transfer * * * Arguments: * * none * * Return Value: * * BYTE* pBuffer - memory block * * History: * * 2/14/1999 Original Version * \**************************************************************************/ // GetDataPtr
BYTE* _stdcall CWiaDataCallback::GetDataPtr() { return m_pBuffer; }
|