If you mean the 2 sides of a scanned document when using a duplex scanner, the answer is as follows:
- To know which side of the paper is currently being processed in the bitmap callback, the following code can be used inside the callback function:
L_INT EXT_CALLBACK LTwainBitmapCallback(HTWAINSESSION hSession, pBITMAPHANDLE pBitmap, L_VOID * pUserData)
{
L_INT nRet = SUCCESS;
TW_EXTIMAGEINFO* pExtImg = NULL;
int nExtraInfoAftreZero = 0; // we have only one info, so no extra needed
pExtImg = (TW_EXTIMAGEINFO *)malloc(sizeof TW_EXTIMAGEINFO + nExtraInfoAftreZero * sizeof TW_INFO);
if (pExtImg)
{
pExtImg->NumInfos = 1;
pExtImg->Info[0].InfoID = TWEI_PAGESIDE;
pExtImg->Info[0].ItemType = TWTY_UINT16;
nRet = L_TwainGetExtendedImageInfo (hSession, pExtImg);
if (nRet == SUCCESS)
{
// Do processing to returned values
if(pExtImg->Info[0].Item == TWCS_TOP)
OutputDebugString("Front of sheet.\n");
else if (pExtImg->Info[0].Item == TWCS_BOTTOM)
OutputDebugString("Rear of sheet.\n");
else
OutputDebugString("Unexpected!\n");
nRet = L_TwainFreeExtendedImageInfoStructure (&pExtImg);
if(nRet != SUCCESS)
return nRet;
}
free(pExtImg);
}
return SUCCESS;
}
- Forcing a specific side to scan can be done using a combination of CAP_CAMERASIDE and CAP_CAMERAENABLED capabilities, as explained in the Twain Spec.
Quoting from that document:
To enable bottom only scanning, set CAP_CAMERASIDE to TWCS_BOTTOM and
set CAP_CAMERAENABLED to TRUE, then set CAP_CAMERASIDE to TWCS_TOP and
set CAP_CAMERAENABLED to FALSE.
If you mean you have a computer with 2 Twain camera sources (back and front), the answer becomes as follows:
- To know which Twain source (e.g. camera) triggered the Twain Bitmap Callback when
L_TwainAcquire()
was called, you can use the
L_TwainGetSources()
function with the LTWAIN_SOURCE_ENUMERATE_DEFAULT
flag to get the currently-selected Twain device. This can be done inside the Bitmap Callback as shown in the following code:
// Source Info Callback
L_INT EXT_CALLBACK TwainSourceInfoCallbackCurrent(HTWAINSESSION hSession, pLTWAINSOURCEINFO pSourceInfo, L_VOID * pUserData)
{
strcpy((L_CHAR *)pUserData, pSourceInfo->pszTwnSourceName);
return SUCCESS;
}
// Twain Bitmap Callback
L_INT EXT_CALLBACK LTwainBitmapCallback(HTWAINSESSION hSession, pBITMAPHANDLE pBitmap, L_VOID * pUserData)
{
char szSourceName[1024];
L_TwainGetSources(hSession, TwainSourceInfoCallbackCurrent, sizeof LTWAINSOURCEINFO, LTWAIN_SOURCE_ENUMERATE_DEFAULT, szSourceName);
// Now szSourceName contains name of Twain Source.
return SUCCESS;
}
- Yes, you can force scanning from a specific device (scanner, camera, etc.) by sending its name to the
L_TwainSelectSource()
function before scanning, as follows:
LTWAINSOURCE TwainSource;
TwainSource.uStructSize = sizeof LTWAINSOURCE;
TwainSource.pszTwainSourceName = pszRearCameraTwainSourceName;
L_TwainSelectSource(twainSession, &TwainSource);
// Now L_TwainAcquire() will capture from Rear Camera
To find the name of all devices, you can use this code:
L_TwainGetSources(twainSession, TwainSourceInfoCallback, sizeof LTWAINSOURCEINFO, LTWAIN_SOURCE_ENUMERATE_ALL, NULL);
The Source Info Callback will be triggered once for each Twain source. It can be implemented like this:
L_INT EXT_CALLBACK TwainSourceInfoCallback(HTWAINSESSION hSession, pLTWAINSOURCEINFO pSourceInfo, L_VOID * pUserData)
{
OutputDebugString(pSourceInfo->pszTwnSourceName); // You can save the names of Twain Sources into global variables if you like
OutputDebugString("\n");
return SUCCESS;
}