Acquire an Image From a TWAIN Source - Windows C DLL

This tutorial shows how to acquire an image from a TWAIN source in a Windows C DLL application using the LEADTOOLS SDK.

Overview  
Summary This tutorial covers how to acquire an image from a TWAIN source in a Windows C DLL application.
Completion Time 30 minutes
Visual Studio Project Download tutorial project (19 KB)
Platform Windows C DLL Application
IDE Visual Studio 2017, 2019
Development License Download LEADTOOLS
Try it in another language

Required Knowledge

Get familiar with the basic steps of creating a project and loading/displaying images by reviewing the Add References and Set a License and Load, Display, and Save Images tutorials, before working on the Acquire an Image From a TWAIN Source - Windows C DLL tutorial.

Create the Project and Add LEADTOOLS References

Start with a copy of the project created in the Load, Display, and Save Images tutorial. If the project is not available, create it by following the steps in that tutorial.

To implement TWAIN scanning using LEADTOOLS, add the required header and library files. Open the pre-compiled header file (either pch.h or stdafx.h, depending on the version of Visual Studio used) and add the following lines:

#include "C:\LEADTOOLS22\Include\Lttwn.h" 
 
#pragma comment (lib, "C:\\LEADTOOLS22\\Lib\\CDLL\\x64\\Lttwn_x.lib") // TWAIN support 

Note

For a complete list of DLLs that are required for your application, refer to Files to be Included with your Application - C API.

Set the License File

The License unlocks the features needed for the project. It must be set before any toolkit functionality is called. For details, including tutorials for different platforms, refer to Setting a Runtime License.

There are two types of runtime licenses:

Note

Adding LEADTOOLS references and setting a license are covered in more detail in the Add References and Set a License tutorial.

Add the TWAIN Session Startup and Shutdown Code

With the project created, the references added, the license set, and the load image code added, coding can begin.

Using the Solution Explorer, navigate to the main CPP file of the project and add the following global variable near the BITMAPHANDLE declaration at the top:

HTWAINSESSION twainSession = NULL; 

Add a new case to the switch (message) statement in the WndProc() function named WM_CREATE. Add the code below to the new case to initialize the TWAIN session:

case WM_CREATE: 
   if (!L_IsTwainAvailable(hWnd)) 
   { 
      MessageBox(hWnd, TEXT("Could not initialize Twain features.\nTwain Not Available"), TEXT("Twain Tutorial"), MB_ICONERROR); 
   } 
   else 
   { 
      APPLICATIONDATA appData = { sizeof(APPLICATIONDATA), hWnd, TEXT("My Company"), TEXT("My Product"), TEXT("1.0"), TEXT("My App"), TWLG_ENGLISH_USA, TWCY_USA }; 
      L_TwainInitSession(&twainSession, &appData); 
   } 
   break; 

Modify the case that handles WM_DESTROY, in the WndProc() function, to terminate the TWAIN session at the end of the program.

case WM_DESTROY: 
   if(twainSession) 
   { 
      L_TwainEndSession(&twainSession); 
      twainSession = NULL; 
   } 
   // Keep the rest of the code in the case unchanged 

Add the Source Selection and Image Scanning Code

In the Solution Explorer double-click the resources file (.rc) to open the Resource View. Then double-click the menu in the resources tree.

Add a new &Twain drop down menu next to the File menu. Add two menu items in the the table below to the newly-added &Twain menu.

Menu Item Text Item ID
&Select Source ID_TWAIN_SELECTSOURCE
&Acquire ID_TWAIN_ACQUIRE
Screenshot showing the window with the new menu items.

Navigate back to the WndProc function, and under the switch (wmId) statement that is below the WM_COMMAND case, add the below two new cases.

