| 
   Available in LEADTOOLS Imaging Pro, Vector, Document, and Medical Imaging toolkits.  | 
Note: The purpose of this TWAIN tutorial is to provide you a quick and easy way to generate a TWAIN program. For more in depth TWAIN programming, refer to the TWAIN demo.
To create and run a program that implements LEADTOOLS TWAIN Duplex features:
| 
 1.  | 
 Create a new directory in the \Examples\CDLL directory called TwainDuplex  | 
| 
 2.  | 
 Copy everything in the SimpleLoad directory into the TwainDuplex directory.  | 
| 
 3.  | 
 Compile the project as it is and run SimpleLoad.exe to familiarize yourself with the basic program.  | 
| 
 4.  | 
 In the Imports.cpp, add the following lines:  | 
#if defined(WIN64)
…
…
#else
…
…
#pragma comment(lib, "..\\..\\..\\Lib"L_VER_DESIGNATOR"\\CDLL\\Win32\\Lttwn_u.lib")
#endif // #if defined(WIN64)
| 
 5.  | 
 Add the following line in StdAfx.h in the TwainDuplex directory:  | 
#include "..\..\..\include\lttwn.h"
| 
 6.  | 
 Define the following global variables in Ezfunc.h in the TwainDuplex directory:  | 
HTWAINSESSION hSession;
Also, add the following defines:
#define IDM_ACQUIRE 200
| 
 7.  | 
 Edit EZFUNC.RC file in the TwainCap directory and add the following lines:  | 
#include "EZFUNC.H"
MAIN_MENU MENU
BEGIN
MENUITEM "Acquire" IDM_ACQUIRE
END
| 
 8.  | 
 In the InitApplication function change the line:  | 
wcWindowClass.lpszMenuName = NULL;  /* No menu */
to be
wcWindowClass.lpszMenuName = TEXT("MAIN_MENU");
| 
 9.  | 
 In the MainWndProc function and before the handling of the WM_PALETTECHANGED message add the following code:  | 
   case WM_COMMAND: 
      {
         switch (LOWORD(wParam)) 
         {
         case IDM_ACQUIRE: 
            {
            }
            break; 
         }
      }
      break;
| 
 10.  | 
 In the IDM_ACQUIRE menu handler add the following code:  | 
         case IDM_ACQUIRE: 
            {
               TwainTestDuplex(hWnd); 
            }
| 
 11.  | 
 Add the following function to the EZFUNC.CPP:  | 
L_INT EXT_CALLBACK TwainAcquireCB(HTWAINSESSION hSession, 
 pBITMAPHANDLE pBitmap, L_VOID * pUserData) 
{
   UNREFERENCED_PARAMETER(hSession);
UNREFERENCED_PARAMETER(pBitmap);
UNREFERENCED_PARAMETER(pUserData);
if (LeadBitmap.Flags.Allocated)
L_FreeBitmap(&LeadBitmap);
L_CopyBitmap(&LeadBitmap, pBitmap, sizeof(BITMAPHANDLE));
L_FreeBitmap(pBitmap);
   return SUCCESS; 
}
| 
 12.  | 
 Add the following function to the EZFUNC.CPP after the TwainAcquireCB function:  | 
void TwainTestDuplex(HWND hWnd) 
{
   HTWAINSESSION hSession; 
   APPLICATIONDATA AppData; 
   L_INT nRet; 
   TW_CAPABILITY twCap; 
   memset(&AppData, 0, sizeof(APPLICATIONDATA)); 
   AppData.hWnd = hWnd; 
   lstrcpy (AppData.szManufacturerName, TEXT("LEAD Technologies, Inc.")); 
   lstrcpy (AppData.szAppProductFamily, TEXT("LEAD Sample"));
   lstrcpy (AppData.szVersionInfo,      TEXT("Version 1.0"));
   lstrcpy (AppData.szAppName,          TEXT("LEAD Sample"));
   AppData.uStructSize = sizeof(APPLICATIONDATA); 
   nRet = L_TwainInitSession(&hSession, &AppData); 
   if (nRet != TWAIN_SUCCESS) 
      return; 
   L_TwainSelectSource(hSession, NULL);
   L_TwainStartCapsNeg(hSession); 
   twCap.Cap = CAP_DUPLEX; 
   twCap.ConType = TWON_ONEVALUE; 
   twCap.hContainer = NULL; 
   nRet = L_TwainGetCapability(hSession, &twCap, LTWAIN_CAPABILITY_GETVALUES); 
   if (nRet == TWAIN_SUCCESS) 
   {
      // check if the selected driver supports duplex capability
      pTW_ONEVALUE pOneValue = (pTW_ONEVALUE)GlobalLock(twCap.hContainer); 
      if (pOneValue->ItemType != TWTY_UINT16) 
      {
         GlobalUnlock(twCap.hContainer); 
         L_TwainFreeContainer(&twCap); 
         L_TwainEndCapsNeg(hSession); 
         L_TwainEndSession(&hSession); 
         return; 
      }
      TW_UINT16 item = (TW_UINT16)pOneValue->Item; 
      switch (item) 
      {
      case TWDX_NONE: 
         MessageBox(hWnd, TEXT("Duplex capability is not supported in the selected driver"), TEXT("Notice"), MB_OK); 
         break; 
      case TWDX_1PASSDUPLEX: 
         MessageBox(hWnd, TEXT("1 Pass Duplex capability is supported in the selected driver"), TEXT("Notice"), MB_OK); 
         break; 
      case TWDX_2PASSDUPLEX: 
         MessageBox(hWnd, TEXT("2 Pass Duplex capability is supported in the selected driver"), TEXT("Notice"), MB_OK); 
         break; 
      }
      GlobalUnlock(twCap.hContainer); 
      L_TwainFreeContainer(&twCap); 
      // make sure the duplex capability is enabled
      if (item != TWDX_NONE) 
      {
         BOOL bEnable = TRUE; 
         twCap.Cap = CAP_DUPLEXENABLED; 
         twCap.ConType = TWON_ONEVALUE; 
         twCap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE)); 
         pTW_ONEVALUE pOneValue = (pTW_ONEVALUE)GlobalLock(twCap.hContainer); 
         pOneValue->ItemType = TWTY_BOOL; 
         pOneValue->Item = (TW_UINT32)bEnable; 
         GlobalUnlock(twCap.hContainer); 
         nRet = L_TwainSetCapability(hSession, &twCap, LTWAIN_CAPABILITY_SET); 
         if (nRet == TWAIN_SUCCESS) 
            MessageBox(hWnd, TEXT("The duplex capability is enabled"), TEXT("Notice"), MB_OK); 
         else
            MessageBox(hWnd, TEXT("Can't enable duplex capability"), TEXT("Notice"), MB_OK); 
      }
   }
   else
      MessageBox(hWnd, TEXT("Duplex capability is not supported in the selected driver"), TEXT("Notice"), MB_OK); 
   L_TwainEndCapsNeg(hSession); 
   // try to acquire pages using duplex capability
   L_TwainAcquire(hSession, NULL, sizeof(BITMAPHANDLE), TwainAcquireCB, LTWAIN_SHOW_USER_INTERFACE | LTWAIN_MODAL_USER_INTERFACE, NULL, NULL); 
   L_TwainEndSession(&hSession); 
}
| 
 13.  | 
 Compile and test the program.  |