1293 lines
34 KiB
C++
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;
|
|
}
|
|
|