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.
338 lines
11 KiB
338 lines
11 KiB
#include "precomp.h"
|
|
|
|
//
|
|
// WIA data callback implementation
|
|
//
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CWiaDataCallback::AddRef()
|
|
{
|
|
InterlockedIncrement((LONG*)&m_Ref);
|
|
return m_Ref;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CWiaDataCallback::Release()
|
|
{
|
|
if (!InterlockedDecrement((LONG*)&m_Ref)) {
|
|
m_Ref++;
|
|
delete this;
|
|
return(ULONG) 0;
|
|
}
|
|
return m_Ref;
|
|
}
|
|
|
|
STDMETHODIMP CWiaDataCallback::QueryInterface(REFIID iid, void **ppv)
|
|
{
|
|
if (!ppv)
|
|
return E_INVALIDARG;
|
|
*ppv = NULL;
|
|
if (IID_IUnknown == iid) {
|
|
*ppv = (IUnknown*)this;
|
|
AddRef();
|
|
return S_OK;
|
|
} else if (IID_IWiaDataCallback == iid) {
|
|
*ppv = (IWiaDataCallback *)this;
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
HRESULT CWiaDataCallback::Initialize(HWND hWndOwner,BOOL bShowProgress)
|
|
{
|
|
m_hwndOwner = hWndOwner;
|
|
if (bShowProgress) {
|
|
if (NULL == m_pProgDlg) {
|
|
m_pProgDlg = new CProgressDlg();
|
|
if (!m_pProgDlg) {
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
m_pProgDlg->Initialize(g_hInstance, IDD_PROGRESSDLG);
|
|
}
|
|
//
|
|
// Preload progress title strings
|
|
//
|
|
m_pszXferFromDevice = LoadResourceString(IDS_PROGRESS_XFER_FROM_DEVICE);
|
|
m_pszProcessingData = LoadResourceString(IDS_PROGRESS_PROCESSING_DATA);
|
|
m_pszXferToClient = LoadResourceString(IDS_PROGRESS_XFER_TO_CLIENT);
|
|
m_bSetTitle = FALSE;
|
|
if (!m_pszXferFromDevice || !m_pszProcessingData || !m_pszXferToClient) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
if (m_pProgDlg->DoModeless(m_hwndOwner, (LPARAM)m_pProgDlg)) {
|
|
m_pProgDlg->SetRange(0, 100);
|
|
m_pProgDlg->SetPos(0);
|
|
m_lCurrentTextUpdate = TITLE_TRANSFERTOCLIENT;
|
|
m_pProgDlg->SetTitle(m_pszXferToClient);
|
|
} else {
|
|
DBG_ERR(("DoModeless Failed to create Progress Dialog"));
|
|
}
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
#define WIADSMSG_PROGRESS MSG_USER + 0
|
|
|
|
STDMETHODIMP CWiaDataCallback::BandedDataCallback(LONG lMessage,LONG lStatus,LONG lPercentComplete,
|
|
LONG lOffset,LONG Length,LONG lReserved,
|
|
LONG lResLength,BYTE *pData)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (lMessage) {
|
|
case IT_MSG_FILE_PREVIEW_DATA_HEADER: // we do nothing with file preview header data
|
|
break;
|
|
case IT_MSG_DATA_HEADER:
|
|
{
|
|
PWIA_DATA_CALLBACK_HEADER pHeader = NULL;
|
|
pHeader = (PWIA_DATA_CALLBACK_HEADER)pData;
|
|
if(pHeader->guidFormatID == WiaImgFmt_MEMORYBMP){
|
|
DBG_TRC(("pHeader->guidFormatID = WiaImgFmt_MEMORYBMP"));
|
|
m_bBitmapData = TRUE;
|
|
} else if(pHeader->guidFormatID == WiaImgFmt_MEMORYBMP){
|
|
DBG_TRC(("pHeader->guidFormatID = WiaImgFmt_RAWRGB"));
|
|
m_bBitmapData = FALSE;
|
|
} else {
|
|
DBG_TRC(("pHeader->guidFormatID = (unknown)"));
|
|
m_bBitmapData = TRUE;
|
|
}
|
|
|
|
m_MemBlockSize = pHeader->lBufferSize;
|
|
DBG_TRC(("CWiaDataCallback::BandedDataCallback(), IT_MSG_DATA_HEADER Reports"));
|
|
DBG_TRC(("pHeader->lBufferSize = %d",pHeader->lBufferSize));
|
|
DBG_TRC(("pHeader->lPageCount = %d",pHeader->lPageCount));
|
|
DBG_TRC(("pHeader->lSize = %d",pHeader->lSize));
|
|
|
|
//
|
|
// if we get a lbuffer size of zero, allocate one for us,
|
|
// and maintain the size.
|
|
//
|
|
|
|
DBG_TRC(("MemBlockSize = %d",pHeader->lBufferSize));
|
|
if(m_MemBlockSize <= 0){
|
|
m_MemBlockSize = (520288 * 2);
|
|
DBG_WRN(("CWiaDataCallback::BandedDataCallback(), adjusting MemBlockSize to %d",m_MemBlockSize));
|
|
}
|
|
|
|
if (m_hImage) {
|
|
GlobalFree(m_hImage);
|
|
m_hImage = NULL;
|
|
m_pImage = NULL;
|
|
m_ImageSize = 0;
|
|
m_SizeTransferred = 0;
|
|
}
|
|
|
|
m_SizeTransferred = 0;
|
|
|
|
//
|
|
// allocate the buffer
|
|
//
|
|
|
|
m_hImage = (HGLOBAL)GlobalAlloc(GHND, m_MemBlockSize);
|
|
hr = E_OUTOFMEMORY;
|
|
if (m_hImage) {
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
}
|
|
case IT_MSG_FILE_PREVIEW_DATA: // we do nothing with file preview data
|
|
break;
|
|
case IT_MSG_DATA:
|
|
{
|
|
m_SizeTransferred += Length;
|
|
if((LONG)m_SizeTransferred >= m_MemBlockSize){
|
|
m_MemBlockSize += (Length * MEMORY_BLOCK_FACTOR);
|
|
|
|
//
|
|
// process allocation into a temp handle, and fail, if allocation
|
|
// fails.
|
|
//
|
|
|
|
HGLOBAL hTempMemory = (HGLOBAL)GlobalReAlloc(m_hImage,m_MemBlockSize,LMEM_MOVEABLE);
|
|
if(hTempMemory){
|
|
m_hImage = hTempMemory;
|
|
} else {
|
|
if(m_hImage){
|
|
GlobalFree(m_hImage);
|
|
m_hImage = NULL;
|
|
}
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
//
|
|
// lock memory down
|
|
//
|
|
|
|
m_pImage = (BYTE*)GlobalLock(m_hImage);
|
|
if (m_pImage) {
|
|
DBG_TRC(("Copying %d into m_pImage (m_hImage = 0x%X, m_pImage = 0x%X) buffer",Length,m_hImage,m_pImage));
|
|
memcpy(m_pImage + lOffset, pData, Length);
|
|
|
|
//
|
|
// unlock memory
|
|
//
|
|
|
|
GlobalUnlock(m_hImage);
|
|
} else {
|
|
DBG_ERR(("Could not lock down m_hImage memory block"));
|
|
}
|
|
|
|
/*
|
|
if (Length == 40) {
|
|
BITMAPINFOHEADER* pbmi = NULL;
|
|
pbmi = (BITMAPINFOHEADER*)pData;
|
|
DBG_TRC(("CWiaDataCallback::BandedDataCallback(), Reported BITMAPINFOHEADER from IT_MSG_DATA"));
|
|
DBG_TRC(("pbmi->biSize = %d",pbmi->biSize));
|
|
DBG_TRC(("pbmi->biSizeImage = %d",pbmi->biSizeImage));
|
|
DBG_TRC(("pbmi->biBitCount = %d",pbmi->biBitCount));
|
|
DBG_TRC(("pbmi->biClrImportant = %d",pbmi->biClrImportant));
|
|
DBG_TRC(("pbmi->biClrUsed = %d",pbmi->biClrUsed));
|
|
DBG_TRC(("pbmi->biCompression = %d",pbmi->biCompression));
|
|
DBG_TRC(("pbmi->biHeight = %d",pbmi->biHeight));
|
|
DBG_TRC(("pbmi->biWidth = %d",pbmi->biWidth));
|
|
DBG_TRC(("pbmi->biPlanes = %d",pbmi->biPlanes));
|
|
DBG_TRC(("pbmi->biXPelsPerMeter = %d",pbmi->biXPelsPerMeter));
|
|
DBG_TRC(("pbmi->biYPelsPerMeter = %d",pbmi->biYPelsPerMeter));
|
|
}
|
|
*/
|
|
|
|
if (m_pProgDlg) {
|
|
m_lCurrentTextUpdate = TITLE_TRANSFERTOCLIENT;
|
|
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
|
|
m_lLastTextUpdate = m_lCurrentTextUpdate;
|
|
m_pProgDlg->SetTitle(m_pszXferToClient);
|
|
}
|
|
m_pProgDlg->SetPos(lPercentComplete);
|
|
}
|
|
}
|
|
break;
|
|
case IT_MSG_STATUS:
|
|
if (m_pProgDlg) {
|
|
if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE) {
|
|
m_lCurrentTextUpdate = TITLE_FROMDEVICE;
|
|
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
|
|
m_lLastTextUpdate = m_lCurrentTextUpdate;
|
|
m_pProgDlg->SetTitle(m_pszXferFromDevice);
|
|
}
|
|
} else if (lStatus & IT_STATUS_PROCESSING_DATA) {
|
|
m_lCurrentTextUpdate = TITLE_PROCESSINGDATA;
|
|
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
|
|
m_lLastTextUpdate = m_lCurrentTextUpdate;
|
|
m_pProgDlg->SetTitle(m_pszProcessingData);
|
|
}
|
|
} else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT) {
|
|
m_lCurrentTextUpdate = TITLE_TRANSFERTOCLIENT;
|
|
if(m_lLastTextUpdate != m_lCurrentTextUpdate){
|
|
m_lLastTextUpdate = m_lCurrentTextUpdate;
|
|
m_pProgDlg->SetTitle(m_pszXferToClient);
|
|
}
|
|
}
|
|
m_pProgDlg->SetPos(lPercentComplete);
|
|
}
|
|
break;
|
|
case IT_MSG_TERMINATION:
|
|
|
|
if (m_pProgDlg) {
|
|
delete m_pProgDlg;
|
|
m_pProgDlg = NULL;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//
|
|
// check for user cancel operation
|
|
//
|
|
|
|
if (m_pProgDlg && m_pProgDlg->CheckCancelled()) {
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
//
|
|
// transfer failed, or user pressed cancel
|
|
//
|
|
|
|
if (FAILED(hr) || S_FALSE == hr) {
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaDataCallback::BandedDataCallback(), The transfer failed"));
|
|
} else {
|
|
DBG_WRN(("CWiaDataCallback::BandedDataCallback(), The user pressed cancel"));
|
|
}
|
|
|
|
if (m_pProgDlg) {
|
|
delete m_pProgDlg;
|
|
m_pProgDlg = NULL;
|
|
}
|
|
}
|
|
|
|
//
|
|
// save last hr
|
|
//
|
|
|
|
m_hrLast = hr;
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWiaDataCallback::GetImage(HGLOBAL *phImage,ULONG *pImageSize)
|
|
{
|
|
if (!phImage)
|
|
return E_INVALIDARG;
|
|
|
|
if (pImageSize)
|
|
*pImageSize = 0;
|
|
*phImage = NULL;
|
|
|
|
if (SUCCEEDED(m_hrLast)) {
|
|
if (m_bBitmapData) {
|
|
|
|
//
|
|
// we need to adjust any headers, because the height and image size information
|
|
// could be incorrect. (this will handle infinite page length devices)
|
|
//
|
|
|
|
BITMAPINFOHEADER *pbmh = NULL;
|
|
pbmh = (BITMAPINFOHEADER*)GlobalLock(m_hImage);
|
|
if (pbmh) {
|
|
// only fix the BITMAPINFOHEADER if height needs to be calculated
|
|
if (pbmh->biHeight == 0) {
|
|
LONG lPaletteSize = pbmh->biClrUsed * sizeof(RGBQUAD);
|
|
LONG lWidthBytes = CalculateWidthBytes(pbmh->biWidth,pbmh->biBitCount);
|
|
pbmh->biSizeImage = m_SizeTransferred - lPaletteSize - sizeof(BITMAPINFOHEADER);
|
|
pbmh->biHeight = -(LONG)(pbmh->biSizeImage/lWidthBytes); // 0 also means upside down
|
|
pbmh->biXPelsPerMeter = 0; // zero out
|
|
pbmh->biYPelsPerMeter = 0; // zero out
|
|
}
|
|
m_lImageHeight = abs(pbmh->biHeight);
|
|
m_lImageWidth = abs(pbmh->biWidth);
|
|
GlobalUnlock(m_hImage);
|
|
}
|
|
}
|
|
|
|
if (pImageSize){
|
|
*pImageSize = m_SizeTransferred;
|
|
}
|
|
|
|
*phImage = m_hImage;
|
|
|
|
//
|
|
// reset internal variables, for next data transfer
|
|
//
|
|
|
|
m_hImage = NULL;
|
|
m_pImage = NULL;
|
|
m_SizeTransferred = 0;
|
|
DBG_TRC(("CWiaDataCallback::GetImage(), Returned 0x%X (HANDLE pointer)",*phImage));
|
|
}
|
|
return m_hrLast;
|
|
}
|
|
|
|
LONG CWiaDataCallback::CalculateWidthBytes(LONG lWidthPixels,LONG lbpp)
|
|
{
|
|
LONG lWidthBytes = 0;
|
|
lWidthBytes = (lWidthPixels * lbpp) + 31;
|
|
lWidthBytes = ((lWidthBytes/8) & 0xfffffffc);
|
|
return lWidthBytes;
|
|
}
|