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. |