Set up a TWAIN Feeder Scan

Note: The purpose of this TWAIN tutorial is to provide you with 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 Feeder features:

1.

Create a new directory in the \Examples\CDLL directory called TwainAutoFeed

2.

Copy everything in the SimpleLoad directory into the TwainAutoFeed 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\\CDLL\\Win32\\Lttwn_u.lib")
#endif // #if defined(WIN64) 
 

5.

Add the following line in StdAfx.h in the TwainAutoFeed directory:

#include "..\..\..\include\lttwn.h"

6.

Define the following global variable in Ezfunc.h in the TwainAutoFeed directory:

HTWAINSESSION hSession; 

Also, add the following defines:

#define IDM_ACQUIRE          200
#define IDM_SET_AUTOFEED     201
#define IDM_SET_FEEDER       202
#define IDM_SELECT_SOURCE    203
 

7.

Edit EZFUNC.RC file in the TwainAutoFeed directory and add the following lines:

#include "EZFUNC.H"

MAIN_MENU   MENU
BEGIN
   MENUITEM "Select Source"        IDM_SELECT_SOURCE
   MENUITEM "Set Auto Feed"        IDM_SET_AUTOFEED
   MENUITEM "Set Manual Feeder"    IDM_SET_FEEDER
   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 WM_CREATE message handler add the following code at the end (after SendMessage (hWnd, WM_QUERYNEWPALETTE, 0, 0L); ):

      APPLICATIONDATA AppData; 
      AppData.uStructSize = sizeof(APPLICATIONDATA);
      AppData.hWnd = hWnd; 
      lstrcpy (AppData.szManufacturerName, TEXT("LEAD Technologies, Inc.")); 
      lstrcpy (AppData.szAppProductFamily, TEXT("LEAD Test Applications"));
      lstrcpy (AppData.szVersionInfo, TEXT("Version 1.0"));
      lstrcpy (AppData.szAppName, TEXT("TWAIN Test Application"));
      nRet = L_TwainInitSession(&hSession, &AppData); 
      if (nRet != SUCCESS) 
         return FALSE; 

10.

In the WM_DESTROY message handler add the following code at the end (before the PostQuitMessage (0);): 

      L_TwainEndSession(&hSession); 
 

11.

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_SELECT_SOURCE: 
            {
            }
            break; 
         case IDM_SET_AUTOFEED: 
            {
            }
            break; 
         case IDM_SET_FEEDER: 
            {
            }
            break; 
         case IDM_ACQUIRE: 
            {
            }
            break; 
         }
      }
      break;

 

12.

In the IDM_SELECT_SOURCE menu handler add the following code:

         case IDM_SELECT_SOURCE:
            {
               L_TwainSelectSource(hSession, NULL); 
            }
 

13.

In the IDM_ACQUIRE menu handler add the following code:

         case IDM_ACQUIRE:
            {
               L_TwainEndCapsNeg(hSession); 

               // try to acquire pages using AutoFeed capability
               L_TwainAcquire(hSession, NULL, sizeof(BITMAPHANDLE), TwainAcquireCB, LTWAIN_SHOW_USER_INTERFACE | LTWAIN_MODAL_USER_INTERFACE, NULL, NULL); 

               L_TwainEndSession(&hSession); 
            }
 

14.

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;
}
 

15.

In the IDM_SET_AUTOFEED menu handler add the following code:

         case IDM_SET_AUTOFEED:
            {
               TW_CAPABILITY twCap;
               L_INT nRet;
               L_BOOL bEnable;

               L_TwainStartCapsNeg(hSession);

               twCap.Cap = CAP_AUTOFEED;
               twCap.ConType = TWON_ONEVALUE;
               twCap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));

               pTW_ONEVALUE pOneValue = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
               bEnable = TRUE;

               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("AutoFeed capability is enabled"), TEXT("Notice"), MB_OK);
               else
                  MessageBox(hWnd, TEXT("Can't enable AutoFeed capability"), TEXT("Notice"), MB_OK);
            }
 

16.

In the IDM_SET_FEEDER menu handler add the following code:

         case IDM_SET_FEEDER:
            {
               TW_CAPABILITY twCap;
               L_INT nRet;
               L_BOOL bEnable;

               L_TwainStartCapsNeg(hSession);

               twCap.Cap = CAP_FEEDERENABLED;
               twCap.ConType = TWON_ONEVALUE;
               twCap.hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE));

               pTW_ONEVALUE pOneValue = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
               bEnable = TRUE;

               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("CAP_FEEDERENABLED capability is enabled"), TEXT("Notice"), MB_OK);
                  L_TwainFreeContainer(&twCap);

                  // check if there is document loaded in the feeder
                  twCap.Cap = CAP_FEEDERLOADED;
                  twCap.ConType = TWON_ONEVALUE;
                  twCap.hContainer = NULL;

                  nRet = L_TwainGetCapability(hSession, &twCap, LTWAIN_CAPABILITY_GETCURRENT);
                  if (nRet == TWAIN_SUCCESS)
                  {
                     // check if the selected driver supports duplex capability
                     pOneValue = (pTW_ONEVALUE)GlobalLock(twCap.hContainer);
                     bEnable = pOneValue->Item;
                     if (bEnable)
                        MessageBox(hWnd, TEXT("There is document loaded in the feeder"), TEXT("Notice"), MB_OK);
                     else
                        MessageBox(hWnd, TEXT("There is no document loaded in the feeder"), TEXT("Notice"), MB_OK);

                     GlobalUnlock(twCap.hContainer);
                     L_TwainFreeContainer(&twCap);
                  }
               }
               else
                  MessageBox(hWnd, TEXT("Can't enable Feeder capability"), TEXT("Notice"), MB_OK);
            }
 

17.

Compile and test the program.