windows-nt/Source/XPSP1/NT/printscan/wia/test/msqscan/cwia.cpp
2020-09-26 16:20:57 +08:00

1293 lines
34 KiB
C++

// CWIA.cpp : implementation file
//
#include "stdafx.h"
#include "CWIA.h"
extern IGlobalInterfaceTable *g_pGIT;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CWIA::CWIA(DATA_ACQUIRE_INFO* pThreadDataInfo, IWiaItem *pRootItem)
{
m_bFinishedAcquire = FALSE;
m_pIWiaRootItem = NULL;
m_pIWiaFirstChildItem = NULL;
if(pRootItem != NULL)
m_pIWiaRootItem = pRootItem;
}
CWIA::~CWIA()
{
}
VOID CWIA::CleanUp()
{
if(m_pIWiaRootItem != NULL)
m_pIWiaRootItem->Release();
if(m_pIWiaFirstChildItem != NULL)
m_pIWiaFirstChildItem->Release();
}
VOID CWIA::SetRootItem(IWiaItem *pRootItem)
{
m_pIWiaRootItem = pRootItem;
SetFirstChild();
}
BOOL CWIA::IsAcquireComplete()
{
return m_bFinishedAcquire;
}
HRESULT CWIA::EnumerateSupportedFormats(IWiaItem *pIWiaItem, WIA_FORMAT_INFO **ppSupportedFormats, ULONG *pulCount)
{
HRESULT hr = E_FAIL;
*pulCount = 0;
IWiaDataTransfer *pIWiaDataTransfer = NULL;
IWiaItem *pTargetItem = pIWiaItem;
if(pTargetItem == NULL) {
//
// use first child of root
//
pTargetItem = m_pIWiaFirstChildItem;
}
if(pTargetItem != NULL) {
hr = pTargetItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIWiaDataTransfer);
if (SUCCEEDED(hr)) {
IEnumWIA_FORMAT_INFO *pIEnumWIA_FORMAT_INFO;
hr = pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO(&pIEnumWIA_FORMAT_INFO);
if (SUCCEEDED(hr)) {
hr = pIEnumWIA_FORMAT_INFO->Reset();
if(SUCCEEDED(hr)) {
hr = pIEnumWIA_FORMAT_INFO->GetCount(pulCount);
if(SUCCEEDED(hr)) {
//
// caller of this routine must free the allocated memory
//
*ppSupportedFormats = (WIA_FORMAT_INFO*)GlobalAlloc(GPTR,(sizeof(WIA_FORMAT_INFO) * (*pulCount)));
if(*ppSupportedFormats != NULL) {
hr = pIEnumWIA_FORMAT_INFO->Next(*pulCount, *ppSupportedFormats, pulCount);
if(hr != S_OK) {
//
// if this failed, write error to Last error buffer,
// and let the procedure wind out
//
//
// free allocated memory, because we failed
//
GlobalFree(*ppSupportedFormats);
//
// set pointer to NULL, to clean the exit path for
// application
//
*ppSupportedFormats = NULL;
SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIEnumWIA_FORMAT_INFO->Next() failed"));
}
} else {
SaveErrorText(TEXT("EnumerateSupportedFileTypes, out of memory"));
}
} else {
SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIEnumWIA_FORMAT_INFO->GetCount() failed"));
}
} else {
SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIEnumWIA_FORMAT_INFO->Reset() failed"));
}
//
// Release supported format enumerator interface
//
pIEnumWIA_FORMAT_INFO->Release();
} else {
SaveErrorText(TEXT("EnumerateSupportedFileTypes, pIWiaDataTransfer->idtEnumWIA_FORMAT_INFO() failed"));
}
//
// Release data transfer interface
//
pIWiaDataTransfer->Release();
} else {
SaveErrorText(TEXT("EnumerateSupportedFileTypes, QI for IWiaDataTransfer failed"));
}
}
return hr;
}
BOOL CWIA::SetFirstChild()
{
HRESULT hr = E_FAIL;
BOOL bSuccess = FALSE;
IEnumWiaItem* pIEnumWiaItem = NULL;
IWiaItem *pIWiaItem = NULL;
hr = m_pIWiaRootItem->EnumChildItems(&pIEnumWiaItem);
if(SUCCEEDED(hr)) {
//
// get first child item
//
hr = pIEnumWiaItem->Next(1,&pIWiaItem,NULL);
if(hr == S_OK) {
//
// item was retrieved, so now assign you first child member
//
m_pIWiaFirstChildItem = pIWiaItem;
//
// assign success flag
//
bSuccess = TRUE;
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("SetFirstChild, pIEnumWiaItem->Next failed"));
m_hrLastError = hr;
}
//
// release Item enumerator
//
pIEnumWiaItem->Release();
}
return bSuccess;
}
IWiaItem* CWIA::GetFirstChild()
{
return m_pIWiaFirstChildItem;
}
IWiaItem* CWIA::GetRootItem()
{
return m_pIWiaRootItem;
}
LONG CWIA::GetRootItemType(IWiaItem *pRootItem)
{
IWiaItem *pTargetRootItem = NULL;
//
// start with the requested RootItem first
//
pTargetRootItem = pRootItem;
if(pTargetRootItem == NULL) {
//
// the requested root item is NULL, so try our
// internal root item (m_pIWiaRootItem)
//
pTargetRootItem = m_pIWiaRootItem;
}
//
// get Root item's type (ie. device type)
//
LONG lVal = -888;
if (pTargetRootItem != NULL) {
//
// get an IWiaPropertyStorage Interface
//
IWiaPropertyStorage *pIWiaPropStg;
HRESULT hr = S_OK;
hr = pTargetRootItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
if (SUCCEEDED(hr)) {
//
// read Root Item's Type
//
hr = ReadPropLong(WIA_DIP_DEV_TYPE, pIWiaPropStg, &lVal);
if(SUCCEEDED(hr)) {
//
// release the IWiaPropertyStorage Interface
//
pIWiaPropStg->Release();
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("GetRootItemType, ReadPropLong(WIA_DIP_DEV_TYPE) failed"));
m_hrLastError = hr;
}
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("GetRootItemType, ReadPropLong(WIA_DIP_DEV_TYPE) failed"));
m_hrLastError = hr;
}
}
return(GET_STIDEVICE_TYPE(lVal));
}
//
// ERROR PROCESSING
//
VOID CWIA::SaveErrorText(TCHAR *pszText)
{
lstrcpy(m_szErrorText,pszText);
}
HRESULT CWIA::GetLastWIAError(TCHAR *pszErrorText)
{
if(pszErrorText != NULL)
lstrcpy(pszErrorText, m_szErrorText);
return m_hrLastError;
}
//
// PROPERTY ACCESS HELPERS
//
HRESULT CWIA::WritePropLong(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, LONG lVal)
{
HRESULT hr = E_FAIL;
PROPSPEC propspec[1];
PROPVARIANT propvar[1];
propspec[0].ulKind = PRSPEC_PROPID;
propspec[0].propid = propid;
propvar[0].vt = VT_I4;
propvar[0].lVal = lVal;
hr = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
return hr;
}
HRESULT CWIA::ReadPropLong(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, LONG *plval)
{
HRESULT hr = E_FAIL;
PROPSPEC PropSpec[1];
PROPVARIANT PropVar[1];
UINT cbSize = 0;
memset(PropVar, 0, sizeof(PropVar));
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
hr = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
if (SUCCEEDED(hr)) {
*plval = PropVar[0].lVal;
}
return hr;
}
HRESULT CWIA::ReadRangeLong(IWiaItem *pIWiaItem, PROPID propid, ULONG ulFlag, LONG *plVal)
{
HRESULT hr = E_FAIL;
IWiaItem *pTargetItem = NULL;
PROPSPEC PropSpec[1];
PROPVARIANT AttrPropVar;
ULONG ulAccessFlags = 0;
//
// create a propspec
//
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
pTargetItem = pIWiaItem;
if(pTargetItem == NULL) {
//
// use first child of root
//
pTargetItem = m_pIWiaFirstChildItem;
}
if(pTargetItem != NULL) {
//
// get an IWiaPropertyStorage Interface
//
IWiaPropertyStorage *pIWiaPropStg;
hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
if (SUCCEEDED(hr)) {
//
// get property's attributes
//
hr = pIWiaPropStg->GetPropertyAttributes(1, PropSpec, &ulAccessFlags, &AttrPropVar);
if(SUCCEEDED(hr)) {
*plVal = (LONG)AttrPropVar.caul.pElems[ulFlag];
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadRangeLong, GetPropertyAttributes() failed"));
m_hrLastError = hr;
}
//
// release the IWiaPropertyStorage Interface
//
pIWiaPropStg->Release();
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadRangeLong, QI for IWiaProperyStorage failed"));
m_hrLastError = hr;
}
}
return hr;
}
HRESULT CWIA::ReadLong(IWiaItem *pIWiaItem, PROPID propid, LONG *plVal)
{
HRESULT hr = E_FAIL;
IWiaItem *pTargetItem = NULL;
PROPSPEC PropSpec[1];
//
// create a propspec
//
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
pTargetItem = pIWiaItem;
if(pTargetItem == NULL) {
//
// use first child of root
//
pTargetItem = m_pIWiaFirstChildItem;
}
if(pTargetItem != NULL) {
//
// get an IWiaPropertyStorage Interface
//
IWiaPropertyStorage *pIWiaPropStg;
hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
if (SUCCEEDED(hr)) {
hr = ReadPropLong(propid,pIWiaPropStg,plVal);
if(SUCCEEDED(hr)) {
//
// read has taken place
//
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadLong, ReadPropLong() failed"));
m_hrLastError = hr;
}
pIWiaPropStg->Release();
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadLong, QI for IWiaProperyStorage failed"));
m_hrLastError = hr;
}
}
return hr;
}
HRESULT CWIA::WriteLong(IWiaItem *pIWiaItem, PROPID propid, LONG lVal)
{
HRESULT hr = E_FAIL;
IWiaItem *pTargetItem = NULL;
PROPSPEC PropSpec[1];
//
// create a propspec
//
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
pTargetItem = pIWiaItem;
if(pTargetItem == NULL) {
//
// use first child of root
//
pTargetItem = m_pIWiaFirstChildItem;
}
if(pTargetItem != NULL) {
//
// get an IWiaPropertyStorage Interface
//
IWiaPropertyStorage *pIWiaPropStg;
hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
if (SUCCEEDED(hr)) {
hr = WritePropLong(propid,pIWiaPropStg,lVal);
if(SUCCEEDED(hr)) {
//
// read has taken place
//
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("WriteLong, WritePropLong() failed"));
m_hrLastError = hr;
}
pIWiaPropStg->Release();
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("WriteLong, QI for IWiaProperyStorage failed"));
m_hrLastError = hr;
}
}
return hr;
}
HRESULT CWIA::ReadStr(IWiaItem *pIWiaItem, PROPID propid, BSTR *pbstr)
{
HRESULT hr = E_FAIL;
IWiaItem *pTargetItem = NULL;
PROPSPEC PropSpec[1];
//
// create a propspec
//
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
pTargetItem = pIWiaItem;
if(pTargetItem == NULL) {
//
// use first child of root
//
pTargetItem = m_pIWiaFirstChildItem;
}
if(pTargetItem != NULL) {
//
// get an IWiaPropertyStorage Interface
//
IWiaPropertyStorage *pIWiaPropStg;
hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
if (SUCCEEDED(hr)) {
hr = ReadPropStr(propid,pIWiaPropStg,pbstr);
if(SUCCEEDED(hr)) {
//
// read has taken place
//
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadStr, ReadPropStr() failed"));
m_hrLastError = hr;
}
pIWiaPropStg->Release();
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadStr, QI for IWiaProperyStorage failed"));
m_hrLastError = hr;
}
}
return hr;
}
HRESULT CWIA::ReadGuid(IWiaItem *pIWiaItem, PROPID propid, GUID *pguidVal)
{
HRESULT hr = E_FAIL;
IWiaItem *pTargetItem = NULL;
PROPSPEC PropSpec[1];
//
// create a propspec
//
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
pTargetItem = pIWiaItem;
if(pTargetItem == NULL) {
//
// use first child of root
//
pTargetItem = m_pIWiaFirstChildItem;
}
if(pTargetItem != NULL) {
//
// get an IWiaPropertyStorage Interface
//
IWiaPropertyStorage *pIWiaPropStg;
hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
if (SUCCEEDED(hr)) {
hr = ReadPropGUID(propid,pIWiaPropStg,pguidVal);
if(SUCCEEDED(hr)) {
//
// read has taken place
//
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadGuid, ReadPropGuid() failed"));
m_hrLastError = hr;
}
pIWiaPropStg->Release();
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("ReadGuid, QI for IWiaProperyStorage failed"));
m_hrLastError = hr;
}
}
return hr;
}
HRESULT CWIA::WriteGuid(IWiaItem *pIWiaItem, PROPID propid, GUID guidVal)
{
HRESULT hr = E_FAIL;
IWiaItem *pTargetItem = NULL;
PROPSPEC PropSpec[1];
//
// create a propspec
//
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
pTargetItem = pIWiaItem;
if(pTargetItem == NULL) {
//
// use first child of root
//
pTargetItem = m_pIWiaFirstChildItem;
}
if(pTargetItem != NULL) {
//
// get an IWiaPropertyStorage Interface
//
IWiaPropertyStorage *pIWiaPropStg;
hr = pTargetItem->QueryInterface(IID_IWiaPropertyStorage,(void **)&pIWiaPropStg);
if (SUCCEEDED(hr)) {
hr = WritePropGUID(propid,pIWiaPropStg,guidVal);
if(SUCCEEDED(hr)) {
//
// read has taken place
//
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("WriteGuid, WritePropGuid() failed"));
m_hrLastError = hr;
}
pIWiaPropStg->Release();
} else {
//
// save last error, for later request
//
SaveErrorText(TEXT("WriteGuid, QI for IWiaProperyStorage failed"));
m_hrLastError = hr;
}
}
return hr;
}
HRESULT CWIA::DoBandedTransfer(DATA_ACQUIRE_INFO* pDataAcquireInfo)
{
HRESULT hr = S_OK;
//
// Write TYMED value to callback
//
hr = WriteLong(m_pIWiaFirstChildItem,WIA_IPA_TYMED,TYMED_CALLBACK);
//
// get IWiaDatatransfer interface
//
IWiaDataTransfer *pIBandTran = NULL;
hr = m_pIWiaFirstChildItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIBandTran);
if (SUCCEEDED(hr)) {
//
// create Banded callback
//
IWiaDataCallback* pIWiaDataCallback = NULL;
CWiaDataCallback* pCBandedCB = new CWiaDataCallback();
if (pCBandedCB) {
hr = pCBandedCB->QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback);
if (SUCCEEDED(hr)) {
WIA_DATA_TRANSFER_INFO wiaDataTransInfo;
pCBandedCB->Initialize(pDataAcquireInfo);
ZeroMemory(&wiaDataTransInfo, sizeof(WIA_DATA_TRANSFER_INFO));
wiaDataTransInfo.ulSize = sizeof(WIA_DATA_TRANSFER_INFO);
wiaDataTransInfo.ulBufferSize = 524288;//262144; // calculate, or determine buffer size
hr = pIBandTran->idtGetBandedData(&wiaDataTransInfo, pIWiaDataCallback);
m_bFinishedAcquire = TRUE;
pIBandTran->Release();
if (hr == S_OK) {
OutputDebugString(TEXT("IWiaData Transfer.(CALLBACK)..Success\n"));
} else if (hr == S_FALSE) {
OutputDebugString(TEXT("IWiaData Transfer.(CALLBACK)..Canceled by user\n"));
} else {
OutputDebugString(TEXT("* idtGetBandedData() Failed\n"));
}
//
// release Callback object
//
pCBandedCB->Release();
} else
// TEXT("* pCBandedCB->QueryInterface(IID_IWiaDataCallback) Failed");
return hr;
} else
return hr;
// TEXT("* pCBandedCB failed to create..");
} else
return hr;
// TEXT("* pIWiaItem->QueryInterface(IID_IWiaDataTransfer) Failed");
return S_OK;
}
HRESULT CWIA::DoFileTransfer(DATA_ACQUIRE_INFO* pDataAcquireInfo)
{
HRESULT hr = S_OK;
//
// Write TYMED value to file
//
hr = WriteLong(m_pIWiaFirstChildItem,WIA_IPA_TYMED,TYMED_FILE);
//
// get IWiaDatatransfer interface
//
IWiaDataTransfer *pIBandTran = NULL;
hr = m_pIWiaFirstChildItem->QueryInterface(IID_IWiaDataTransfer, (void **)&pIBandTran);
if (SUCCEEDED(hr)) {
//
// create Banded callback
//
IWiaDataCallback* pIWiaDataCallback = NULL;
CWiaDataCallback* pCBandedCB = new CWiaDataCallback();
if (pCBandedCB) {
hr = pCBandedCB->QueryInterface(IID_IWiaDataCallback,(void **)&pIWiaDataCallback);
if (SUCCEEDED(hr)) {
//
// fill out STGMEDIUM
//
STGMEDIUM StgMedium;
ZeroMemory(&StgMedium, sizeof(STGMEDIUM));
StgMedium.tymed = TYMED_FILE;
StgMedium.lpszFileName = NULL;
StgMedium.pUnkForRelease = NULL;
StgMedium.hGlobal = NULL;
pCBandedCB->Initialize(pDataAcquireInfo);
hr = pIBandTran->idtGetData(&StgMedium,pIWiaDataCallback);
m_bFinishedAcquire = TRUE;
pIBandTran->Release();
if (hr == S_OK) {
OutputDebugString(TEXT("IWiaData Transfer.(FILE)..Success\n"));
//
// We have completed the transfer...so now move the temporary file into
// the needed location, with the users requested file name.
//
CString WIATempFile = StgMedium.lpszFileName;
if(!CopyFile(WIATempFile,pDataAcquireInfo->szFileName,FALSE)){
OutputDebugString(TEXT("Failed to copy temp file.."));
}
//
// delete WIA created TEMP file
//
DeleteFile(WIATempFile);
} else if (hr == S_FALSE) {
OutputDebugString(TEXT("IWiaData Transfer.(FILE)..Canceled by user\n"));
} else {
OutputDebugString(TEXT("* idtGetData() Failed\n"));
}
//
// release Callback object
//
pCBandedCB->Release();
} else
// TEXT("* pCBandedCB->QueryInterface(IID_IWiaDataCallback) Failed");
return hr;
} else
return hr;
// TEXT("* pCBandedCB failed to create..");
} else
return hr;
// TEXT("* pIWiaItem->QueryInterface(IID_IWiaDataTransfer) Failed");
return hr;
}
HRESULT CWIA::WritePropGUID(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, GUID guidVal)
{
HRESULT hr = E_FAIL;
PROPSPEC propspec[1];
PROPVARIANT propvar[1];
propspec[0].ulKind = PRSPEC_PROPID;
propspec[0].propid = propid;
propvar[0].vt = VT_CLSID;
propvar[0].puuid = &guidVal;
hr = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
return hr;
}
HRESULT CWIA::ReadPropGUID(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, GUID *pguidVal)
{
HRESULT hr = E_FAIL;
PROPSPEC PropSpec[1];
PROPVARIANT PropVar[1];
UINT cbSize = 0;
memset(PropVar, 0, sizeof(PropVar));
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
hr = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
if (SUCCEEDED(hr)) {
pguidVal = PropVar[0].puuid;
}
return hr;
}
HRESULT CWIA::ReadPropStr(PROPID propid,IWiaPropertyStorage *pIWiaPropStg,BSTR *pbstr)
{
HRESULT hr = S_OK;
PROPSPEC PropSpec[1];
PROPVARIANT PropVar[1];
UINT cbSize = 0;
*pbstr = NULL;
memset(PropVar, 0, sizeof(PropVar));
PropSpec[0].ulKind = PRSPEC_PROPID;
PropSpec[0].propid = propid;
hr = pIWiaPropStg->ReadMultiple(1, PropSpec, PropVar);
if (SUCCEEDED(hr)) {
if (PropVar[0].pwszVal) {
*pbstr = SysAllocString(PropVar[0].pwszVal);
} else {
*pbstr = SysAllocString(L"");
}
if (*pbstr == NULL) {
hr = E_OUTOFMEMORY;
}
PropVariantClear(PropVar);
}
return hr;
}
HRESULT CWIA::WritePropStr(PROPID propid, IWiaPropertyStorage *pIWiaPropStg, BSTR bstr)
{
HRESULT hr = S_OK;
PROPSPEC propspec[1];
PROPVARIANT propvar[1];
propspec[0].ulKind = PRSPEC_PROPID;
propspec[0].propid = propid;
propvar[0].vt = VT_BSTR;
propvar[0].pwszVal = bstr;
hr = pIWiaPropStg->WriteMultiple(1, propspec, propvar, MIN_PROPID);
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////////////
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;
}
ULONG _stdcall CWiaDataCallback::AddRef()
{
InterlockedIncrement((long*) &m_cRef);
return m_cRef;
}
ULONG _stdcall CWiaDataCallback::Release()
{
ULONG ulRefCount = m_cRef - 1;
if (InterlockedDecrement((long*) &m_cRef) == 0)
{
delete this;
return 0;
}
return ulRefCount;
}
CWiaDataCallback::CWiaDataCallback()
{
m_cRef = 0;
m_BytesTransfered = 0;
m_pProgressFunc = NULL;
m_bCanceled = FALSE;
m_bBitmapCreated = FALSE;
}
CWiaDataCallback::~CWiaDataCallback()
{
}
HRESULT _stdcall CWiaDataCallback::Initialize(DATA_ACQUIRE_INFO* pDataAcquireInfo)
{
m_pProgressFunc = pDataAcquireInfo->pProgressFunc;
m_pDataAcquireInfo = pDataAcquireInfo;
m_lPageCount = 0;
return S_OK;
}
HRESULT _stdcall CWiaDataCallback::BandedDataCallback(LONG lMessage,
LONG lStatus,
LONG lPercentComplete,
LONG lOffset,
LONG lLength,
LONG lReserved,
LONG lResLength,
BYTE* pbBuffer)
{
m_bCanceled = FALSE;
//
// process callback messages
//
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;
if(m_pDataAcquireInfo->bTransferToClipboard) {
m_pDataAcquireInfo->hClipboardData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,m_MemBlockSize);
} else {
m_pDataAcquireInfo->hBitmapData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,m_MemBlockSize);
}
m_BytesTransfered = 0;
m_cFormat = pHeader->guidFormatID;
}
break;
case IT_MSG_DATA:
{
//
// increment bytes transferred counter
//
m_BytesTransfered += lLength;
if(m_BytesTransfered >= m_MemBlockSize){
//
// Alloc more memory for transfer buffer
//
m_MemBlockSize += (lLength * 2);
if(m_pDataAcquireInfo->bTransferToClipboard) {
if(m_pDataAcquireInfo->hClipboardData != NULL) {
m_pDataAcquireInfo->hClipboardData = GlobalReAlloc(m_pDataAcquireInfo->hClipboardData,
m_MemBlockSize, GMEM_MOVEABLE);
}
} else {
if(m_pDataAcquireInfo->hBitmapData != NULL) {
m_pDataAcquireInfo->hBitmapData = GlobalReAlloc(m_pDataAcquireInfo->hBitmapData,
m_MemBlockSize, GMEM_MOVEABLE);
}
}
}
if(m_pDataAcquireInfo->bTransferToClipboard) {
BYTE* pByte = (BYTE*)GlobalLock(m_pDataAcquireInfo->hClipboardData);
memcpy(pByte + lOffset, pbBuffer, lLength);
GlobalUnlock(m_pDataAcquireInfo->hClipboardData);
} else {
if(m_pDataAcquireInfo->hBitmapData != NULL) {
BYTE* pByte = (BYTE*)GlobalLock(m_pDataAcquireInfo->hBitmapData);
memcpy(pByte + lOffset, pbBuffer, lLength);
GlobalUnlock(m_pDataAcquireInfo->hBitmapData);
}
}
//
// do any extra image processing here
//
if(!m_pDataAcquireInfo->bTransferToClipboard) {
if(m_cFormat == WiaImgFmt_MEMORYBMP) {
if(m_bBitmapCreated) {
//
// Add data to your bitmap
//
AddDataToHBITMAP(m_pDataAcquireInfo->hWnd,
m_pDataAcquireInfo->hBitmapData,
&m_pDataAcquireInfo->hBitmap,
lOffset);
} else {
//
// Create your bitmap for display
//
CreateHBITMAP(m_pDataAcquireInfo->hWnd,
m_pDataAcquireInfo->hBitmapData,
&m_pDataAcquireInfo->hBitmap,
lOffset);
}
}
else if(m_cFormat == WiaImgFmt_TIFF) {
}
}
//
// process progress monitor
//
if(m_pProgressFunc != NULL){
if(lPercentComplete == 0)
m_bCanceled = m_pProgressFunc(TEXT("Acquiring Image..."),lPercentComplete);
else {
TCHAR szBuffer[MAX_PATH];
sprintf(szBuffer,TEXT("%d%% Complete..."),lPercentComplete);
m_bCanceled = m_pProgressFunc(szBuffer,lPercentComplete);
}
}
}
break;
case IT_MSG_STATUS:
{
//
// process "Status" message
//
if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE) {
if(m_pProgressFunc != NULL)
m_bCanceled = m_pProgressFunc(TEXT("Transfer from device"),lPercentComplete);
}
else if (lStatus & IT_STATUS_PROCESSING_DATA) {
if(m_pProgressFunc != NULL)
m_bCanceled = m_pProgressFunc(TEXT("Processing Data"),lPercentComplete);
}
else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT) {
if(m_pProgressFunc != NULL)
m_bCanceled = m_pProgressFunc(TEXT("Transfer to Client"),lPercentComplete);
}
}
break;
case IT_MSG_NEW_PAGE:
{
//
// process "New Page" message
//
PWIA_DATA_CALLBACK_HEADER pHeader = (PWIA_DATA_CALLBACK_HEADER)pbBuffer;
m_lPageCount = pHeader->lPageCount;
if(m_pProgressFunc != NULL)
m_bCanceled = m_pProgressFunc(TEXT("New Page"),lPercentComplete);
}
break;
}
//
// check use canceled acquire
//
if(m_bCanceled)
return S_FALSE;
return S_OK;
}
void CWiaDataCallback::AddDataToHBITMAP(HWND hWnd, HGLOBAL hBitmapData, HBITMAP *phBitmap, LONG lOffset)
{
BYTE* pData = (BYTE*)GlobalLock(hBitmapData);
if(pData) {
HDC hdc = ::GetDC(hWnd);
if(*phBitmap == NULL) {
OutputDebugString(TEXT("HBITMAP is NULL...this is a bad thing\n"));
return;
}
if(hdc == NULL) {
OutputDebugString(TEXT("HDC is NULL...this is a bad thing\n"));
return;
}
LPBITMAPINFO pbmi = (LPBITMAPINFO)pData;
if(hdc != NULL){
if(pbmi != NULL) {
if(SetDIBits(hdc,
*phBitmap,
0,
(pbmi->bmiHeader.biHeight < 0?(-(pbmi->bmiHeader.biHeight)):pbmi->bmiHeader.biHeight),
pData + sizeof(BITMAPINFOHEADER) + (sizeof(RGBQUAD) * pbmi->bmiHeader.biClrUsed),
pbmi,
DIB_RGB_COLORS) == 0) {
DWORD dwLastError = GetLastError();
TCHAR buf[10];
sprintf(buf,"GetLastError() code = %d\n",dwLastError);
OutputDebugString("AddDataToHBITMAP, SetDIBits failed..with ");
OutputDebugString(buf);
}
}
}
GlobalUnlock(hBitmapData);
} else {
OutputDebugString(TEXT("No bitmap memory available..\n"));
}
}
void CWiaDataCallback::CreateHBITMAP(HWND hWnd, HGLOBAL hBitmapData, HBITMAP *phBitmap, LONG lOffset)
{
HDC hdc = NULL; // DC to draw to
LPBITMAPINFO pbmi = NULL; // pointer to BITMAPINFO struct
BITMAP bitmap;
BYTE *pDib = NULL; // dib data
BYTE *pData = (BYTE*)GlobalLock(hBitmapData);
if(pData) {
if(*phBitmap != NULL) {
//
// delete old bitmap, if one exists
//
OutputDebugString(TEXT("Destroying old HBITMAP..\n"));
DeleteObject(*phBitmap);
}
//
// get hdc
//
hdc = ::GetWindowDC(hWnd);
if(hdc != NULL){
//
// set bitmap header information
//
pbmi = (LPBITMAPINFO)pData;
if (pbmi != NULL) {
//
// create a HBITMAP object
//
*phBitmap = ::CreateDIBSection(hdc,pbmi,DIB_RGB_COLORS,(void **)&pDib,NULL,0);
if (*phBitmap != NULL) {
//
// initialize it to white
//
memset(pDib,255,pbmi->bmiHeader.biSizeImage);
//
// get HBITMAP
//
::GetObject(*phBitmap,sizeof(BITMAP),(LPSTR)&bitmap);
m_bBitmapCreated = TRUE;
} else {
OutputDebugString(TEXT("HBITMAP is NULL..\n"));
}
} else {
OutputDebugString(TEXT("BITMAPINFOHEADER is NULL..\n"));
}
//
// release hdc
//
::ReleaseDC(hWnd,hdc);
} else {
OutputDebugString(TEXT("DC is NULL\n"));
}
GlobalUnlock(hBitmapData);
} else {
OutputDebugString(TEXT("No bitmap memory available..\n"));
}
}
//
// global Interface access functions
//
HRESULT WriteInterfaceToGlobalInterfaceTable(DWORD *pdwCookie, IWiaItem *pIWiaItem)
{
HRESULT hr = S_OK;
hr = g_pGIT->RegisterInterfaceInGlobal(pIWiaItem, IID_IWiaItem, pdwCookie);
return hr;
}
HRESULT ReadInterfaceFromGlobalInterfaceTable(DWORD dwCookie, IWiaItem **ppIWiaItem)
{
HRESULT hr = S_OK;
hr = g_pGIT->GetInterfaceFromGlobal(dwCookie, IID_IWiaItem, (void**)ppIWiaItem);
return hr;
}