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.
1659 lines
62 KiB
1659 lines
62 KiB
#include "precomp.h"
|
|
|
|
//
|
|
// values that the WIA/TWAIN data source provides for capability negotation
|
|
//
|
|
|
|
TW_UINT16 g_ScannerUnits[] = {TWUN_INCHES,TWUN_PIXELS};
|
|
TW_UINT16 g_ScannerBitOrder[] = {TWBO_MSBFIRST};
|
|
TW_UINT16 g_ScannerXferMech[] = {TWSX_NATIVE, TWSX_FILE, TWSX_MEMORY};
|
|
TW_UINT16 g_ScannerPixelFlavor[] = {TWPF_CHOCOLATE,TWPF_VANILLA};
|
|
|
|
const TW_UINT32 NUM_SCANNERCAPDATA = 29;
|
|
const TW_UINT32 NUM_SCANNERCAPDATA_NO_FEEDER_DETECTED = 26;
|
|
CAPDATA SCANNER_CAPDATA[NUM_SCANNERCAPDATA] =
|
|
{
|
|
//
|
|
// Every source must support all five DG_CONTROL / DAT_CAPABILITY operations on:
|
|
//
|
|
|
|
{CAP_XFERCOUNT, TWTY_INT16, TWON_ONEVALUE,
|
|
sizeof(TW_INT16), 0, 0, -1, 0, 1, NULL, NULL
|
|
},
|
|
|
|
//
|
|
// Every source must support DG_CONTROL / DAT_CAPABILITY, MSG_GET on:
|
|
//
|
|
|
|
{CAP_SUPPORTEDCAPS, TWTY_UINT16, TWON_ARRAY,
|
|
sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{CAP_UICONTROLLABLE, TWTY_BOOL, TWON_ONEVALUE,
|
|
sizeof(TW_BOOL), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
|
|
},
|
|
|
|
//
|
|
// Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
|
|
// MSG_GET, MSG_GETCURRENT, and MSG_GETDEFAULT on:
|
|
//
|
|
|
|
{ICAP_COMPRESSION, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{ICAP_PLANARCHUNKY, TWTY_UINT16, TWON_ONEVALUE,
|
|
sizeof(TW_UINT16), TWPC_CHUNKY, TWPC_CHUNKY, TWPC_CHUNKY, TWPC_PLANAR, 0, NULL, NULL
|
|
},
|
|
{ICAP_PHYSICALHEIGHT, TWTY_FIX32, TWON_ONEVALUE,
|
|
sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{ICAP_PHYSICALWIDTH, TWTY_FIX32, TWON_ONEVALUE,
|
|
sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{ICAP_PIXELFLAVOR, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 1, 0, g_ScannerPixelFlavor, NULL
|
|
},
|
|
|
|
//
|
|
// Sources that supply image information must support DG_CONTROL / DAT_CAPABILITY /
|
|
// MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT, MSG_RESET, and MSG_SET on:
|
|
//
|
|
|
|
{ICAP_BITDEPTH, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{ICAP_BITORDER, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 0, 0, g_ScannerBitOrder, NULL
|
|
},
|
|
{ICAP_PIXELTYPE, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{ICAP_UNITS, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 1, 0, g_ScannerUnits, NULL
|
|
},
|
|
{ICAP_XFERMECH, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 2, 0, g_ScannerXferMech, NULL
|
|
},
|
|
{ICAP_XRESOLUTION, TWTY_FIX32, TWON_RANGE,
|
|
sizeof(TW_FIX32), 100, 100, 75, 1200, 1, NULL, NULL
|
|
},
|
|
{ICAP_YRESOLUTION, TWTY_FIX32, TWON_RANGE,
|
|
sizeof(TW_FIX32), 100, 100, 75, 1200, 1, NULL, NULL
|
|
},
|
|
|
|
//
|
|
// The following capabilities are provided for application compatiblity only.
|
|
//
|
|
|
|
{ICAP_IMAGEFILEFORMAT, TWTY_UINT16, TWON_ENUMERATION,
|
|
sizeof(TW_UINT16), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{CAP_INDICATORS, TWTY_BOOL, TWON_ONEVALUE,
|
|
sizeof(TW_BOOL), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
|
|
},
|
|
{CAP_ENABLEDSUIONLY, TWTY_BOOL, TWON_ONEVALUE,
|
|
sizeof(TW_BOOL), FALSE, FALSE, FALSE, FALSE, 0, NULL, NULL
|
|
},
|
|
{CAP_DEVICEONLINE, TWTY_BOOL, TWON_ONEVALUE,
|
|
sizeof(TW_UINT16), TRUE, TRUE, TRUE, TRUE, 0, NULL, NULL
|
|
},
|
|
{ICAP_XNATIVERESOLUTION, TWTY_FIX32, TWON_ONEVALUE,
|
|
sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{ICAP_YNATIVERESOLUTION, TWTY_FIX32, TWON_ONEVALUE,
|
|
sizeof(TW_FIX32), 0, 0, 0, 0, 0, NULL, NULL
|
|
},
|
|
{ICAP_BRIGHTNESS, TWTY_FIX32, TWON_RANGE,
|
|
sizeof(TW_FIX32), 0, 0, -1000, 1000, 1, NULL, NULL
|
|
},
|
|
{ICAP_CONTRAST, TWTY_FIX32, TWON_RANGE,
|
|
sizeof(TW_FIX32), 0, 0, -1000, 1000, 1, NULL, NULL
|
|
},
|
|
{ICAP_XSCALING, TWTY_FIX32, TWON_RANGE,
|
|
sizeof(TW_FIX32), 1, 1, 1, 1, 1, NULL, NULL
|
|
},
|
|
{ICAP_YSCALING, TWTY_FIX32, TWON_RANGE,
|
|
sizeof(TW_FIX32), 1, 1, 1, 1, 1, NULL, NULL
|
|
},
|
|
{ICAP_THRESHOLD, TWTY_FIX32, TWON_RANGE,
|
|
sizeof(TW_FIX32), 128, 128, 0, 255, 1, NULL, NULL
|
|
},
|
|
|
|
//
|
|
// All sources must implement the advertised features supplied by their devices.
|
|
// The following properties are supplied for TWAIN protocol only, this source
|
|
// supports document feeders (if they are detected).
|
|
//
|
|
|
|
{CAP_FEEDERENABLED, TWTY_BOOL, TWON_ONEVALUE,
|
|
sizeof(TW_BOOL), FALSE, FALSE, FALSE, TRUE, 0, NULL, NULL
|
|
},
|
|
{CAP_FEEDERLOADED, TWTY_BOOL, TWON_ONEVALUE,
|
|
sizeof(TW_BOOL), FALSE, FALSE, FALSE, TRUE, 0, NULL, NULL
|
|
},
|
|
{CAP_AUTOFEED, TWTY_BOOL, TWON_ONEVALUE,
|
|
sizeof(TW_BOOL), FALSE, FALSE, FALSE, TRUE, 0, NULL, NULL
|
|
}
|
|
};
|
|
|
|
TW_UINT16 CWiaScannerDS::OpenDS(PTWAIN_MSG ptwMsg)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::OpenDS());
|
|
m_bUnknownPageLength = FALSE;
|
|
m_bCacheImage = FALSE;
|
|
m_bEnforceUIMode = FALSE;
|
|
m_bUnknownPageLengthMultiPageOverRide = FALSE;
|
|
if (ReadTwainRegistryDWORDValue(DWORD_REGVALUE_ENABLE_MULTIPAGE_SCROLLFED,
|
|
DWORD_REGVALUE_ENABLE_MULTIPAGE_SCROLLFED_ON) == DWORD_REGVALUE_ENABLE_MULTIPAGE_SCROLLFED_ON) {
|
|
m_bUnknownPageLengthMultiPageOverRide = TRUE;
|
|
}
|
|
|
|
TW_UINT16 twRc = TWRC_FAILURE;
|
|
HRESULT hr = S_OK;
|
|
|
|
twRc = CWiaDataSrc::OpenDS(ptwMsg);
|
|
if (TWRC_SUCCESS != twRc)
|
|
return twRc;
|
|
|
|
BASIC_INFO BasicInfo;
|
|
memset(&BasicInfo,0,sizeof(BasicInfo));
|
|
BasicInfo.Size = sizeof(BasicInfo);
|
|
|
|
hr = m_pDevice->GetBasicScannerInfo(&BasicInfo);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::OpenDS(), GetBasicScannerInfo() failed"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
DBG_TRC(("CWiaScannerDS::OpenDS(), Reported Basic Scanner Information from WIA device"));
|
|
DBG_TRC(("BasicInfo.Size = %d",BasicInfo.Size));
|
|
DBG_TRC(("BasicInfo.xBedSize = %d",BasicInfo.xBedSize));
|
|
DBG_TRC(("BasicInfo.yBedSize = %d",BasicInfo.yBedSize));
|
|
DBG_TRC(("BasicInfo.xOpticalRes = %d",BasicInfo.xOpticalRes));
|
|
DBG_TRC(("BasicInfo.yOpticalRes = %d",BasicInfo.yOpticalRes));
|
|
DBG_TRC(("BasicInfo.FeederCaps = %d",BasicInfo.FeederCaps));
|
|
|
|
//
|
|
// Update cap based on information we got
|
|
//
|
|
|
|
CCap * pCap = NULL;
|
|
TW_UINT32 Value = 0;
|
|
TW_FIX32 fix32;
|
|
memset(&fix32,0,sizeof(fix32));
|
|
|
|
//
|
|
// Cache the scanner document handling capability
|
|
//
|
|
|
|
m_FeederCaps = BasicInfo.FeederCaps;
|
|
|
|
//
|
|
// create capability list
|
|
//
|
|
|
|
if(m_FeederCaps > 0){
|
|
twRc = CreateCapList(NUM_SCANNERCAPDATA, SCANNER_CAPDATA);
|
|
} else {
|
|
twRc = CreateCapList(NUM_SCANNERCAPDATA_NO_FEEDER_DETECTED, SCANNER_CAPDATA);
|
|
}
|
|
|
|
if (TWCC_SUCCESS != twRc) {
|
|
m_twStatus.ConditionCode = twRc;
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
if (m_FeederCaps > 0) {
|
|
|
|
//
|
|
// we have a scanner that has feeder capabilities
|
|
//
|
|
|
|
pCap = NULL;
|
|
pCap = FindCap(CAP_FEEDERENABLED);
|
|
if (pCap) {
|
|
DBG_TRC(("Setting feeder enabled to TRUE, because we have a document feeder"));
|
|
twRc = pCap->Set(FALSE, FALSE, TRUE, TRUE);
|
|
}
|
|
|
|
pCap = NULL;
|
|
pCap = FindCap(CAP_FEEDERLOADED);
|
|
if (pCap) {
|
|
DBG_TRC(("Setting feeder loaded to TRUE, because we have a document feeder and assume it is loaded"));
|
|
twRc = pCap->Set(TRUE, TRUE, TRUE, TRUE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update the cached frame.
|
|
//
|
|
|
|
m_CurFrame.Left.Whole = m_CurFrame.Top.Whole = 0;
|
|
m_CurFrame.Left.Frac = m_CurFrame.Top.Frac = 0;
|
|
pCap = FindCap(ICAP_XNATIVERESOLUTION);
|
|
if (pCap) {
|
|
twRc = pCap->Set(BasicInfo.xOpticalRes, BasicInfo.xOpticalRes,
|
|
BasicInfo.xOpticalRes, BasicInfo.xOpticalRes);
|
|
}
|
|
pCap = NULL;
|
|
pCap = FindCap(ICAP_YNATIVERESOLUTION);
|
|
if (pCap) {
|
|
twRc = pCap->Set(BasicInfo.yOpticalRes, BasicInfo.yOpticalRes,
|
|
BasicInfo.yOpticalRes, BasicInfo.yOpticalRes);
|
|
}
|
|
pCap = NULL;
|
|
pCap = FindCap(ICAP_PHYSICALHEIGHT);
|
|
if (pCap) {
|
|
// bed size is in 1000th inches (we default to inches, so calculate the size correctly..)
|
|
fix32 = FloatToFix32((FLOAT)(BasicInfo.yBedSize / 1000.00));
|
|
memcpy(&Value, &fix32, sizeof(TW_UINT32));
|
|
twRc = pCap->Set(Value, Value, Value, Value);
|
|
m_CurFrame.Bottom = fix32;
|
|
}
|
|
pCap = NULL;
|
|
pCap = FindCap(ICAP_PHYSICALWIDTH);
|
|
if (pCap) {
|
|
// bed size is in 1000th inches (we default to inches, so calculate the size correctly..)
|
|
fix32 = FloatToFix32((FLOAT)(BasicInfo.xBedSize / 1000.00));
|
|
memcpy(&Value, &fix32, sizeof(TW_UINT32));
|
|
twRc = pCap->Set(Value, Value, Value, Value);
|
|
m_CurFrame.Right = fix32;
|
|
}
|
|
|
|
//
|
|
// By TWAIN standard, capability negotiations come before
|
|
// data source enabling. For this reason, we have to
|
|
// trigger the device have those information ready for us.
|
|
//
|
|
|
|
hr = m_pDevice->AcquireImages(NULL, FALSE);
|
|
if (SUCCEEDED(hr)) {
|
|
hr = m_pDevice->EnumAcquiredImage(0, &m_pCurrentIWiaItem);
|
|
if (SUCCEEDED(hr)) {
|
|
twRc = GetCommonSettings();
|
|
if(TWRC_SUCCESS == twRc){
|
|
twRc = GetSettings();
|
|
}
|
|
}
|
|
}
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::OnImageLayoutMsg(PTWAIN_MSG ptwMsg)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::OnImageLayoutMsg());
|
|
TW_UINT16 twRc = TWRC_SUCCESS;
|
|
TW_IMAGELAYOUT *pLayout = (TW_IMAGELAYOUT*)ptwMsg->pData;
|
|
switch (ptwMsg->MSG) {
|
|
case MSG_GET:
|
|
case MSG_GETDEFAULT:
|
|
case MSG_GETCURRENT:
|
|
switch (GetTWAINState()) {
|
|
case DS_STATE_7:
|
|
m_twStatus.ConditionCode = TWCC_SEQERROR;
|
|
twRc = TWRC_FAILURE;
|
|
break;
|
|
default:
|
|
{
|
|
GetImageLayout(&m_CurImageLayout);
|
|
pLayout->DocumentNumber = m_CurImageLayout.DocumentNumber;
|
|
pLayout->PageNumber = m_CurImageLayout.PageNumber;
|
|
pLayout->FrameNumber = m_CurImageLayout.FrameNumber;
|
|
pLayout->Frame.Top.Whole = m_CurImageLayout.Frame.Top.Whole;
|
|
pLayout->Frame.Top.Frac = m_CurImageLayout.Frame.Top.Frac;
|
|
pLayout->Frame.Left.Whole = m_CurImageLayout.Frame.Left.Whole;
|
|
pLayout->Frame.Left.Frac = m_CurImageLayout.Frame.Left.Frac;
|
|
pLayout->Frame.Right.Whole = m_CurImageLayout.Frame.Right.Whole;
|
|
pLayout->Frame.Right.Frac = m_CurImageLayout.Frame.Right.Frac;
|
|
pLayout->Frame.Bottom.Whole = m_CurImageLayout.Frame.Bottom.Whole;
|
|
pLayout->Frame.Bottom.Frac = m_CurImageLayout.Frame.Bottom.Frac;
|
|
//pLayout->Frame = m_CurFrame; // BETTER BE IN CORRECT UNITS!!!!
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case MSG_SET:
|
|
|
|
switch (GetTWAINState()) {
|
|
case DS_STATE_5:
|
|
case DS_STATE_6:
|
|
case DS_STATE_7:
|
|
m_twStatus.ConditionCode = TWCC_SEQERROR;
|
|
twRc = TWRC_FAILURE;
|
|
break;
|
|
default:
|
|
// do actual MSG_SET here..
|
|
{
|
|
DBG_TRC(("CWiaScannerDS::OnImageLayoutMsg(), MSG_SET TW_IMAGELAYOUT to set from Application"));
|
|
DBG_TRC(("DocumentNumber = %d",pLayout->DocumentNumber));
|
|
DBG_TRC(("PageNumber = %d",pLayout->PageNumber));
|
|
DBG_TRC(("FrameNumber = %d",pLayout->FrameNumber));
|
|
DBG_TRC(("Frame.Top.Whole = %d",pLayout->Frame.Top.Whole));
|
|
DBG_TRC(("Frame.Top.Frac = %d",pLayout->Frame.Top.Frac));
|
|
DBG_TRC(("Frame.Left.Whole = %d",pLayout->Frame.Left.Whole));
|
|
DBG_TRC(("Frame.Left.Frac = %d",pLayout->Frame.Left.Frac));
|
|
DBG_TRC(("Frame.Right.Whole = %d",pLayout->Frame.Right.Whole));
|
|
DBG_TRC(("Frame.Right.Frac = %d",pLayout->Frame.Right.Frac));
|
|
DBG_TRC(("Frame.Bottom.Whole = %d",pLayout->Frame.Bottom.Whole));
|
|
DBG_TRC(("Frame.Bottom.Frac = %d",pLayout->Frame.Bottom.Frac));
|
|
|
|
//
|
|
// perform a really rough validation check on FRAME values.
|
|
// validate possible incorrect settings by an application.
|
|
//
|
|
|
|
CCap *pXCap = FindCap(ICAP_PHYSICALWIDTH);
|
|
TW_INT16 MaxWidthWhole = 8;
|
|
if(pXCap){
|
|
MaxWidthWhole = (TW_INT16)pXCap->GetCurrent();
|
|
}
|
|
if(pLayout->Frame.Right.Whole > MaxWidthWhole) {
|
|
twRc = TWRC_FAILURE;
|
|
m_twStatus.ConditionCode = TWCC_BADVALUE;
|
|
DBG_TRC(("Frame.Right.Whole Value (%d) is greater than MAX Right value (%d)",pLayout->Frame.Right.Whole,MaxWidthWhole));
|
|
}
|
|
|
|
CCap *pYCap = FindCap(ICAP_PHYSICALHEIGHT);
|
|
TW_INT16 MaxHeightWhole = 11;
|
|
if(pYCap){
|
|
MaxHeightWhole = (TW_INT16)pYCap->GetCurrent();
|
|
}
|
|
|
|
if(pLayout->Frame.Bottom.Whole > MaxHeightWhole) {
|
|
twRc = TWRC_FAILURE;
|
|
m_twStatus.ConditionCode = TWCC_BADVALUE;
|
|
DBG_TRC(("Frame.Bottom.Whole Value (%d) is greater than MAX Bottom value (%d)",pLayout->Frame.Bottom.Whole,MaxHeightWhole));
|
|
}
|
|
|
|
if (twRc == TWRC_SUCCESS) {
|
|
|
|
//
|
|
// save SET values to ImageLayout member
|
|
//
|
|
|
|
m_CurImageLayout.DocumentNumber = pLayout->DocumentNumber;
|
|
m_CurImageLayout.PageNumber = pLayout->PageNumber;
|
|
m_CurImageLayout.FrameNumber = pLayout->FrameNumber;
|
|
m_CurImageLayout.Frame.Top.Whole = pLayout->Frame.Top.Whole;
|
|
m_CurImageLayout.Frame.Top.Frac = pLayout->Frame.Top.Frac;
|
|
m_CurImageLayout.Frame.Left.Whole = pLayout->Frame.Left.Whole;
|
|
m_CurImageLayout.Frame.Left.Frac = pLayout->Frame.Left.Frac;
|
|
m_CurImageLayout.Frame.Right.Whole = pLayout->Frame.Right.Whole;
|
|
m_CurImageLayout.Frame.Right.Frac = pLayout->Frame.Right.Frac;
|
|
m_CurImageLayout.Frame.Bottom.Whole = pLayout->Frame.Bottom.Whole;
|
|
m_CurImageLayout.Frame.Bottom.Frac = pLayout->Frame.Bottom.Frac;
|
|
twRc = SetImageLayout(pLayout);
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
break;
|
|
case MSG_RESET:
|
|
|
|
switch (GetTWAINState()) {
|
|
case DS_STATE_5:
|
|
case DS_STATE_6:
|
|
case DS_STATE_7:
|
|
m_twStatus.ConditionCode = TWCC_SEQERROR;
|
|
twRc = TWRC_FAILURE;
|
|
break;
|
|
default:
|
|
// do actual MSG_RESET here..
|
|
{
|
|
#ifdef DEBUG
|
|
DBG_TRC(("\n\nMSG_RESET - ImageLayout DocNum = %d, PgNum = %d, FrameNum = %d",
|
|
pLayout->DocumentNumber,
|
|
pLayout->PageNumber,
|
|
pLayout->FrameNumber));
|
|
|
|
DBG_TRC(("Frame Values\n Top = %d.%d\nLeft = %d.%d\nRight = %d.%d\nBottom = %d.%d",
|
|
pLayout->Frame.Top.Whole,
|
|
pLayout->Frame.Top.Frac,
|
|
pLayout->Frame.Left.Whole,
|
|
pLayout->Frame.Left.Frac,
|
|
pLayout->Frame.Right.Whole,
|
|
pLayout->Frame.Right.Frac,
|
|
pLayout->Frame.Bottom.Whole,
|
|
pLayout->Frame.Bottom.Frac));
|
|
#endif
|
|
|
|
m_CurImageLayout.Frame.Top.Whole = 0;
|
|
m_CurImageLayout.Frame.Top.Frac = 0;
|
|
m_CurImageLayout.Frame.Left.Whole = 0;
|
|
m_CurImageLayout.Frame.Left.Frac = 0;
|
|
m_CurImageLayout.Frame.Right.Whole = 8;
|
|
m_CurImageLayout.Frame.Right.Frac = 5;
|
|
m_CurImageLayout.Frame.Bottom.Whole = 11;
|
|
m_CurImageLayout.Frame.Bottom.Frac = 0;
|
|
|
|
}
|
|
break;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
twRc = TWRC_FAILURE;
|
|
m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
|
|
DSError();
|
|
break;
|
|
}
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::CloseDS(PTWAIN_MSG ptwMsg)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::CloseDS());
|
|
DestroyCapList();
|
|
return CWiaDataSrc::CloseDS(ptwMsg);
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::EnableDS(TW_USERINTERFACE *pUI)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::EnableDS());
|
|
TW_UINT16 twRc = TWRC_FAILURE;
|
|
m_bUnknownPageLength = FALSE;
|
|
if (DS_STATE_4 == GetTWAINState()) {
|
|
HRESULT hr = S_OK;
|
|
if(pUI->ShowUI){
|
|
DBG_TRC(("CWiaScannerDS::EnableDS(), TWAIN UI MODE"));
|
|
m_pDevice->FreeAcquiredImages();
|
|
m_pCurrentIWiaItem = NULL;
|
|
} else {
|
|
DBG_TRC(("CWiaScannerDS::EnableDS(), TWAIN UI-LESS MODE"));
|
|
m_pDevice->FreeAcquiredImages();
|
|
m_pCurrentIWiaItem = NULL;
|
|
}
|
|
hr = m_pDevice->AcquireImages(HWND (pUI->ShowUI ? pUI->hParent : NULL),pUI->ShowUI);
|
|
if (S_OK == hr) {
|
|
twRc = TWRC_SUCCESS;
|
|
LONG lNumImages = 0;
|
|
m_pDevice->GetNumAcquiredImages(&lNumImages);
|
|
if (lNumImages) {
|
|
m_NumIWiaItems = (TW_UINT32)lNumImages;
|
|
m_pIWiaItems = new (IWiaItem *[m_NumIWiaItems]);
|
|
if (m_pIWiaItems) {
|
|
hr = m_pDevice->GetAcquiredImageList(lNumImages, m_pIWiaItems, NULL);
|
|
if (FAILED(hr)) {
|
|
delete [] m_pIWiaItems;
|
|
m_pIWiaItems = NULL;
|
|
m_NumIWiaItems = 0;
|
|
m_NextIWiaItemIndex = 0;
|
|
m_twStatus.ConditionCode = TWCC_BUMMER;
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
} else {
|
|
m_NumIWiaItems = 0;
|
|
m_twStatus.ConditionCode = TWCC_LOWMEMORY;
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
}
|
|
} else if(S_FALSE == hr) {
|
|
return TWRC_CANCEL;
|
|
} else {
|
|
m_twStatus.ConditionCode = TWCC_OPERATIONERROR;
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
|
|
if (TWRC_SUCCESS == twRc) {
|
|
if (m_NumIWiaItems) {
|
|
m_pCurrentIWiaItem = m_pIWiaItems[0];
|
|
m_NextIWiaItemIndex = 1;
|
|
|
|
//
|
|
// Special case the devices that can acquire with an unknown page length setting.
|
|
// WIA devices will be missing the YExtent property, or it will be set to 0.
|
|
// TRUE will be returned from IsUnknownPageLengthDevice() if it this functionality
|
|
// is supported.
|
|
// Since TWAIN does not support unknown page lengths very well, we are required to
|
|
// cache the page data, and image settings.
|
|
// Note: unknown page length devices will be limited to DIB/BMP data types.
|
|
// This will allow the TWAIN compatibility layer to calculate the
|
|
// missing image information from the transferred data size.
|
|
//
|
|
|
|
if(IsUnknownPageLengthDevice()){
|
|
twRc = TransferToMemory(WiaImgFmt_MEMORYBMP);
|
|
if(TWRC_SUCCESS != twRc){
|
|
return twRc;
|
|
}
|
|
m_bUnknownPageLength = TRUE;
|
|
m_bCacheImage = TRUE;
|
|
}
|
|
|
|
//
|
|
// transition to STATE_5
|
|
//
|
|
|
|
SetTWAINState(DS_STATE_5);
|
|
|
|
NotifyXferReady();
|
|
|
|
twRc = TWRC_SUCCESS;
|
|
} else {
|
|
NotifyCloseReq();
|
|
|
|
//
|
|
// transition to STATE_5
|
|
//
|
|
|
|
SetTWAINState(DS_STATE_5);
|
|
|
|
twRc = TWRC_SUCCESS;
|
|
}
|
|
}
|
|
}
|
|
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::SetCapability(CCap *pCap,TW_CAPABILITY *ptwCap)
|
|
{
|
|
TW_UINT16 twRc = TWRC_SUCCESS;
|
|
|
|
//
|
|
// Use base class's function for now
|
|
//
|
|
|
|
twRc = CWiaDataSrc::SetCapability(pCap, ptwCap);
|
|
|
|
if (twRc == TWRC_SUCCESS) {
|
|
twRc = CWiaDataSrc::SetCommonSettings(pCap);
|
|
if(twRc == TWRC_SUCCESS){
|
|
twRc = SetSettings(pCap);
|
|
}
|
|
}
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::TransferToFile(GUID guidFormatID)
|
|
{
|
|
TW_UINT16 twRc = TWRC_FAILURE;
|
|
|
|
CCap *pPendingXfers = FindCap(CAP_XFERCOUNT);
|
|
if(pPendingXfers){
|
|
if(IsFeederEnabled()){
|
|
DBG_TRC(("CWiaScannerDS::TransferToFile(), Scanner device is set to FEEDER mode for transfer"));
|
|
pPendingXfers->SetCurrent((TW_UINT32)32767);
|
|
} else {
|
|
DBG_TRC(("CWiaScannerDS::TransferToFile(), Scanner device is set to FLATBED mode for transfer"));
|
|
pPendingXfers->SetCurrent((TW_UINT32)0);
|
|
}
|
|
}
|
|
|
|
if (m_bCacheImage) {
|
|
m_bCacheImage = FALSE;
|
|
|
|
//
|
|
// acquire a cached image
|
|
//
|
|
|
|
HGLOBAL hDIB = NULL;
|
|
|
|
twRc = CWiaDataSrc::GetCachedImage(&hDIB);
|
|
if(TWRC_SUCCESS == twRc){
|
|
|
|
//
|
|
// cached data is always upside down orientation
|
|
// because it was acquired using the TransferToMemory()
|
|
// API. Call FlipDIB() to correct the image's orientation
|
|
// and to adjust any negative heights that may exist.
|
|
//
|
|
|
|
FlipDIB(hDIB,TRUE);
|
|
|
|
twRc = WriteDIBToFile(m_FileXferName, hDIB);
|
|
|
|
GlobalFree(hDIB);
|
|
hDIB = NULL;
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// acquire a real image
|
|
//
|
|
|
|
twRc = CWiaDataSrc::TransferToFile(guidFormatID);
|
|
}
|
|
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::TransferToDIB(HGLOBAL *phDIB)
|
|
{
|
|
TW_UINT16 twRc = TWRC_FAILURE;
|
|
|
|
CCap *pPendingXfers = FindCap(CAP_XFERCOUNT);
|
|
if(pPendingXfers){
|
|
if(IsFeederEnabled()){
|
|
DBG_TRC(("CWiaScannerDS::TransferToDIB(), Scanner device is set to FEEDER mode for transfer"));
|
|
pPendingXfers->SetCurrent((TW_UINT32)32767);
|
|
} else {
|
|
DBG_TRC(("CWiaScannerDS::TransferToDIB(), Scanner device is set to FLATBED mode for transfer"));
|
|
pPendingXfers->SetCurrent((TW_UINT32)0);
|
|
}
|
|
}
|
|
|
|
if (m_bCacheImage) {
|
|
m_bCacheImage = FALSE;
|
|
|
|
//
|
|
// acquire a cached image
|
|
//
|
|
|
|
twRc = CWiaDataSrc::GetCachedImage(phDIB);
|
|
if(TWRC_SUCCESS == twRc){
|
|
|
|
//
|
|
// cached data is always upside down orientation
|
|
// because it was acquired using the TransferToMemory()
|
|
// API. Call FlipDIB() to correct the image's orientation
|
|
// and to adjust any negative heights that may exist.
|
|
//
|
|
|
|
FlipDIB(*phDIB,TRUE);
|
|
|
|
twRc = TWRC_XFERDONE;
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// acquire a real image
|
|
//
|
|
|
|
twRc = CWiaDataSrc::TransferToDIB(phDIB);
|
|
}
|
|
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::TransferToMemory(GUID guidFormatID)
|
|
{
|
|
TW_UINT16 twRc = TWRC_FAILURE;
|
|
CCap *pPendingXfers = FindCap(CAP_XFERCOUNT);
|
|
if(pPendingXfers){
|
|
if(IsFeederEnabled()){
|
|
DBG_TRC(("CWiaScannerDS::TransferToMemory(), Scanner device is set to FEEDER mode for transfer"));
|
|
pPendingXfers->SetCurrent((TW_UINT32)32767);
|
|
} else {
|
|
DBG_TRC(("CWiaScannerDS::TransferToMemory(), Scanner device is set to FLATBED mode for transfer"));
|
|
pPendingXfers->SetCurrent((TW_UINT32)0);
|
|
}
|
|
}
|
|
|
|
if (m_bCacheImage) {
|
|
m_bCacheImage = FALSE;
|
|
|
|
//
|
|
// acquire a cached image
|
|
//
|
|
|
|
//
|
|
// cached data is already in the correct form to just pass
|
|
// back because it was originally acquired using the TransferToMemory()
|
|
// API.
|
|
//
|
|
|
|
twRc = CWiaDataSrc::GetCachedImage(&m_hMemXferBits);
|
|
if(TWRC_FAILURE == twRc){
|
|
DBG_ERR(("CWiaDataSrc::GetCachedImage(), failed to return cached data"));
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// acquire a real image
|
|
//
|
|
|
|
twRc = CWiaDataSrc::TransferToMemory(guidFormatID);
|
|
|
|
if(TWRC_FAILURE == twRc){
|
|
DBG_ERR(("CWiaDataSrc::TransferToMemory(), failed to return data"));
|
|
}
|
|
}
|
|
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::OnPendingXfersMsg(PTWAIN_MSG ptwMsg)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::OnPendingXfersMsg());
|
|
TW_UINT16 twRc = TWRC_SUCCESS;
|
|
|
|
CCap *pXferCount;
|
|
pXferCount = FindCap(CAP_XFERCOUNT);
|
|
if (!pXferCount) {
|
|
m_twStatus.ConditionCode = TWCC_BUMMER;
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
twRc = TWRC_SUCCESS;
|
|
switch (ptwMsg->MSG) {
|
|
case MSG_GET:
|
|
switch (GetTWAINState()) {
|
|
case DS_STATE_4:
|
|
case DS_STATE_5:
|
|
case DS_STATE_6:
|
|
case DS_STATE_7:
|
|
if(m_bUnknownPageLength){
|
|
if(m_bUnknownPageLengthMultiPageOverRide){
|
|
((TW_PENDINGXFERS *)ptwMsg->pData)->Count = (TW_INT16)pXferCount->GetCurrent();
|
|
DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_GET returning %d (unknown page length device detected) MULTI-PAGE enabled",((TW_PENDINGXFERS *)ptwMsg->pData)->Count));
|
|
} else {
|
|
DBG_WRN(("CWiaScannerDS::OnPendingXfersMsg(), MSG_GET returning 0 (unknown page length device detected)"));
|
|
((TW_PENDINGXFERS *)ptwMsg->pData)->Count = 0; // force 1 page only
|
|
}
|
|
} else {
|
|
((TW_PENDINGXFERS *)ptwMsg->pData)->Count = (TW_INT16)pXferCount->GetCurrent();
|
|
DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_GET returning %d",((TW_PENDINGXFERS *)ptwMsg->pData)->Count));
|
|
}
|
|
break;
|
|
default:
|
|
twRc = TWRC_FAILURE;
|
|
m_twStatus.ConditionCode = TWCC_SEQERROR;
|
|
DSError();
|
|
break;
|
|
}
|
|
break;
|
|
case MSG_ENDXFER:
|
|
if (DS_STATE_6 == GetTWAINState() || DS_STATE_7 == GetTWAINState()) {
|
|
ResetMemXfer();
|
|
TW_INT32 Count = 0;
|
|
if (m_bUnknownPageLength) {
|
|
if(m_bUnknownPageLengthMultiPageOverRide){
|
|
DBG_WRN(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER (unknown page length device detected) MULTI-PAGE enabled"));
|
|
|
|
//
|
|
// check to see if we are in FEEDER mode
|
|
//
|
|
|
|
if (IsFeederEnabled()) {
|
|
|
|
//
|
|
// check for documents
|
|
//
|
|
|
|
if (IsFeederEmpty()) {
|
|
Count = 0;
|
|
} else {
|
|
Count = pXferCount->GetCurrent();
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// we must be in FLATBED mode, so force a single page transfer
|
|
//
|
|
|
|
Count = 0;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER returning 0 (unknown page length device detected)"));
|
|
Count = 0; // force a single page transfer only
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// check to see if we are in FEEDER mode
|
|
//
|
|
|
|
if (IsFeederEnabled()) {
|
|
|
|
//
|
|
// check for documents
|
|
//
|
|
|
|
if (IsFeederEmpty()) {
|
|
Count = 0;
|
|
} else {
|
|
Count = pXferCount->GetCurrent();
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// we must be in FLATBED mode, so force a single page transfer
|
|
//
|
|
|
|
Count = 0;
|
|
}
|
|
}
|
|
|
|
if(Count == 32767){
|
|
DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER, -1 or (32767) (feeder may have more documents)"));
|
|
} else if (Count > 0){
|
|
Count--;
|
|
} else {
|
|
Count = 0;
|
|
}
|
|
|
|
((TW_PENDINGXFERS*)ptwMsg->pData)->Count = (SHORT)Count;
|
|
pXferCount->SetCurrent((TW_UINT32)Count);
|
|
if (Count == 0) {
|
|
|
|
DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER, no more pages to transfer"));
|
|
|
|
//
|
|
// Transition to STATE_5
|
|
//
|
|
|
|
SetTWAINState(DS_STATE_5);
|
|
NotifyCloseReq();
|
|
} else if(Count == 32767){
|
|
|
|
DBG_TRC(("CWiaScannerDS::OnPendingXfersMsg(), MSG_ENDXFER, more pages to transfer"));
|
|
|
|
//
|
|
// Transition to STATE_6
|
|
//
|
|
|
|
SetTWAINState(DS_STATE_6);
|
|
|
|
}
|
|
} else {
|
|
twRc = TWRC_FAILURE;
|
|
m_twStatus.ConditionCode = TWCC_SEQERROR;
|
|
DSError();
|
|
}
|
|
break;
|
|
case MSG_RESET:
|
|
if (DS_STATE_6 == GetTWAINState()) {
|
|
|
|
//
|
|
// Transition to STATE_5
|
|
//
|
|
|
|
SetTWAINState(DS_STATE_5);
|
|
((TW_PENDINGXFERS*)ptwMsg->pData)->Count = 0;
|
|
|
|
ResetMemXfer();
|
|
pXferCount->SetCurrent((TW_UINT32)0);
|
|
} else {
|
|
twRc = TWRC_FAILURE;
|
|
m_twStatus.ConditionCode = TWCC_SEQERROR;
|
|
DSError();
|
|
}
|
|
break;
|
|
default:
|
|
twRc = TWRC_FAILURE;
|
|
m_twStatus.ConditionCode = TWCC_BADPROTOCOL;
|
|
DSError();
|
|
break;
|
|
}
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::SetImageLayout(TW_IMAGELAYOUT *pImageLayout)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::SetImageLayout());
|
|
HRESULT hr = S_OK;
|
|
LONG lXPos = 0;
|
|
LONG lYPos = 0;
|
|
LONG lXExtent = 0;
|
|
LONG lYExtent = 0;
|
|
LONG lXRes = 0;
|
|
LONG lYRes = 0;
|
|
BOOL bCheckStatus = FALSE;
|
|
CWiahelper WIA;
|
|
hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to set IWiaItem for property reading"));
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_XPOS,&lXPos);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_XPOS"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YPOS,&lYPos);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_YPOS"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_XEXTENT,&lXExtent);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_XEXTENT"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YEXTENT,&lYExtent);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_YEXTENT"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_XRES,&lXRes);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_XRES"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YRES,&lYRes);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to read WIA_IPS_YRES"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
//
|
|
// read the current values of the device
|
|
//
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
DBG_TRC(("==============================================================================="));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), WIA extents from device at %d dpi(x), %d dpi(y)",lXRes,lYRes));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current X Position = %d",lXPos));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current Y Position = %d",lYPos));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current X Extent = %d",lXExtent));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), Current Y Extent = %d",lYExtent));
|
|
DBG_TRC(("==============================================================================="));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN extents to convert.."));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN X Position = %f",Fix32ToFloat(pImageLayout->Frame.Left)));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN Y Position = %f",Fix32ToFloat(pImageLayout->Frame.Top)));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN X Extent = %f",Fix32ToFloat(pImageLayout->Frame.Right)));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(),TWAIN Y Extent = %f",Fix32ToFloat(pImageLayout->Frame.Bottom)));
|
|
DBG_TRC(("==============================================================================="));
|
|
|
|
lXPos = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Left),lXRes);
|
|
lYPos = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Top),lYRes);
|
|
lXExtent = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Right),lXRes);
|
|
lYExtent = ConvertFromTWAINUnits(Fix32ToFloat(pImageLayout->Frame.Bottom),lYRes);
|
|
|
|
DBG_TRC(("TWAIN -> WIA extent conversion at %d dpi(x), %d dpi(y)",lXRes,lYRes));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), New X Position = %d",lXPos));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), New Y Position = %d",lYPos));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), New X Extent = %d",lXExtent));
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), New Y Extent = %d",lYExtent));
|
|
DBG_TRC(("==============================================================================="));
|
|
|
|
if (!m_bUnknownPageLength) {
|
|
|
|
//
|
|
// note: A failure to write the properties, isn't a large issue here, because
|
|
// TWAIN UI-LESS mode expects clipping. They will reread properties
|
|
// for application's validation section. All capabilities are validated
|
|
// against their valid values, before setting here.
|
|
//
|
|
|
|
//
|
|
// Write extents first, because TWAIN expects Height/Width settings to validate
|
|
// the new Pos settings.
|
|
//
|
|
|
|
hr = WIA.WritePropertyLong(WIA_IPS_XEXTENT,lXExtent);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_XEXTENT"));
|
|
bCheckStatus = TRUE;
|
|
}
|
|
|
|
hr = WIA.WritePropertyLong(WIA_IPS_YEXTENT,lYExtent);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_YEXTENT"));
|
|
bCheckStatus = TRUE;
|
|
}
|
|
|
|
//
|
|
// Write position settings...(top-of-page offsets)
|
|
//
|
|
|
|
hr = WIA.WritePropertyLong(WIA_IPS_XPOS,lXPos);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_XPOS"));
|
|
bCheckStatus = TRUE;
|
|
}
|
|
|
|
hr = WIA.WritePropertyLong(WIA_IPS_YPOS,lYPos);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::SetImageLayout(), failed to write WIA_IPS_YPOS"));
|
|
bCheckStatus = TRUE;
|
|
}
|
|
|
|
if (bCheckStatus) {
|
|
DBG_TRC(("CWiaScannerDS::SetImageLayout(), some settings could not be set exactly, so return TWRC_CHECKSTATUS"));
|
|
//return TWRC_CHECKSTATUS;
|
|
}
|
|
} else {
|
|
DBG_WRN(("CWiaScannerDS::SetImageLayout(), ImageLayout is does not make since when using a UnknownPageLength Device"));
|
|
//return TWRC_CHECKSTATUS;
|
|
}
|
|
|
|
} else {
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
//
|
|
// Always return TWRC_CHECKSTATUS because we may have rounding errors.
|
|
// According to the TWAIN spec, a return of TWRC_CHECKSTATUS tells the
|
|
// calling application that we successfully set the settings, but there
|
|
// may have been some changes (clipping etc.) So the Calling application
|
|
// is required to requery for our current settings.
|
|
//
|
|
|
|
//
|
|
// call GetImageLayout to update our TWAIN capabilities to match our new WIA settings.
|
|
//
|
|
|
|
GetImageLayout(&m_CurImageLayout);
|
|
|
|
return TWRC_CHECKSTATUS; //return TWRC_SUCCESS;
|
|
}
|
|
TW_UINT16 CWiaScannerDS::GetImageLayout(TW_IMAGELAYOUT *pImageLayout)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::GetImageLayout());
|
|
HRESULT hr = S_OK;
|
|
LONG lXPos = 0;
|
|
LONG lYPos = 0;
|
|
LONG lXExtent = 0;
|
|
LONG lYExtent = 0;
|
|
LONG lXRes = 0;
|
|
LONG lYRes = 0;
|
|
CWiahelper WIA;
|
|
hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to set IWiaItem for property reading"));
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_XPOS,&lXPos);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_XPOS"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YPOS,&lYPos);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_YPOS"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_XEXTENT,&lXExtent);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_XEXTENT"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YEXTENT,&lYExtent);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_YEXTENT"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_XRES,&lXRes);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_XRES"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YRES,&lYRes);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), failed to read WIA_IPS_YRES"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
if(lXRes <= 0){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), WIA_IPS_XRES returned an invalid value (%d)",lXRes));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
if(lYRes <= 0){
|
|
DBG_ERR(("CWiaScannerDS::GetImageLayout(), WIA_IPS_YRES returned an invalid value (%d)",lYRes));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
pImageLayout->Frame.Top = FloatToFix32((float)((float)lYPos/(float)lYRes));
|
|
pImageLayout->Frame.Left = FloatToFix32((float)((float)lXPos/(float)lXRes));
|
|
pImageLayout->Frame.Right = FloatToFix32((float)((float)lXExtent/(float)lXRes));
|
|
pImageLayout->Frame.Bottom = FloatToFix32((float)((float)lYExtent/(float)lYRes));
|
|
} else {
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
if(m_bUnknownPageLength){
|
|
DBG_WRN(("CWiaScannerDS::GetImageLayout(), ImageLayout is does not make since when using a UnknownPageLength Device"));
|
|
return TWRC_CHECKSTATUS;
|
|
}
|
|
return TWRC_SUCCESS;
|
|
}
|
|
TW_UINT16 CWiaScannerDS::GetResolutions()
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::GetResolutions());
|
|
HRESULT hr = S_OK;
|
|
CWiahelper WIA;
|
|
hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to set IWiaItem for property reading"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
TW_UINT16 twRc = TWRC_FAILURE;
|
|
TW_RANGE twOptionalYRange;
|
|
memset(&twOptionalYRange,0,sizeof(twOptionalYRange));
|
|
TW_UINT32 *pOptionalYResArray = NULL;
|
|
TW_UINT32 OptionalYResNumValues = 0;
|
|
BOOL bOptionalYResRange = FALSE;
|
|
|
|
PROPVARIANT pv;
|
|
memset(&pv,0,sizeof(pv));
|
|
LONG lAccessFlags = 0;
|
|
hr = WIA.ReadPropertyAttributes(WIA_IPS_XRES,&lAccessFlags,&pv);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// collect valid values for X resolutions
|
|
//
|
|
|
|
CCap *pCap = FindCap(ICAP_XRESOLUTION);
|
|
if (pCap) {
|
|
if (lAccessFlags & WIA_PROP_RANGE) {
|
|
twRc = pCap->Set((TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_MIN],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_MAX],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_STEP]); // range
|
|
//
|
|
// save X resolution values in RANGE form (just in case the Y
|
|
// resolution is WIA_PROP_NONE)
|
|
//
|
|
|
|
twOptionalYRange.ItemType = TWTY_UINT32;
|
|
twOptionalYRange.CurrentValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM];
|
|
twOptionalYRange.DefaultValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM];
|
|
twOptionalYRange.MinValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_MIN];
|
|
twOptionalYRange.MaxValue = (TW_UINT32)pv.caul.pElems[WIA_RANGE_MAX];
|
|
twOptionalYRange.StepSize = (TW_UINT32)pv.caul.pElems[WIA_RANGE_STEP];
|
|
|
|
bOptionalYResRange = TRUE;
|
|
|
|
} else if (lAccessFlags & WIA_PROP_LIST) {
|
|
TW_UINT32 *pResArray = new TW_UINT32[WIA_PROP_LIST_COUNT(&pv)];
|
|
if (pResArray) {
|
|
memset(pResArray,0,(sizeof(TW_UINT32)*WIA_PROP_LIST_COUNT(&pv)));
|
|
pOptionalYResArray = new TW_UINT32[WIA_PROP_LIST_COUNT(&pv)];
|
|
if (pOptionalYResArray) {
|
|
memset(pOptionalYResArray,0,(sizeof(TW_UINT32)*WIA_PROP_LIST_COUNT(&pv)));
|
|
for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
|
|
pResArray[i] = (TW_UINT32)pv.caul.pElems[i+2];
|
|
|
|
//
|
|
// save the X resolution values in LIST form (just in case the Y
|
|
// resolution is WIA_PROP_NONE)
|
|
//
|
|
|
|
pOptionalYResArray[i] = (TW_UINT32)pv.caul.pElems[i+2];
|
|
}
|
|
|
|
//
|
|
// save the number of X resolutions saved
|
|
//
|
|
|
|
OptionalYResNumValues = (TW_UINT32)WIA_PROP_LIST_COUNT(&pv);
|
|
|
|
twRc = pCap->Set(0,0,WIA_PROP_LIST_COUNT(&pv),(BYTE*)pResArray,TRUE); // list
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to allocate optional Y Resolution Array Memory"));
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
|
|
delete [] pResArray;
|
|
pResArray = NULL;
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to allocate X Resolution Array Memory"));
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
} else if (lAccessFlags & WIA_PROP_NONE) {
|
|
|
|
//
|
|
// we are a "real" WIA_PROP_NONE value
|
|
//
|
|
|
|
LONG lCurrentValue = 0;
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_XRES,&lCurrentValue);
|
|
if (SUCCEEDED(hr)) {
|
|
TW_UINT32 OneValueArray[1];
|
|
OneValueArray[0] = (TW_UINT32)lCurrentValue;
|
|
twRc = pCap->Set(0,0,1,(BYTE*)OneValueArray,TRUE); // list
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read X Resolution current value"));
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
|
|
PropVariantClear(&pv);
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read WIA_IPS_XRES attributes"));
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
|
|
if (TWRC_SUCCESS == twRc) {
|
|
memset(&pv,0,sizeof(pv));
|
|
lAccessFlags = 0;
|
|
hr = WIA.ReadPropertyAttributes(WIA_IPS_YRES,&lAccessFlags,&pv);
|
|
if (SUCCEEDED(hr)) {
|
|
|
|
//
|
|
// collect valid values for Y resolutions
|
|
//
|
|
|
|
CCap *pCap = FindCap(ICAP_YRESOLUTION);
|
|
if (pCap) {
|
|
if (lAccessFlags & WIA_PROP_RANGE) {
|
|
twRc = pCap->Set((TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_NOM],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_MIN],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_MAX],
|
|
(TW_UINT32)pv.caul.pElems[WIA_RANGE_STEP]); // range
|
|
} else if (lAccessFlags & WIA_PROP_LIST) {
|
|
TW_UINT32 *pResArray = new TW_UINT32[WIA_PROP_LIST_COUNT(&pv)];
|
|
if (pResArray) {
|
|
memset(pResArray,0,(sizeof(TW_UINT32)*WIA_PROP_LIST_COUNT(&pv)));
|
|
for (ULONG i = 0; i < WIA_PROP_LIST_COUNT(&pv);i++) {
|
|
pResArray[i] = (TW_UINT32)pv.caul.pElems[i+2];
|
|
}
|
|
|
|
twRc = pCap->Set(0,0,WIA_PROP_LIST_COUNT(&pv),(BYTE*)pResArray,TRUE); // list
|
|
delete [] pResArray;
|
|
pResArray = NULL;
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to allocate Y Resolution Array Memory"));
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
} else if (lAccessFlags & WIA_PROP_NONE) {
|
|
|
|
if (pOptionalYResArray) {
|
|
|
|
//
|
|
// if we have an optional array allocated, then X Resolution must be in
|
|
// array form, so match it.
|
|
//
|
|
|
|
twRc = pCap->Set(0,0,OptionalYResNumValues,(BYTE*)pOptionalYResArray,TRUE); // list
|
|
|
|
} else if (bOptionalYResRange) {
|
|
|
|
//
|
|
// if the RANGE flag is set to TRUE, then X Resolution must be in range form, so match it.
|
|
//
|
|
|
|
twRc = pCap->Set(twOptionalYRange.DefaultValue,
|
|
twOptionalYRange.CurrentValue,
|
|
twOptionalYRange.MinValue,
|
|
twOptionalYRange.MaxValue,
|
|
twOptionalYRange.StepSize); // range
|
|
|
|
} else {
|
|
|
|
//
|
|
// we are a "real" WIA_PROP_NONE value
|
|
//
|
|
|
|
LONG lCurrentValue = 0;
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YRES,&lCurrentValue);
|
|
if (SUCCEEDED(hr)) {
|
|
TW_UINT32 OneValueArray[1];
|
|
OneValueArray[0] = (TW_UINT32)lCurrentValue;
|
|
twRc = pCap->Set(0,0,1,(BYTE*)OneValueArray,TRUE); // list
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read Y Resolution current value"));
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
PropVariantClear(&pv);
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::GetResolutions(), failed to read WIA_IPS_YRES attributes"));
|
|
twRc = TWRC_FAILURE;
|
|
}
|
|
}
|
|
|
|
if (pOptionalYResArray) {
|
|
delete [] pOptionalYResArray;
|
|
pOptionalYResArray = NULL;
|
|
}
|
|
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::GetSettings()
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::GetSettings());
|
|
TW_UINT16 twRc = TWRC_SUCCESS;
|
|
twRc = GetImageLayout(&m_CurImageLayout);
|
|
if (TWRC_SUCCESS == twRc) {
|
|
twRc = GetResolutions();
|
|
}
|
|
return twRc;
|
|
}
|
|
|
|
TW_UINT16 CWiaScannerDS::SetSettings(CCap *pCap)
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::SetSettings());
|
|
HRESULT hr = S_OK;
|
|
LONG lValue = 0;
|
|
CWiahelper WIA;
|
|
IWiaItem *pIRootItem = NULL;
|
|
hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::SetSettings(), failed to set IWiaItem for property reading"));
|
|
}
|
|
|
|
//
|
|
// determine if it is a Capability that the device really needs to know
|
|
// about.
|
|
//
|
|
|
|
switch (pCap->GetCapId()) {
|
|
case CAP_FEEDERENABLED:
|
|
DBG_TRC(("CWiaScannerDS::SetCommonSettings(CAP_FEEDERENABLED)"));
|
|
lValue = (LONG)pCap->GetCurrent();
|
|
if(lValue){
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), Setting FEEDER mode"));
|
|
lValue = FEEDER;
|
|
} else {
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), Setting FLATBED mode Enabled"));
|
|
lValue = FLATBED;
|
|
}
|
|
hr = m_pCurrentIWiaItem->GetRootItem(&pIRootItem);
|
|
if(S_OK == hr){
|
|
hr = WIA.SetIWiaItem(pIRootItem);
|
|
if(SUCCEEDED(hr)){
|
|
|
|
//
|
|
// read current document handling select setting
|
|
//
|
|
|
|
LONG lCurrentDocumentHandlingSelect = 0;
|
|
hr = WIA.ReadPropertyLong(WIA_DPS_DOCUMENT_HANDLING_SELECT,&lCurrentDocumentHandlingSelect);
|
|
if(lValue == FEEDER){
|
|
lCurrentDocumentHandlingSelect &= ~FLATBED;
|
|
} else {
|
|
lCurrentDocumentHandlingSelect &= ~FEEDER;
|
|
}
|
|
|
|
//
|
|
// add the intended settings, and write them to the WIA device
|
|
//
|
|
|
|
lValue = lValue | lCurrentDocumentHandlingSelect;
|
|
hr = WIA.WritePropertyLong(WIA_DPS_DOCUMENT_HANDLING_SELECT,lValue);
|
|
|
|
if(SUCCEEDED(hr)){
|
|
|
|
//
|
|
// adjust ICAP_PHYSICALWIDTH and ICAP_PHYSICALHEIGHT
|
|
//
|
|
|
|
LONG lWidth = 0;
|
|
LONG lHeight = 0;
|
|
TW_UINT32 Value = 0;
|
|
CCap* pPhysicalCap = NULL;
|
|
TW_FIX32 fix32;
|
|
memset(&fix32,0,sizeof(fix32));
|
|
|
|
if(lValue & FEEDER){
|
|
|
|
//
|
|
// read current horizontal sheet feeder size
|
|
//
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_DPS_HORIZONTAL_SHEET_FEED_SIZE,&lWidth);
|
|
|
|
} else {
|
|
|
|
//
|
|
// read current horizontal bed size
|
|
//
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_DPS_HORIZONTAL_BED_SIZE,&lWidth);
|
|
|
|
}
|
|
|
|
if(SUCCEEDED(hr)){
|
|
|
|
//
|
|
// find the TWAIN capability ICAP_PHYSICALWIDTH
|
|
//
|
|
|
|
pPhysicalCap = FindCap(ICAP_PHYSICALWIDTH);
|
|
if(pPhysicalCap){
|
|
|
|
//
|
|
// set the current value, by reading the current setting from
|
|
// the WIA property WIA_DPS_HORIZONTAL_SHEET_FEED_SIZE and
|
|
// dividing by 1000.0 (because WIA units are in 1/1000th of
|
|
// an inch)
|
|
//
|
|
|
|
memset(&fix32,0,sizeof(fix32));
|
|
fix32 = FloatToFix32((FLOAT)(lWidth / 1000.00));
|
|
memcpy(&Value, &fix32, sizeof(TW_UINT32));
|
|
if(TWRC_SUCCESS == pPhysicalCap->Set(Value, Value, Value, Value)){
|
|
|
|
//
|
|
// if setting the new ICAP_PHYSICALWIDTH was successful, continue
|
|
// and attempt to set the ICAP_PHYSICALHEIGHT
|
|
//
|
|
|
|
if(lValue & FEEDER){
|
|
|
|
//
|
|
// read current vertical sheet feeder size
|
|
//
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_DPS_VERTICAL_SHEET_FEED_SIZE,&lHeight);
|
|
} else {
|
|
|
|
//
|
|
// read current vertical bed size
|
|
//
|
|
|
|
hr = WIA.ReadPropertyLong(WIA_DPS_VERTICAL_BED_SIZE,&lHeight);
|
|
}
|
|
|
|
if (S_OK == hr){
|
|
|
|
//
|
|
// if the setting was successful, continue to attempt to set
|
|
// ICAP_PHYSICALHEIGHT setting.
|
|
//
|
|
|
|
pPhysicalCap = FindCap(ICAP_PHYSICALHEIGHT);
|
|
if (pPhysicalCap){
|
|
|
|
//
|
|
// set the current value, by reading the current setting from
|
|
// the WIA property WIA_DPS_VERTICAL_SHEET_FEED_SIZE and
|
|
// dividing by 1000.0 (because WIA units are in 1/1000th of
|
|
// an inch)
|
|
//
|
|
|
|
memset(&fix32,0,sizeof(fix32));
|
|
fix32 = FloatToFix32((FLOAT)(lHeight / 1000.00));
|
|
memcpy(&Value, &fix32, sizeof(TW_UINT32));
|
|
if (TWRC_SUCCESS != pPhysicalCap->Set(Value, Value, Value, Value)){
|
|
DBG_WRN(("CWiaScannerDS::SetSettings(), could not update TWAIN ICAP_PHYSICALHEIGHT settings"));
|
|
}
|
|
}
|
|
} else {
|
|
|
|
//
|
|
// allow this to pass, because we are either dealing with a "unknown length"
|
|
// device and it can not tell us the height, or the driver can not give us this
|
|
// value at this time.. (this is OK, because this setting is not fully needed for
|
|
// proper data transfers.) Worst case scenerio: The TWAIN compat layer will
|
|
// report the same height as the flatbed for the new ICAP_PHYSICALHEIGHT value.
|
|
//
|
|
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::SetSettings(), could not find ICAP_PHYSICALHEIGHT capability"));
|
|
}
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::SetSettings(), failed to read physical sheet feeder size settings"));
|
|
}
|
|
}
|
|
}
|
|
pIRootItem->Release();
|
|
}
|
|
break;
|
|
case ICAP_XRESOLUTION:
|
|
DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_XRESOLUTION)"));
|
|
lValue = (LONG)pCap->GetCurrent();
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), Setting X Resolution to %d",lValue));
|
|
hr = WIA.WritePropertyLong(WIA_IPS_XRES,lValue);
|
|
break;
|
|
case ICAP_YRESOLUTION:
|
|
DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_YRESOLUTION)"));
|
|
lValue = (LONG)pCap->GetCurrent();
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), Setting Y Resolution to %d",lValue));
|
|
hr = WIA.WritePropertyLong(WIA_IPS_YRES,lValue);
|
|
break;
|
|
case ICAP_BRIGHTNESS:
|
|
DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_BRIGHTNESS)"));
|
|
lValue = (LONG)pCap->GetCurrent();
|
|
// to do: convert -1000 to 1000 range value in the range specified by the WIA driver
|
|
// and set that to lValue.
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), Setting WIA_IPS_BRIGHTNESS to %d",lValue));
|
|
break;
|
|
case ICAP_CONTRAST:
|
|
DBG_TRC(("CWiaScannerDS::SetCommonSettings(ICAP_CONTRAST)"));
|
|
lValue = (LONG)pCap->GetCurrent();
|
|
// to do: convert -1000 to 1000 range value in the range specified by the WIA driver
|
|
// and set that to lValue.
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), Setting WIA_IPS_CONTRAST to %d",lValue));
|
|
break;
|
|
default:
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), data source is not setting CAPID = %x to WIA device (it is not needed)",pCap->GetCapId()));
|
|
break;
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
DBG_TRC(("CWiaScannerDS::SetSettings(), Settings were successfully sent to WIA device"));
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::SetSettings(), Settings were unsuccessfully sent to WIA device"));
|
|
return TWRC_FAILURE;
|
|
}
|
|
|
|
return TWRC_SUCCESS;
|
|
}
|
|
|
|
BOOL CWiaScannerDS::IsUnknownPageLengthDevice()
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::IsUnknownPageLengthDevice());
|
|
HRESULT hr = S_OK;
|
|
BOOL bIsUnknownPageLengthDevice = FALSE;
|
|
CWiahelper WIA;
|
|
hr = WIA.SetIWiaItem(m_pCurrentIWiaItem);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::IsUnknownPageLengthDevice(), failed to set IWiaItem for property reading"));
|
|
return FALSE;
|
|
}
|
|
|
|
LONG lYExtent = 0;
|
|
hr = WIA.ReadPropertyLong(WIA_IPS_YEXTENT,&lYExtent);
|
|
if(FAILED(hr)){
|
|
DBG_ERR(("CWiaScannerDS::IsUnknownPageLengthDevice(), failed to read WIA_IPS_YEXTENT"));
|
|
}
|
|
|
|
if(SUCCEEDED(hr)){
|
|
if(S_FALSE == hr){ // property does not exist, so we have to support this feature
|
|
bIsUnknownPageLengthDevice = TRUE;
|
|
} else if(S_OK == hr){ // property exists, (need more information, so check the current value)
|
|
if(lYExtent == 0){ // property is set to 0, which means unknown page length is supported
|
|
bIsUnknownPageLengthDevice = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bIsUnknownPageLengthDevice){
|
|
DBG_TRC(("CWiaScannerDS::IsUnknownPageLengthDevice(), device is set to do unknown page length"));
|
|
} else {
|
|
DBG_TRC(("CWiaScannerDS::IsUnknownPageLengthDevice(), device is not set to do unknown page length"));
|
|
}
|
|
|
|
return bIsUnknownPageLengthDevice;
|
|
}
|
|
|
|
BOOL CWiaScannerDS::IsFeederEnabled()
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::IsFeederEnabled());
|
|
HRESULT hr = S_OK;
|
|
BOOL bIsFeederEnabled = FALSE;
|
|
LONG lDocumentHandlingSelect = 0;
|
|
CWiahelper WIA;
|
|
IWiaItem *pIRootItem = NULL;
|
|
hr = m_pCurrentIWiaItem->GetRootItem(&pIRootItem);
|
|
if (SUCCEEDED(hr)) {
|
|
if (NULL != pIRootItem) {
|
|
hr = WIA.SetIWiaItem(pIRootItem);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::IsFeederEnabled(), failed to set IWiaItem for property reading"));
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
hr = WIA.ReadPropertyLong(WIA_DPS_DOCUMENT_HANDLING_SELECT,&lDocumentHandlingSelect);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::IsFeederEnabled(), failed to read WIA_DPS_DOCUMENT_HANDLING_SELECT"));
|
|
}
|
|
|
|
if (S_OK == hr) {
|
|
if ((lDocumentHandlingSelect & FEEDER) == FEEDER) {
|
|
bIsFeederEnabled = TRUE;
|
|
}
|
|
} else if (S_FALSE == hr) {
|
|
DBG_WRN(("CWiaScannerDS::IsFeederEnabled(), WIA_DPS_DOCUMENT_HANDLING_SELECT was not found...defaulting to FLATBED"));
|
|
}
|
|
}
|
|
|
|
pIRootItem->Release();
|
|
pIRootItem = NULL;
|
|
}
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::IsFeederEnabled(), failed to get ROOT IWiaItem from current IWiaItem"));
|
|
}
|
|
return bIsFeederEnabled;
|
|
}
|
|
|
|
BOOL CWiaScannerDS::IsFeederEmpty()
|
|
{
|
|
DBG_FN_DS(CWiaScannerDS::IsFeederEmpty());
|
|
HRESULT hr = S_OK;
|
|
BOOL bIsFeederEmpty = TRUE;
|
|
LONG lDocumentHandlingStatus = 0;
|
|
CWiahelper WIA;
|
|
IWiaItem *pIRootItem = NULL;
|
|
hr = m_pCurrentIWiaItem->GetRootItem(&pIRootItem);
|
|
if (SUCCEEDED(hr)) {
|
|
if (NULL != pIRootItem) {
|
|
hr = WIA.SetIWiaItem(pIRootItem);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::IsFeederEmpty(), failed to set IWiaItem for property reading"));
|
|
}
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
hr = WIA.ReadPropertyLong(WIA_DPS_DOCUMENT_HANDLING_STATUS,&lDocumentHandlingStatus);
|
|
if (FAILED(hr)) {
|
|
DBG_ERR(("CWiaScannerDS::IsFeederEmpty(), failed to read WIA_DPS_DOCUMENT_HANDLING_STATUS"));
|
|
}
|
|
|
|
if (S_OK == hr) {
|
|
if (lDocumentHandlingStatus & FEED_READY) {
|
|
bIsFeederEmpty = FALSE;
|
|
}
|
|
} else if (S_FALSE == hr) {
|
|
DBG_WRN(("CWiaScannerDS::IsFeederEmpty(), WIA_DPS_DOCUMENT_HANDLING_STATUS was not found"));
|
|
}
|
|
}
|
|
|
|
pIRootItem->Release();
|
|
pIRootItem = NULL;
|
|
}
|
|
} else {
|
|
DBG_ERR(("CWiaScannerDS::IsFeederEmpty(), failed to get ROOT IWiaItem from current IWiaItem"));
|
|
}
|
|
return bIsFeederEmpty;
|
|
}
|
|
|