Home › Forums › TWAIN Classic › TW_ENUMERATION container
- This topic has 3 replies, 2 voices, and was last updated 14 years, 11 months ago by sdavi.
- AuthorPosts
Hi all,
i’m building a c++ dll wrapper around twain.
My question is related to getting capabilities.
For example, i found an example how tu unpacking certain containers for reading its contents about a specific capability.
I try to get supported values for ICAP_UNIT of mu scannet (TW-BROTHER MFC-790 CW) and i’m based on a routine founded on pag. 83 of twain 2.0 specifications document: when it tests if itemlist contains a TW_UINT16 type, it gets it so:
if (pvalEnum->ItemType == TWTY_UINT16)
{
valueU16 = ((TW_UINT16)(pvalEnum->ItemList[index*2]));
}
why “index*2”?
Its appear correct, because i get values of ICAP_UNIT capabiliry ,
with ItemList[index], i get
follow sequence:
0 – 0 – 1
instead, if i write ItemList[index*2] i get
0 – 1 – 5 (respectively TWUN_INCHES,TWUN_CENTIMETERS,TWUN_PIXELS) and its is correct.
Can someone explain this?I post entire code function:
void TwainSource::getCapability(TW_UINT16 capability)
{
TW_CAPABILITY twCap;
twCap.Cap = capability;
twCap.ConType = TWON_DONTCARE16;
twCap.hContainer=NULL;
TW_UINT16 valueU16;
TW_UINT16 index;
pTW_ONEVALUE pvalOneValue;
pTW_ENUMERATION pvalEnum;
pTW_ARRAY pvalArray;
TW_BOOL valueBool;
if(twainProcedure(&m_appId,getIdentity(),DG_CONTROL,DAT_CAPABILITY,MSG_GET,(TW_MEMREF)&twCap))
{
switch(twCap.ConType)
{
case TWON_ARRAY:
pvalArray = (pTW_ARRAY)GlobalLock(twCap.hContainer);
for (index = 0; index < pvalArray->NumItems; index++)
{
if (pvalArray->ItemType == TWTY_UINT16)
{
valueU16 = ((TW_UINT16)(pvalArray->ItemList[index*2]));
}
}
GlobalUnlock(twCap.hContainer);
break;
case TWON_ENUMERATION:
MessageBox(NULL,"TWON_ENUMERATION","OK",MB_OK);
pvalEnum = (pTW_ENUMERATION)GlobalLock(twCap.hContainer);
for (index = 0; index < pvalEnum->NumItems; index++)
{
if (pvalEnum->ItemType == TWTY_UINT16)
{
valueU16 = ((TW_UINT16)(pvalEnum->ItemList[index*2]));
}
else if (pvalEnum->ItemType == TWTY_BOOL)
{
valueBool = ((TW_BOOL*)&pvalEnum->ItemList)[index];
}
}
GlobalUnlock(twCap.hContainer);
break;
}
}
else
{
MessageBox(NULL,"FAIL","ERROR",MB_OK);
}
GlobalFree(twCap.hContainer);
}
where twainProcedure looks like this:
BOOL TwainSource::twainProcedure(pTW_IDENTITY pOrigin, pTW_IDENTITY pDest, TW_UINT32 DG, TW_UINT16 DAT, TW_UINT16 MSG, TW_MEMREF pData)
{
TW_STATUS m_status;
USHORT ret_val;
ret_val = (*m_dataSourceManagerProc)(&m_appId,pDest,DG,DAT,MSG,pData);
m_lastOperationResult->setResultCode(ret_val);
if(ret_val != TWRC_SUCCESS)
{
(*m_pDSMProc)(pOrigin,pDest,DG_CONTROL,DAT_STATUS,MSG_GET,&m_status);
m_lastOperationResult->setStatus(m_status);
if(!m_lastOperationResult->isSuccessfulTriplet())
MessageBox(NULL,m_lastOperationResult->getResultDescription(),"ERR",MB_OK);
}
return (ret_val == TWRC_SUCCESS);
}
Best regards,
Sergio[/code]Anyone out there?
The code works because ItemList is defined as an array of TW_UINT8, but an enumeration or array can store different types. In the example it is TWTY_UINT16 which is twice the size of TW_UINT8, hence the *2.
A better way would be to casting the address of ItemList to the stored type and then indexing that.case TWTY_UINT16:
valueU16 = ((pTW_UINT16)(&pvalEnum->ItemList))[index];
break;Jim Watters
Thank you, jimwatters. Solved.
Now i’d write classes (and one c++ interface) to generalize that values.
best regards
(sorry for my bad aenglish).
sdavi- AuthorPosts