switch (wmId) 
{ 
case ID_TWAIN_SELECTSOURCE: 
   L_TwainSelectSource(twainSession, NULL); 
   break; 
case ID_TWAIN_ACQUIRE: 
   if (TwainScan(hWnd) == SUCCESS) 
      InvalidateRect(hWnd, NULL, TRUE); 
   else 
      MessageBox(hWnd, TEXT("Did not scan from Twain source. Either the user canceled or an error occurred."), TEXT("Twain Tutorial"), MB_ICONERROR); 
   break; 
   // Keep rest of the code as is 

Add a new TwainScan function, which can be placed above the WndProc function, and add the code below.

L_INT TwainScan(HWND hwnd) 
{ 
   BITMAPHANDLE bmp = { 0 }; 
   L_INT nRet = L_TwainAcquire(twainSession, &bmp, sizeof(bmp), NULL, LTWAIN_SHOW_USER_INTERFACE, NULL, NULL); 
   if (nRet != SUCCESS) 
      return nRet; 
   if (LEADBmp.Flags.Allocated) 
      L_FreeBitmap(&LEADBmp); 
   L_CopyBitmapHandle(&LEADBmp, &bmp, sizeof BITMAPHANDLE); // The data now belongs to the global bitmap 
   return SUCCESS; 
} 

Add TWAIN Capability Options

Open the Resource View and double-click the menu in the resources tree.

Add a new &Options drop down menu next to the &Twain menu. Add the three menu items in the table below to the newly-added &Options menu.

Menu Item Text Item ID
&Native ID_OPTIONS_NATIVE
&Memory ID_OPTIONS_MEMORY
&File ID_OPTIONS_FILE

Go to the WndProc function, and under the switch (wmId) statement that is below the WM_COMMAND case, add the new cases below for the new menu items.

switch (wmId) 
{ 
case ID_OPTIONS_NATIVE: 
   SetTransferMech(hWnd, TWSX_NATIVE); 
   break; 
case ID_OPTIONS_MEMORY: 
   SetTransferMech(hWnd, TWSX_MEMORY); 
   break; 
case ID_OPTIONS_FILE: 
   SetTransferMech(hWnd, TWSX_FILE); 
   break; 
// Keep rest of the code as is 

Add a new SetTransferMode function, placed above the WndProc function. This function shows how to set TWAIN capability by changing the value of the Image Transfer Mechanism capability.

void SetTransferMech(HWND hWnd, L_UINT transferMech) 
{ 
 
   // Instruct the Twain source to change transfer mode 
   TW_CAPABILITY twSetCap; 
   twSetCap.Cap = ICAP_XFERMECH; 
   twSetCap.ConType = TWON_ONEVALUE; 
   L_TwainStartCapsNeg(twainSession); 
   L_TwainCreateNumericContainerOneValue(&twSetCap, TWAINNUMERICTYPE_TW_UINT16, transferMech); 
   L_TwainSetCapability(twainSession, &twSetCap, LTWAIN_CAPABILITY_SET); 
   L_TwainFreeContainer(&twSetCap); 
   L_TwainEndCapsNeg(twainSession); 
   CheckOptionsMenu(hWnd); 
} 

Add a new CheckOptionsMenu function above the SetTransferMode function. This new function shows how to retrieve the value of the Image Transfer Mechanism TWAIN capability and add a check mark next to the corresponding menu item.

void CheckOptionsMenu(HWND hWnd) 
{ 
   // Ask the Twain source about current transfer mode 
   TW_CAPABILITY twGetCap = { 0 }; 
   twGetCap.Cap = ICAP_XFERMECH; 
   twGetCap.ConType = TWON_ONEVALUE; 
   L_TwainStartCapsNeg(twainSession); 
   L_TwainGetCapability(twainSession, &twGetCap, LTWAIN_CAPABILITY_GETCURRENT); 
   L_UINT transferMech = -1; 
   L_TwainGetNumericContainerUINTValue(&twGetCap, 0, &transferMech); 
   L_TwainEndCapsNeg(twainSession); 
 
   UINT item = 0; 
   switch (transferMech) 
   { 
   case TWSX_NATIVE: 
      item = ID_OPTIONS_NATIVE; 
      break; 
   case TWSX_MEMORY: 
      item = ID_OPTIONS_MEMORY; 
      break; 
   case TWSX_FILE: 
      item = ID_OPTIONS_FILE; 
   } 
   HMENU menu = GetMenu(hWnd); 
   CheckMenuItem(menu, ID_OPTIONS_NATIVE, MF_UNCHECKED); 
   CheckMenuItem(menu, ID_OPTIONS_MEMORY, MF_UNCHECKED); 
   CheckMenuItem(menu, ID_OPTIONS_FILE, MF_UNCHECKED); 
   CheckMenuItem(menu, item, MF_CHECKED); 
} 

Run the Project

Run the project by pressing F5, or by selecting Debug -> Start Debugging.

If the steps were followed correctly, the application should run. For testing, follow the below instructions:

  1. Click Twain -> Select Source and select a TWAIN device.
  2. Click Twain -> Acquire to have the application scan a page.
  3. The scanned page should then be displayed in the Image Viewer.

Note

Ensure that required TWAIN drivers for the scanner are installed on the machine, which is usually installed with the scanning device.

Wrap-up

This tutorial showed how to list the available TWAIN devices and acquire a scanned image from those devices. It also covered how to use the TwainSession and TwainCapability classes.

See Also

Help Version 22.0.2021.10.18
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.

Products | Support | Contact Us | Intellectual Property Notices
© 1991-2021 LEAD Technologies, Inc. All Rights Reserved.