ObjectTWAIN™ 3.1

ActiveX Library

 

 

 

User’s Guide


 

 

Copyright © 2001, JFL Peripheral Solutions, Inc.

All rights reserved.

 

Phone: (613) 728-2521

Fax: (613) 728-4459

http://www.jflinc.com

E-mail: info@jflinc.com

 

The information contained in this manual is based on information available at the time of publication and is subject to change without notice. Accuracy and completeness are not warranted or guaranteed.

 

No part of this manual may be reproduced or transmitted in any form or by any means, including electronic medium or machine-readable form, without the express written permission of JFL Peripheral Solutions, Inc. ObjectTWAIN™ is a trademark of JFL Peripheral Solutions, Inc. Other brand or product names are trademarks of their respective holders.


 

1. Introduction.................................................................................................................. 1

2. Features........................................................................................................................ 1

3. Software Requirements............................................................................................ 2

4. ObjectTWAIN™ ActiveX Library OCX Installation.................................................... 3

5. Start Example............................................................................................................... 4

6. Programming Guide..................................................................................................... 6

6.1. ObjectTWAIN™ Acquisition Session States....................................................... 6

6.2. How To Handle Error Conditions....................................................................... 8

6.2.1. General Rules......................................................................................................................................... 8

6.2.2. Handling ObjectTWAIN™ Operation Errors....................................................................................... 8

6.2.2.1. OLE Exceptions.................................................................................................................................... 8

6.2.2.2. The GetLastError method................................................................................................................ 10

6.3. How To Select a Data Source and Open a TWAIN Session........................... 11

6.3.1. Select and use the default TWAIN Data Source....................................................... 11

6.3.2. Select and use a custom, fixed TWAIN Data Source................................................ 11

6.3.3. Use a custom select source dialog......................................................................... 12

6.4. How To Negotiate Capabilities........................................................................... 13

6.4.1. How to iterate through an enumeration, array or range of capability values.................. 14

6.4.1.1. Arrays and Enumerations of values............................................................................................... 14

6.4.1.2. Ranges of values.............................................................................................................................. 14

6.4.1.3. Example how to get the capabilities reported as supported by the Data Source................. 15

6.4.1.4. Example how to get the x-axis resolution values supported by the Data Source................. 17

6.4.2. How to set to Data Source an enumeration or array of capability values...................... 20

6.4.2.1. Use a TWContainer object returned by a GetAvailable or Get operation................................ 20

6.4.2.2. Use a new TWContainer object...................................................................................................... 20

6.5. How To Negotiate the Acquisition Frame Layout.......................................... 22

6.5.1.1. Visual Basic example....................................................................................................................... 22

6.5.1.2. Delphi 4 example.............................................................................................................................. 23

6.5.1.3. PowerBuilder example..................................................................................................................... 24

6.6. How To Start the Image Acquisition................................................................. 25

6.7. How To Handle Transferred Image Data and Other Transfer Events.... 26

6.8. How To Get Image Information.......................................................................... 29

6.9. How To Get Extended Image Information........................................................ 30

6.10. How To Use the Automatic Document Feeder............................................... 33

7. Library Reference..................................................................................................... 34

R.1. ObjectTWAIN™ ActiveX/COM Controls.............................................................. 34

R.2. Other ObjectTWAIN™ COM Controls................................................................ 35

R.3. TWControl ActiveX Control Properties......................................................... 37

R.4. TWControl ActiveX Control Basic Methods................................................... 39

R.5. TWControl ActiveX Control Defined Capability Methods........................... 46

R.6. TWControl ActiveX Events................................................................................. 63

R.6. Other ObjectTWAIN™ COM Objects Interfaces.............................................. 64

R.7. ObjectTWAIN™ COM Constant Enumerations.................................................. 66

 


 

1. Introduction

 

TWAIN provides a standard for software developers to access Image Acquisition devices including scanners, digital cameras and multi-function peripherals. The ObjectTWAIN™ ActiveX Library provides support for any Application developed in any ActiveX/COM-aware programming environment to access the entire TWAIN Application Programming Interface (API) through an easy-to-use ActiveX/COM interface. Using the ObjectTWAIN™ ActiveX an application can select, open and manage completely with minimum coding requirements and at the highest possible programmatic control TWAIN image acquisition sessions with any TWAIN-compatible Data Source deserving an image acquisition device.

 

2. Features

 

·         High level, object oriented approach to TWAIN image acquisition programming, accessible for Applications developed in any ActiveX/COM-aware programming environment such as Visual Basic®, Visual C++®, Delphi™ and PowerBuilder™.

 

·         Complete coverage of TWAIN protocol to assure access to any part of mandatory, optional or custom functionality that may be supported by a Data Source.

 

·         Fully supports high-speed production scanning.

 

·         Provides compressed and disk file image transfer capabilities even when the Data Source does not support the optional Compressed Memory Transfer or File Transfer mechanism through conversion of Native and Memory transfer modes including compressed Memory Transfers to disk file transfers. Supported software compression and file formats include JPEG Interchange Format (JFIF), Tagged Image File Format (TIFF): CCITT Group 3.1d, Group 3.2d or Group 4 compressed and multi-page.

 

·         Support for advanced TWAIN capability negotiation including support for custom capabilities and custom capability values: supports any type of defined capability operation and container type: enumeration, range, array for any type defined by TWAIN for capability values (such as boolean, frame, string, floating point). TWAIN capability containers are accessed as COM Collections.

 

·         Automatic feeder loaded detection feature: the application may run in the background and activate when the user loads the scanner’s feeder with paper.

 

 

 

 

Note:

 

ObjectTWAIN™ will not use its internal compression engine when the Data Source will support to and the application will successfully negotiate with the Data Source to deliver compressed image data. Instead ObjectTWAIN™ will use in this case the device’s hardware compression engine in order to achieve maximum transfer speed.

 


3. Software Requirements

 

·         Microsoft® Windows® 95/98/NT4/2000/XP Operating System.

 

·         ActiveX/COM aware programming environment, such as Visual Basic®, Visual C++®, Delphi™ and PowerBuilder™ (only on the development platform).

 

·         TWAIN Data Source Manager and Twunker files (TWAIN.DLL, TWAIN_32.DLL, TWUNK16/32.EXE residing in the <Windows> directory.

 

·         TWAIN Release v1.5..v1.8 compliant Data Source deserving any type of image acquisition device (scanner, digital camera, multi-function peripheral): file with extension *.DS residing in the <Windows>\TWAIN_32\ or <Windows>\TWAIN\ directory.

 

·         TWAIN Specification document (currently updated for TWAIN Release v1.8). This document is available for free download at www.twain.org. It is recommended to be used a reference for the TWAIN triplet operations and capabilities used through ObjectTWAIN™.

 

·         TWAIN.H (TWAIN API C/C++ header file): together with the TWAIN Spec this file describes all the constants defined by TWAIN (optional, not needed for Visual Basic or Delphi, may be used when using the ActiveX to develop an application using Visual C++).

 

 

Note:

 

Although ObjectTWAIN™ ActiveX redefines and may export as COM Enumerations to applications the TWAIN capability constants, because of the lack of support for these COM Enumeration objects in some programming environments (such as PowerBuilder) you may need to directly use some capability values with their numerical values. You may find these values either in the TWAIN Specification document, TWAIN.H or the reference tables in this document.

 

Example:

 

TWPT_BW is a value defined as 0 by TWAIN (TWAIN.H and TWAIN Specification). PT_BW is the related enumerated value exported by ObjectTWAIN™. PT_BW is only an alias for TWPT_BW, the numerical value is the same, 0. A Visual Basic application will call SetIPixelType(PT_BW), a Visual C++ application, if TWAIN.H is included,  will call SetIPixelType(TWPT_BW), a PowerBuilder application may call SetIPixelType(0) (if the TWPT_BW constant is not defined in the PowerBuilder application code).

 

 


4. ObjectTWAIN™ ActiveX Library OCX Installation

 

There are two different types of installations for the ObjectTWAIN™ ActiveX Library:

 

A.      On the development platform (where the application using the OCX will be compiled):

 

Execute the setup.exe installation program which comes with ObjectTWAIN™. When prompted, enter the product serial number. The OCX will be installed to the <Windows>\<System>  directory (e.g. C:\WINNT\SYSTEM32\ObjTWAIN.ocx) and will be automatically registered for application development purposes. Then you will be able to load and use the OCX in your programming environment.

 

 

IMPORTANT:

 

An application built with ObjectTWAIN™ ActiveX Library will contain in its code the run-time license for ObjectTWAIN™. You must not install the ObjectTWAIN™ OCX using the provided ObjectTWAIN installation program on the client machines where the ObjectTWAIN application will run since this will install the design-time license and will enable anyone to use the OCX on these machines to develop unauthorized ObjectTWAIN™ applications. Instead, copy ObjTWAIN.ocx and register it as described by the next paragraph.

 

 

B.      On the client platform (where the application using ObjectTWAIN™ OCX will run):

 

When installing your application, copy the ObjTWAIN.ocx file to the <Windows>\<System> directory (the directory named \SYSTEM for Win95/98 and \SYSTEM32 for WinNT) then register it like any other OCX control.

 

Usually any tool used to build the application installation package should have an option available to enable the installation script to automatically register OCX controls. If the tool you are using to build the installation package for your application does not provide this feature, you may use the Windows REGSVR32.EXE utility: you may either call it directly from the Windows Start Menu REGSVR32 or call from your installation program code the WinExec Windows API function to launch REGSVR32.EXE specifing the complete path for ObjTWAIN.ocx as parameter.


5. Start Example

 

This chapter describes the steps to develop a minimal ObjectTWAIN™ application in Visual Basic Version 6.0 to select a TWAIN Data Source and to acquire and display one image from it.

 

Step 1: Start Visual Basic. Choose New Project | Standard EXE. A project named Project1 with one form called Form1 will be displayed.

 

Step 2:  Select Project | Components and check the component called Object TWAIN ActiveX Library. If this component is not listed here this means that it was not correctly installed. Refer to the Install section about how to install and register the ObjectTWAIN™ ActiveX for design and development purposes.

 


The control shall be listed in the Toolbox list of controls (if this is not visible, select View | Toolbox) with the name TWControl and the following bitmap:

 

Step 3: Select the control and drag it on the form. A new control called TWControl1 will be created. In the properties window make sure that the NativeMemoryAsFile property is enabled, the NativeMemoryFileType property is set to 2 – DIB and the Quiet property is disabled.

 

Step 4: Add a CommandButton (named Command1) and set its caption to “&Select Source”. Double-click the button and add the following code to display the TWAIN Data Source Manager Select Source dialog:

 

Private Sub Command1_Click()

    On Error GoTo errSelectSource

    TWControl1.UserSelectSource

    Exit Sub

errSelectSource:

    MsgBox "Error on Select Source or cancel pressed"

End Sub

 

Step 5: Add another CommandButton (named Command2) and set its caption to “&Acquire”. Double click this newly added button and add the following code to open a TWAIN session with the selected Data Source and start the image acquisition. The code also sets the current value of the CAP_XFERCOUNT capability to 1 (meaning that the application is willing to transfer one image in one TWAIN session) by calling TWControl1.SetXferCount. The transfer mode used is Native. Because the TWControl.NativeMemoryAsFile property is enabled (set to True) the memory Native DIB image will be saved by ObjectTWAIN™ to a disk file. The acquisition will be done with the Data Source User Interface displayed (the parameter of StartNativeAcquisition):

 

Private Sub Command2_Click()

    On Error GoTo errAcquire

    TWControl1.OpenSession hWnd

    TWControl1.SetXferCount 1

    TWControl1.StartNativeAcquisition True

    Exit Sub

errSelectSource:

    MsgBox Err.Description

    TWControl1.CloseSession

End Sub


 

Step 6: Add a PictureBox control, named Picture1. This PictureBox control will be used to display the acquired image.

 

Step 7: Double-click the TWControl1 control and add the following code to receive the transferred image from the Data Source and display it using the PictureBox control. The acquisition will be stopped after one image transfer is completed: if the Data Source will have more images available for transfer the application (in this example) will not continue to transfer the next image:

 

Private Sub TWControl1_DoProcessNativeAsFileData(ByVal FileFormat As OBJTWAINLibCtl.tagImageFileFormat, ByVal FileName As String)

    On Error GoTo errProcessData

    Picture1.Picture = LoadPicture(FileName)

    TWControl1.StopAcquisition

    Exit Sub

errProcessData:

    MsgBox Err.Description

    TWControl1.StopAcquisition

End Sub

 

Step 8: Double-click the TWControl1 control and add the following code to handle special transfer  conditions that may appear: the user may close the Data Source UI without initiating an image transfer, the Data Source may fail the transfer because of an acquisition hardware problem or the user may simply cancel the transfer while processing. All the transferred data and transfer error notifications are signaled by ObjectTWAIN™ as ActiveX events:

 

Private Sub TWControl1_OnCancelTransfer()

    MsgBox "Transfer canceled"

    TWControl1.CloseSession

End Sub

 

Private Sub TWControl1_OnEndTransfers()

    TWControl1.CloseSession

End Sub

 

Private Sub TWControl1_OnTransferError(ByVal Error As OBJTWAINLibCtl.tagObjectTwainError, ByVal ErrorDescription As String)

    MsgBox ErrorDescription

    TWControl1.StopAcquisition

End Sub

 

Private Sub TWControl1_OnUserCloseSourceUI(ByVal CloseOK As Boolean)

    MsgBox "Source UI closed"

    TWControl1.CloseSession

End Sub

 

Step 9: Save and run the EXE application. Press Select Source to display the DSM dialog and select a Data Source. This will be the default TWAIN Data Source in the system and will be preserved across multiple TWAIN sessions until a new Source is installed or set as default. Press Acquire to start the TWAIN acquisition and transfer one image to the application. Make sure you start the scan from the Data Source User Interface: because the Data Source UI is displayed, the ‘Transfer Ready’ signal will be not triggered automatically by the Data Source.


6. Programming Guide

6.1. ObjectTWAIN™ Acquisition Session States

 

TWAIN describes seven states that exist in TWAIN sessions. ObjectTWAIN™ provides a simplified model described by only four states. The following table lists the ObjectTWAIN™ states, the relation with the TWAIN states and how the application may cause a state transition:

 

ObjectTWAIN™ State

TWAIN State(s)

ObjectTWAIN™ State Transition

0- ObjectTWAIN™ not started

1 - DSM not loaded

TO NEXT STATE:

 

Transition to next state when a TWControl is created at run time (e.g. when the form containing the control is created).

1- ObjectTWAIN™ started

 

TO DO:

 

In this state the application may enumerate the available Data Sources, get Data Source information and/or select a Data Source.

 

RESTRICTIONS:

 

In this state the application cannot do state any capability negotiation or request to start acquisition since no Data Source is yet loaded and opened.

2 - DSM loaded

3 - DSM opened

TO NEXT STATE:

 

Transition to next state when a session with a Data Source is opened  (when OpenSession is successfully executed).

 

TO PREVIOUS STATE:

 

Transition to previous state when the current instance of TWControl is destroyed.

2 – Source Session opened

 

TO DO:

 

In this state the application may do capability negotiation (see if a capability is supported, get/set capability values) and negotiate the image layout frame.

 

Note:  A single ObjectTWAIN™ application may open and manage multiple Source sessions simultaneously by using multiple TWControl instances.

4 - Source opened

TO NEXT STATE:

 

Transition to next state when the ObjectTWAIN™ acquisition is started (e.g. one of the TWControl StartXAcquisition methods is executed).

 

TO PREVIOUS STATE:

 

Transition to previous state when the current Source Session is closed (after CloseSession  is executed).

(continue on next page)


(continue from previous page)

ObjectTWAIN™ State

TWAIN State(s)

ObjectTWAIN™ State Transition

3 – Acquisition

 

TO DO:

 

In this state the application may wait to receive image data transferred from the Source and/or to be notified about special conditions that may appear during the acquisition sequence. Also the application may request non-image data (e.g. barcode data) after a transfer, ask information about the next image to be transferred and continue or stop the acquisition.

 

Note: CloseSession may be called at any time: if the acquisition is started it will first stop the acquisition then close the session.

 

RESTRICTIONS:

 

In this state the Application may not request to change any capability value unless that capability was negotiated in the previous state as extended (through Get/ SetExtendedCaps). 

5 - Source enabled

6 - Transfer ready

7 – Transferring data

TO PREVIOUS STATE:

 

Transition to previous state when the acquisition sequence is interrupted (by executing StopAcquisition) or when all the available images are transferred to application.  

 

All TWAIN operations (including Capability operations) are exposed by ObjectTWAIN™ ActiveX Library as methods of an invisible at run-time ActiveX control called TWControl. The transferred image data and the transfer errors and special conditions are signaled through TWControl ActiveX events. The ObjectTWAIN™ ActiveX Library also exposes other COM objects to wrap various TWAIN data structures (e.g. TWContainer which provides access to TWAIN TW_CAPABILITY data and capability containers such as TW_ARRAY). All COM objects exported by the Library may be accessed as OLE Automation objects.

 

In the next sections the basic application operation procedures will be explained (in the order that may appear in an ObjectTWAIN™ session). Some of the techniques described will be accompanied by code examples in Visual Basic or other programming languages.

 


6.2. How To Handle Error Conditions

 

The big part of the TWAIN API is described by the TWAIN Specification to be only optional to be implemented by Data Sources. Worst, there are few Data Sources which really correctly support correctly the minimal set of mandatory TWAIN operations and capabilities. A well designed TWAIN application must be able to identify and handle any kind of error which has occurred in a TWAIN session, and gracefully manage the session with any Data Source.

6.2.1. General Rules

 

·         The application may try to use any kind of optional TWAIN functionality but the application shall not rely on such optional TWAIN functionality to succeed and be able to transfer images from a Data Source. If the Data Source does not support an optional Transfer Mode simply switch to another mode instead of terminating the session prematurely.

 

·         Always check the result of a TWAIN operation: all TWControl methods mapped to TWAIN operations may provide two different error result handling mechanisms (see below).

 

·         It is recommended before using a capability to check if the capability is reported as supported (through GetSupportedCaps). Also, before trying to set a capability value get the values the Data Source supports for that capability. Do not assume that the Data Source will preserve current capability values across sessions.

 

·         The application may interrupt the current acquisition sequence at any time by calling TWControl.StopAcquisition. After this the application may try to start other acquisition sequence (by optionally adjusting capability values and calling one of the TWControl.StartXAcquisition methods) or terminate the entire TWAIN session (by calling TWControl.CloseSession).  It is important to know that CloseSession may be called at any time to terminate the current session: it even calls StopAcquisition automatically if needed. If no session is opened at the time CloseSession is called nothing happens.

6.2.2. Handling ObjectTWAIN™ Operation Errors

 

An application may retrieve the result of a TWControl method in two different modes:

 

·         Handling OLE Exceptions;

·         Using the TWControl.GetLastError method.

 

Each of these two methods is explained in one of the following sub-sections:

 

6.2.2.1. OLE Exceptions

 

When an error is encountered ObjectTWAIN™ (if configured appropriately) throws an exception object. The application may handle such an exception by having a try-catch exception-handling block around the failed operation call.

 

If the application does not handle one exception in its code, it is the default exception handler for the application that will handle this exception: usually this will display a message to the user and terminate the application. While such a behavior (to exit the application at the first TWAIN error encountered) may be useful in the beginning of the application development phase it shall not be used on purpose in the final version of the application: any attempt to get an unsupported capability or to set an unsupported capability value will cause an exception and will terminate the entire application instead of continuing the session and simply consider that capability or value as unsupported by the Data Source.


 

The major advantage of this method is its simplicity: the application may provide a single error-handling block for an entire sequence of TWAIN operations. The drawback would be that an exception will be thrown for every error encountered, the application will be unable to choose to continue for non-fatal errors like the one caused when the user closes the DSM Select Source dialog by pressing cancel. Using the second error handling method the application may decide for which error codes to prompt the user or execute special error action.

 

To use this mechanism the TWControl Quiet property must be disabled (set to False), either at design or run-time.

 

The following examples show how to provide a handler for an error passed by ObjectTWAIN™ as an OLE exception (the TWControl.SetFeederEnabled and SetAutoFeed methods will be used):

 

Visual Basic example:

 

Private Sub SetFeederBtn_Click()

On Error GoTo errSetFeeder

    If TWControl.GetState <> OPENED Then

        MsgBox "No session opened"

        Exit Sub

    End If

    TWControl.SetFeederEnabled True

    TWControl.SetAutoFeed True

    Exit Sub

errSetFeeder:

    MsgBox Err.Description

End Sub

 

Delphi 3 example:

 

try

    TWControl.SetFeederEnabled(True);

    TWControl.SetAutoFeed(True);

except

    Application.MessageBox('SetADF Error', 'Scan', MB_YESNO)

end;

 

Visual C++ example:

 

try

{

    m_twControl.SetFeederEnabled(TRUE);

    m_twControl.SetAutoFeed(TRUE);

}

catch(COleDispatchException *error)

{

    AfxMessageBox(error->m_strDescription);

}


 

6.2.2.2. The GetLastError method

 

ObjectTWAIN™ provides an alternate method to retrieve result codes by using a special TWControl method named GetLastError. This method will return the status of the last TWAIN operation executed. This method may be especially useful when the application development environment or programming language does not support an exception handling mechanism.

 

To use this mechanism the TWControl Quiet property must be enabled (set to True), either at design or run-time. When the Quiet property is enabled, ObjectTWAIN™ does not throw an OLE exception when an error is encountered.

 

Visual Basic example:

 

TWControl.SetFeederEnabled True

If OBJTWAIN_NO_ERROR <> TWControl.GetLastError Then

    MsgBox "SetFeederEnabled failed"

End If

 

Delphi 3 example:

 

//TWError : tagObjectTwainError;

 

TWControl1.SetFeederEnabled(True);

TWError := TWControl.GetLastError();

if TWError <> OBJTWAIN_NO_ERROR then

    Application.MessageBox('SetFeederEnabled failed',

        'Error', MB_ICONSTOP)

 

PowerBuilder example:

 

integer result = 0

 

this.object.SetFeederEnabled(True)

result = this.object.GetLastError

if (512 <> result) then //512 is OBJTWAIN_NO_ERROR

    MessageBox("SetFeederEnabled failed", "Error")

end if

 

 

 

Note:

 

You may see the values defined by ObjectTwainError in the “ObjectTWAIN™ COM Constant Enumerations” reference section at the end of the document.

 

 


6.3. How To Select a Data Source and Open a TWAIN Session

6.3.1. Select and use the default TWAIN Data Source

 

This is the most simple to implement and the most robust mechanism to select and open a session with a Data Source. This technique adheres to the model recommended in the TWAIN Specification. Usually an application will have two User Interface command elements (e.g. menu items or buttons), one to select the default source and another one to open the default source and start the acquisition.

 

Use the TWControl UserSelectSource method to display the default Source Select dialog and let the user to select the default TWAIN Data Source. This default will be preserved across TWAIN sessions until a new Data Source is installed on the system or another default is selected.

 

Use the TWControl OpenSession method to open a session with the default Data Source.

 

Visual Basic example:

 

TWControl.OpenSession Form1.hWnd

 

Delphi example:

 

TWControl.OpenSession(Application.Handle, '');

 

Visual C++/MFC example:

 

m_twControl.OpenSession((long)m_hWnd, _T(""));

 

6.3.2. Select and use a custom, fixed TWAIN Data Source

 

This may be useful for a special purpose application that may need to be dedicated to only one acquisition device. The second parameter of OpenSession may be used to pass as a character string the name of the Data Source to open. This is the same string listed in the Select Source dialog and it corresponds to the TW_IDENTITY.ProductName reported by the Data Source.

 

Visual Basic example:

 

TWControl.OpenSession Form1.hWnd, "ScanPartner 15C"


6.3.3. Use a custom select source dialog

 

ObjectTWAIN™ ActiveX Library exports two COM objects useful in this situation: TWSourceInfo (a wrapper object for the TWAIN TW_IDENTITY structure) and TWSourceList (a collection of TWSourceInfo objects). The TWControl GetInstalledSources method may be used to get the list of installed Data Sources information as a TWSourceList object.

 

First you have to display to the user the names of the Data Sources to select one from. You may display the names for all the Data Source installed or select a subset of the available Data Sources (based on the information contained by the TWSourceInfo object for each Data Source found).

 

Visual Basic example: how to fill a ListBox object (List1) with the names of all TWAIN Data Sources installed on the system:

 

Dim SourceList As TWSourceList

Dim SourceInfo As TWSourceInfo

Set SourceList = TWControl.GetInstalledSources

For Each SourceInfo In SourceList

    List1.AddItem SourceInfo.ProductName

Next

Set SourceList = Nothing

 

Then, to open the selected Data Source, call the TWControl OpenSession method passing the selected Source name as the second parameter:

 

Private Sub SelectBtn_Click()

    TWControl.OpenSession hWnd, List1.List(List1.ListIndex)

End Sub


6.4. How To Negotiate Capabilities

 

ObjectTWAIN™ provides access to any possible capability operation (Get, GetCurrent, GetDefault, Reset, Set, QuerySupport) on any capability, either defined by TWAIN or custom defined, through TWControl methods and the TWContainer COM object. TWContainer is a wrapper object for capability containers (arrays, enumerations and range of values). Where possible, simple types are used (such as integer, boolean or string). In all other cases, a reference to a TWContainer object will be passed to a Set function or returned by a Get operation.

 

IMPORTANT:

 

·         Do not assume that any Data Source will support a capability (even though this would be a capability described by the TWAIN Spec to be mandatory to be supported by any Data Source). Always check for error codes signaling an unsupported capability, operation on capability or even a general failure caused by an unexpected problem into the Data Source.

 

·         It is recommended to always check the TWContainer objects (returned by Get/ GetAvailable/ GetCurrent/ GetDefault and Reset operations) to be valid (the VARIANT/ANY variable received needs to be a valid reference to a TWContainer COM object) and the type of container (TWContainer.Type may be ON_RANGE, ON_ENUMERATION or ON_ARRAY) before trying to read the container values (this is specially important when negotiating capabilities that may accept multiple container types).

 

·         It is recommended to check first if a capability is supported (by using GetSupportedCaps), get the available/supported values (by using the GetAvailable or Get method related to that capability) and only then try to change (set) the current or available set of values for that capability. By isolating a problem in the Data Source the application may avoid using a badly implemented Data Source feature that may cause the entire application to hang or crash.

 

·         Do not try to set a capability after the acquisition has been started unless that capability was previously negotiated as extended (through TWControl.Get/SetExtendedCaps). Also make sure a Data Source Session is opened before executing any capability operation.

 

The next sub-sections will describe some of the most frequent cases of capability negotiation.


 

6.4.1. How to iterate through an enumeration, array or range of capability values

 

All GetAvailable on enumerated and range type capabilities (e.g. ICAP_PIXELTYPE,  ICAP_XRESOLUTION) or Get on array-type capabilities (e.g. CAP_EXTENDEDCAPS) TWControl methods return when successful a reference to a TWContainer COM object ‘filled’ with the array, enumeration or range of capability values returned by the Data Source as result to the TWAIN capability operation requested.

 

6.4.1.1. Arrays and Enumerations of values

 

There are two possible methods of iterating the values from an enumeration or array of values contained by a TWContainer object:

 

·         Use the automatic OLE Collection iteration feature. This method is currently supported only by the most recent versions of Visual Basic through the for each statement.

 

·         Iterate the values by using the special designed methods exposed by TWContainer: Count()  to get the number of items in container and Item(Index) to retrieve an item at the given index. These methods shall be accessible from any programming environment able to understand standard OLE Automation interfaces (all the COM interfaces exposed by ObjectTWAIN™ objects are dual interfaces).

 

 

Notes:

 

·         All indexes for objects exposed by ObjecTWAIN ActiveX Library are 1-based in Visual Basic style: the index of the first item in a list is 1 (not 0).

 

·         A TWContainer object is actually a collection of VARIANT objects: a VARIANT element may be of any possible type, from a boolean value to a reference to a complex COM object expressed as a pointer to an IDispatch interface. For capability operations the most ‘complex’ COM object that may be (under normal conditions) contained by a TWContainer is a TWFrame object (object used for GetAvailable/GetCurrent/GetDefault/Reset/SetIFrames).

 

 

To access the current and/or the default value in a TWContainer enumeration an enumeration TWContainer object exposes the CurrentIndex and DefaultIndex properties.

 

6.4.1.2. Ranges of values

 

The TWContainer objects expose a set of properties to enable an application to access them as ranges of values: RangeMin, RangeMax, RangeStep, RangeCurrent and RangeDefault (when the container type is ON_RANGE).

 


 

6.4.1.3. Example how to get the capabilities reported as supported by the Data Source

 

The application may use TWControl GetSupportedCaps method to ask the Data Source to return an array of the supported capabilities. GetSupportedCaps will return the array as a TWContainer collection of TWCapabilityName objects or simple integer values (depending how the collection is accessed, as a collection of objects or integers):

 

Visual Basic example (no error checking code; the ‘for each’ approach is used):

 

Dim Caps As TWContainer

Dim Capability As TWCapabilityName

Set Caps = TWControl.GetSupportedCaps

For Each Capability In Caps

    ‘ do something, e.g.:   

    If Capability = IC_ORIENTATION Then

        bSupportsOrientation = True

        Exit For

    End If

Next

Set Caps = Nothing

 

Delphi 3 example (no error checking code; the Count/Item(Index) approach is used):

 

//SupportedCapsCon : OleVariant;

//SourceSupportsOrientation : Boolean;

//i : Integer;

 

SupportedCapsCon := TWControl.GetSupportedCaps;

for i := 1 to SupportedCapsCon.Count do

begin

    // do something, e.g.:   

    if SupportedCapsCon.Item[i].Value = IC_ORIENTATION then

        bSupportsOrientation := True;

end;

endSupportedCapsCon := UnAssigned;

 

 

Note:

 

In this case the items in the TWContainer object are references to TWCapabilityName COM objects. In the first example it was not needed to explicitly use the TWCapabilityName.Value property, Visual Basic was smart enough to automatically convert the integer value to the default property of the TWCapabilityName object. The second example shows how to explicitly use this property when the programming environment is not able to automatically make the conversion.

 


 

Visual C++ example:

 

BOOL bIcapOrientationSupported = FALSE;

 

try

{

   

VARIANT varSupportedCaps = m_twControl.GetCapSupportedCaps();

//

// Proceed only if received a valid pointer to a Dispatch interface:

//

if((VT_DISPATCH == varSupportedCaps.vt) && (varSupportedCaps.pdispVal))

{          

  //

  // Connect the received IDispatch to a TWContainer object:

  //

  ITWContainer SupportedCaps(varSupportedCaps.pdispVal);

                 

  //

  // Iterate through the TWContainer and search for ICAP_ORIENTATION:

  //

  int nSupportedCaps = SupportedCaps.GetCount();

  COleVariant varOrientationCapName((long)ICAP_ORIENTATION);

 

  for(int i = 1; i <= nSupportedCaps; i++)

  {

    COleVariant varCapabilityName = SupportedCaps.GetItem(i);

                       

    //

    // Make sure that we compare here an integer value:

    // (VT_I4 stands for '4 bytes signed integer)

    //

    //

    // (the varCapabilityName may be an IDispatch to an   

    // TWCapabilityName object; in this case may be better

    // to access directly this VARIANT as an integer)

    //

    varCapabilityName.ChangeType(VT_I4);

 

    //if(ICAP_ORIENTATION == varCapabilityName.lVal)

    if(varOrientationCapName == varCapabilityName)

    {

      bIcapOrientationSupported = TRUE;

      break;

    }

  }

}

 

}

catch(COleDispatchException *)

{

  // CAP_SUPPORTEDCAPS is not supported

}


 

6.4.1.4. Example how to get the x-axis resolution values supported by the Data Source

 

The application may use TWControl GetAvailableIXResolution method to ask the Data Source to return an enumeration or range of the supported x-axis resolutions. The range or enumeration of values will be returned by GetAvailableIXResolution as a TWContainer collection of floating point values (not integer because ICAP_XRESOLUTION values are defined by TWAIN as TW_FIX32). If the Data Source returns a TWON_ONEVALUE container ObjectTWAIN™ will make automatically an enumeration containing only one item which will also be the current and default one. The application will have to read the TWContainer Type property before trying to access the resolution values as an enumeration or as a range of values (TWAIN defines both container types to be allowed for DAT_CAPABILITY/ MSG_GET on ICAP_XRESOLUTION).

 

Visual Basic example (no error checking code):

 

Dim Xres As TWContainer

Set Xres = TWControl.GetAvailableIXResolution

 

If Xres.Type = ON_ENUMERATION Then

 

    For Each Item In Xres

       ' do something: add the resolutions to a ListBox control

       List1.AddItem Item

    Next

 

    ' read the current and default values:

    MsgBox Xres(Xres.CurrentIndex), vbOKOnly, "Current x res"

    MsgBox Xres(Xres.DefaultIndex), vbOKOnly, "Default x res"

Else

    k = 0

 

    Do

        Value = Xres.RangeMin + k * Xres.RangeStep

        If Value > Xres.RangeMax Then

            Exit Do

        End If

        List1.AddItem Value

        k = k + 1

    Loop

 

    MsgBox Xres.RangeMin, vbOKOnly, "Min x res"

    MsgBox Xres.RangeMax, vbOKOnly, "Max x res"

    MsgBox Xres.RangeCurrent, vbOKOnly, "Current x res"

    MsgBox Xres.RangeDefault, vbOKOnly, "Default x res"

End If


 

Delphi 3 example:

 

// XResCon : OleVariant;

// SourceSupportsXRes, NeedToSetXRes : Boolean;

// i : Integer;

// ConfigRes, rmin, rmax, rdef, rstep, rcur, f : Double;

// TWError : tagObjectTwainError;

 

 

//

// Check if the Data Source supports a ‘configured’ x-resolution

// and set it to be the current value for this session

// (if not already selected in the DS):

//

SourceSupportsXRes := False;

NeedToSetXRes := True;

 

try

 

XResCon := TWControl.GetAvailableIXResolution;

 

TWError := TWControl.GetLastError;

if TWError = OBJTWAIN_NO_ERROR then

begin

    Assert(varDispatch = VarType(XResCon));

    if XResCon.Type = ON_RANGE then

    begin

        // Check basically only if the configured value is in the

        // requested range (no exact step coverage estimation)

        if (XResCon.RangeMin <= ConfigRes) and

            (XResCon.RangeMax >= ConfigRes) then

        begin

            SourceSupportsXRes := True;

            if XResCon.RangeCurrent = ConfigRes then

            begin

                // No need to set XResolution

                NeedToSetXRes := False;

            end;

        end

        else

        begin

            SourceSupportsXRes := False;

            // Configured XResolution outside available range

        end;

    end

    else if XResCon.Type = ON_ENUMERATION then

    begin

        for i := 1 to XResCon.Count do

        begin

            if XResCon.Item[i] = ConfigRes then

            begin

                SourceSupportsXRes := True;

                (continued on next page)


(continued from previous page)  

                if i = XResCon.CurrentIndex then

                begin

                    // XRes already set, no need to set again

                    NeedToSetXRes := False;

                end;

                break;

            end;

        end;

    end;

 

    if SourceSupportsXRes = True and NeedToSetXRes = True then

    begin

        TWControl.SetIXResolution(ConfigRes);

 

        TWError := TWControl.GetLastError;

        if TWError <> OBJTWAIN_NO_ERROR then

        begin

            SourceSupportsXRes := False;

        end;

    end;

end;

except

    SourceSupportsXRes := False;

end;

 


 

6.4.2. How to set to Data Source an enumeration or array of capability values

 

It is recommended to use this technique when the application wants to try to limit the set of available values for an enumerated-type capability (e.g.: limit the pixel types supported by the Data Source in the current session only to B&W and Grayscale – if: (1) the Data Source supports TrueColor by default and the user can change the pixel type from the Data Source UI and (2) the application does not want to receive RGB image data and (3) the Source accepts the application’s request to exclude the RGB pixel type from its set of supported pixel types in this session, then the Data Source shall no longer let the user set RGB from its UI – e.g. by disabling the related button in its interface).

 

There are two different methods to get a TWContainer object to pass the enumeration of values to the Data Source:

 

6.4.2.1. Use a TWContainer object returned by a GetAvailable or Get operation

 

Visual Basic example (no error checking code): get the pixel types supported by the Data Source, then remove RGB if present from the enumeration and set it back to the Data Source:

 

Dim PixelTypes As TWContainer

Dim pt As TWPixelTypeValue

Set PixelTypes = TWControl.GetAvailableIPixelType

 

i = 1

LimitedRGB = False

For Each pt In PixelTypes

    If pt = PT_RGB Then

        PixelTypes.Remove i

        LimitedRGB = True

        Exit For

    End If

    i = i + 1

Next

 

If LimitedRGB Then

    TWControl.SetIPixelType PixelTypes

End If

 

Set PixelTypes = Nothing

 

6.4.2.2. Use a new TWContainer object

 

The only special thing here is that the application has to construct a new COM object, in this case TWContainer:

 

Step 1: Construct a new TWContainer object

 

Visual Basic example:

 

Dim NewPixelTypes As New TWContainer

 

Delphi example:

 

NewPixelTypes := CoTWContainer.Create;


 

PowerBuilder example:

 

OLEObject NewPixelTypes

integer result = 0

NewPixelTypes = CREATE OLEObject

if not IsNull(NewPixelTypes) then

    result = NewPixelTypes.ConnectToNewObject("ObjTWAIN.TWContainer")

    if 0 > result or IsNull(result) then

        /* insert here error handling code */

    else

        /* initialize the new TWContainer */

    end if

end if      

 

Step 2: Initialize the container type

 

Visual Basic example:

 

NewPixelTypes.InitEnumeration 2

 

Notes:

 

·         In the above example 1 is the number of items in the new enumeration.

·         To initialize an Array or Range use TWContainer.InitArray respectively InitRange.

 

Step 3: Add values to the container

 

Visual Basic example (no error checking code):

 

NewPixelTypes.Add PT_BW

NewPixelTypes.Add PT_GRAY

 

Step 4: Set to Data Source the container

 

Visual Basic example (no error checking code):

 

TWControl1.SetIPixelType NewPixelTypes

 

Step 5: When finished with the container object, destroy it

 

Visual Basic example:

 

Set NewPixelTypes = Nothing

 

Delphi example:

 

ImageLayout := UnAssigned;

 

PowerBuilder example:

 

DESTROY NewPixelTypes

 


6.5. How To Negotiate the Acquisition Frame Layout

 

You may use the following TWControl methods to negotiate the acquisition frame layout:

 

·         To get the current and the available dimensional units of measurement (ICAP_UNITS) use GetAvailableIUnits. Use GetCurrentIUnits or GetDefaultIUnits to get only the current or the default value. Use SetIUnits to change the current unit.

 

·         To get the current image layout frame use GetImageLayout. If successful this method will return a TWImageLayout object containing the acquisition frame coordinates, in current units.

 

·         To get the fixed page sizes the Data Source supports use GetAvailableISupportedSizes. Use SetISupportedSizes to set the acquisition frame to a supported page size.

 

·         To set/change the current acquisition layout use SetImageLayout (ResetImageLayout will revert the current layout to the Source’s default – to get this default do GetDefaultImageLayout) and pass the new layout as a TWImageLayout object. Like for TWContainer when setting a capability,  you may use either a TWImageLayout object returned by a previous GetImageLayout or create a new TWImageLayout object.

 

·         The current acquisition frame may also be changed by using SetIFrames and a TWFrame object as parameter (or a collection of TWFrame objects, as a TWContainer) - if the Data Source supports setting the related capability (ICAP_FRAMES).

 

·         To change the orientation or rotate the image to transfer use SetIOrientation or SetIRotation (do not forget to check first if IC_ORIENTATION or IC_ROTATION capabilities are supported and get the supported values with GetAvailableIOrientation or GetAvailableIRotation).

 

 

6.5.1.1. Visual Basic example 

 

This example will:

 

1.       Set the current unit to inches.

2.       Get the current image layout

3.       Modify the received TWImageLayout object and pass it back to the Data Source

4.       Reset the image layout

5.       Create e new TWImageLayout object and set it to the Data Source

 

On Error GoTo errImageLayout

   

TWControl.SetIUnits UN_INCHES

   

Dim layout As TWImageLayout

Set layout = TWControl.GetImageLayout

   

layout.FrameRight = (layout.FrameRight - layout.FrameLeft) / 2

layout.FrameBottom = (layout.FrameBottom - layout.FrameTop) / 2

layout.FrameLeft = 0

layout.FrameTop = 0

TWControl.SetImageLayout layout

(continued on next page)


(continued from previous page)  

Set layout = Nothing

TWControl.ResetImageLayout

   

Dim newLayout As New TWImageLayout

newLayout.FrameLeft = 0

newLayout.FrameRight = 5

newLayout.FrameTop = 0

newLayout.FrameBottom = 5

TWControl.SetImageLayout newLayout

       

Set newLayout = Nothing

Exit Sub

   

errImageLayout:

Exit Sub

 

6.5.1.2. Delphi 4 example

 

The example will show how to set an US-Letter scan page size (8.5 x 11 inches):

 

1.       Set ICAP_UNITS to TWUN_INCHES.

2.       Check if ICAP_SUPPORTEDSIZES and TWSS_USLETTER are supported.

3.       If the Data Source supports ICAP_SUPPORTEDSIZES and TWSS_USLETTER set ICAP_SUPPORTEDSIZES to TWSS_USLETTER and terminate.

4.       Otherwise try to set the TW_IMAGELAYOUT frame data (0, 0, 8.5, 11 inches).

 

SourceSupportsInches := True;

try

TWControl.SetIUnits(UN_INCHES);

except

    SourceSupportsInches := False;

end;

 

if SourceSupportsInches then

begin

    SourceSupportsUSLetter := False;

    NeedToSetUSLetter := True;

 

    try

 

    SupportedSizesCon :=

        TWControl.GetAvailableISupportedSizes(SupportedSizesCon);

    for i := 1 to SupportedSizesCon.Count do

    begin

        x := SupportedSizesCon.Item[i].Value;

        if SupportedSizesCon.Item[i].Value = SS_USLETTER then

        begin

            SourceSupportsUSLetter := True;

            if i = SupportedSizesCon.CurrentIndex then

            begin

                NeedToSetUSLetter := False;

            end;

            break;

        end;

    end;

(continued on next page)


(continued from previous page)  

    SupportedSizesCon := UnAssigned;

 

    if SourceSupportsUSLetter = True and NeedToSetUSLetter = True then

    begin

        TWControl.SetISupportedSizes(SS_USLETTER);

        SourceSupportsUSLetter := True;

    End;

   

    except

        SourceSupportsUSLetter := False;

    end;

end; //if SourceSupportsInches

 

if SourceSupportsInches and False = SourceSupportsUSLetter then

begin

    // Try setting the image layout:

    try

 

    ImageLayout := CoTWImageLayout.Create;

    ImageLayout.FrameLeft := 0;

    ImageLayout.FrameTop := 0;

    ImageLayout.FrameRight := 8.5;

    ImageLayout.FrameBottom := 11;

    

    TWControl.SetImageLayout(ImageLayout);

    SourceSupportsUSLetter := True;

   

    except

        SourceSupportsUSLetter := False;

    end;

 

    ImageLayout := UnAssigned;

end;

 

6.5.1.3. PowerBuilder example

 

OLEObject ImageLayout

integer result = 0

 

this.object.SetIcapUnits(0) /*TWUN_INCHES*/

ImageLayout = CREATE OLEObject

if not IsNull(ImageLayout) then

    result = ImageLayout.ConnectToNewObject("ObjTWAIN.TWImageLayout")

    if 0 > result or IsNull(result) then

         /* insert error handling code here */

    else

        ImageLayout.FrameLeft = 0

        ImageLayout.FrameTop = 0

        ImageLayout.FrameRight = 8.5

        ImageLayout.FrameBottom = 11

        This.object.SetImageLayout(ImageLayout)

    end if

    DESTROY ImageLayout

end if


6.6. How To Start the Image Acquisition

 

TWAIN defines three different modes to execute an image transfer:

 

·         Native

·         Buffered Memory: strips or tile buffers, uncompressed or compressed

·         Disk File

 

The TWAIN Specification  describes the Disk File and Compressed Memory modes as being optional to be implemented by Data Sources and few Data Sources fully supports them. The Native and Uncompressed Memory (especially using strip buffers) modes are marked as mandatory and must be supported correctly by any TWAIN compatible Data Source. The problem when developing a TWAIN application using a high-level programming language like Visual Basic is that under both these modes the application receives the image data either as a DIB handle in memory or a pointer or handle to raw image data (when using the Buffered Memory mode the application will even have to create the image header and assemble the complete image by itself). The ObjectTWAIN™ ActiveX Library solves this by providing conversion of Native and Buffered Memory TWAIN image transfers to disk file transfers. Still the ObjectTWAIN™ ActiveX can execute Native and Buffered Memory transfers in the traditional mode (passing to the application DIB handles or a memory buffers) and let the application to handle and assemble the image by itself.

 

The following table shows the ObjectTWAIN™ Transfer Modes, what TWAIN Transfer Mechanism uses each of them, which TWControl properties shall be set at design or run-time and which  TWControl methods must be called to start the acquisition sequence:

 

ObjectTWAIN™ Xfer Mode

TWAIN Xfer Mode

How to start

Native

(DIB handle)

Native

(DIB handle)

Set NativeMemoryAsFile to False

Call StartNativeAcquisition

Memory

(raw memory buffers)

Memory

(raw memory buffers)

Set NativeMemoryAsFile to False

Call StartMemoryAcquisition

File

(disk file)

File

(disk file)

Set TransferFile

Call StartFileAcquisition

Native to File

(disk file)

Native

(DIB handle)

Set NativeMemoryAsFile to True

Set NativeMemoryFileType

Set NativeMemoryTIFFCompression

Set TransferFile

Call StartNativeAcquisition

Memory to File

(disk file)

Memory

(raw memory buffers)

Set NativeMemoryAsFile to True

Set NativeMemoryFileType

Set NativeMemoryTIFFCompression

Set TransferFile

Call StartMemoryAcquisition

 

See the next section for information about how to expect and receive the image data.


6.7. How To Handle Transferred Image Data and Other Transfer Events

 

The ObjectTWAIN™ ActiveX Library notifies an application when an image transfer (or just an image buffer for Memory Mode) is received and when a special transfer condition occurs (e.g. all the images were transferred or a transfer error occurred) using TWControl ActiveX events.

 

The following table enumerates the events an ObjectTWAIN™ application may expect from a TWControl object:

 

Event / Meaning

Description / Action to do

When to expect

DoProcessNativeData

 

 

 

IMAGE DATA RECEIVED

The application receives a transferred image as a  handle to a DIB in memory.

 

TO DO: save the DIB.

After starting the transfer sequence in Native mode (NativeMemoryAsFile is False)

DoProcessMemoryData

 

 

 

 

 

 

IMAGE DATA RECEIVED

The application receives a raw buffer containing a strip or tile memory buffer of the image.

 

TO DO: save the buffer; if this is the last buffer finish to assemble one image.

After starting the transfer sequence in Memory mode (NativeMemoryAsFile is False)

DoProcessFileData

 

 

 

 

 

 

 

IMAGE DATA RECEIVED

The application receives the file format and the file name where a transferred image was just saved.

 

TO DO: set the TransferFile property for the next transfer or copy the file to other location.

After starting the transfer sequence in File mode.

DoProcessNativeAsFileData

 

 

 

 

 

 

 

IMAGE DATA RECEIVED

The application receives the file format and the file name where a transferred image was just saved.

 

TO DO: set the TransferFile property for the next transfer or copy the file to other location.

After starting the transfer sequence in Native to File mode (NativeMemoryAsFile is True).

DoProcessMemoryAsFileData

 

 

 

 

 

 

 

IMAGE DATA RECEIVED

The application receives the file format and the file name where a transferred image was just saved.

 

TO DO: set the TransferFile property for the next transfer or copy the file to other location.

After starting the transfer sequence in Memory to File mode (NativeMemoryAsFile is True).

(continued on next page)


(continued from previous page)

OnFeederLoaded

 

 

 

 

 

FEEDER LOADED

The application is notified that the user put paper in the device’s Document Feeder.

 

TO DO: the application may now activate and start the image acquisition.

When a session is opened and AutoCheckFeeder is True.

OnBeginTransfers

 

 

TRANSFER(S) READY

The application is notified that the transfers are ready to begin (the Source sent the Transfer Ready signal).

After starting the transfer sequence (of any type). This event shall come only once per acquisition sequence.

OnEndTransfers

 

 

 

 

 

 

NO MORE TRANSFERS

The application is notified that all available images were transferred and the Data Source does not have more pending transfers.

 

 

TO DO: close the session.

After starting the transfer sequence (of any type). This event may come only once per acquisition sequence.

OnCancelTransfer

 

 

 

 

 

TRANSFER CANCELED

The application is notified that either the Source or the user canceled a transfer and the acquisition sequence.

 

 

TO DO: stop the acquisition.

After starting the transfer sequence (of any type). This event or OnEndTransfers may signal that the acquisition is finished.

OnTransferError

 

 

 

 

 

 

 

TRANSFER ERROR

The application is notified that a transfer error occurred (the application may receive the error code and a error text description.

 

TO DO: optionally inform the user about the problem and stop the acquisition.

After starting the transfer sequence (of any type).

OnPreTransfer

 

 

 

 

 

 

PRE-TRANSFER

The application is notified that a transfer is about to begin. The TWAIN session is still in state 6.

 

TO DO: get information about the image to be transferred.

After starting the transfer sequence (of any type). This event shall come once per image transfer in the acquisition sequence.

OnPostTransfer

 

 

 

 

 

POST-TRANSFER

The application is notified that a transfer completed. The TWAIN session is in state 6 or 5 (if there are no more transfers pending).

 

TO DO: -

After starting the transfer sequence (of any type). This event shall come once per image transfer in the acquisition sequence (excepting a canceled or failed transfer).

(continued on next page)


(continued from previous page)

OnDeviceEvent

 

 

 

 

 

DEVICE EVENT

The application is notified that the device triggered an event.

 

TO DO: read the event information and act accordingly.

After opening a session and (through SetDeviceEvents). This event may come before or after starting the acquisition.

OnUserCloseSourceUI

 

 

 

 

 

 

 

USER CLOSES SOURCE UI

The application is notified that the user requested to close the Data Source UI. The event parameter indicates if the user closes the DS UI in ‘OK’ or ‘Cancel’ mode.

 

TO DO: stop the acquisition.

After starting the transfer sequence (of any type) with the option to display the Data Source User Interface.

 

Note: Please see next three sections for explanations about getting image information, getting extended image information and how to scan using the device’s Document Feeder.

 


6.8. How To Get Image Information

 

To get information about the image to be transferred the TWControl GetImageInfo method may be called while processing an OnPreTransfer event. GetImageInfo returns if successful a TWImageInfo object that is a COM wrapper for the TW_IMAGEINFO data structure defined by TWAIN. You can retrieve in this way the image dimensions, pixel type, compression, bit depth per sample and number of samples (color channels) for the image next to transfer.

 

Visual basic example:

 

Private Sub TWControl_OnPreTransfer()

    On Error GoTo errGetImageInfo

    Dim ImageInfo As TWImageInfo

   

    Set ImageInfo = TWControl.GetImageInfo

    ‘ do something:

    If ImageInfo.PixelType = PT_BW Then

        MsgBox "The next image to be transferred will be B&W"

    End If

    Exit Sub

   

errGetImageInfo:

    MsgBox "GetImageInfo failed"

End Sub

 

If the application may call StopAcquisition or CloseSession while processing a OnPreTransfer event (if the application does not know how (or does not want to) handle a certain type of image data - e.g. if one combination of pixel type and bit depth are not supported by the application) when processing OnTransferError the application should check before reporting a transfer error that the ObjectTWAIN™ session state is ACQUISITION:

 

Visual basic example:

 

Private Sub TWControl_OnTransferError(ByVal error As OBJTWAINLibCtl.tagObjectTwainError, ByVal ErrorDescription As String)

    If TWControl.GetState = ACQUISITION Then

        MsgBox ErrorDescription

        TWControl.StopAcquisition

    End If

End Sub

 

Under the following conditions GetImageInfo may also be called while processing one of the OnProcessXData events (when the TWAIN session is in state 7): (1) if the Data Source is unable to detect the image dimensions before the transfer (e.g. a Data Source deserving a hand held scanner), (2) if the ICAP_UNEDFINEDIMAGESIZE is True (use GetIUndefindImageSize), (3) if the image width and length are returned to be –1 pixels in the TWImageInfo object (the one get at OnPreTransfer) and (4) if the Data Source supports returning image information after the transfer (in the TWAIN session state 7) .

 


6.9. How To Get Extended Image Information

 

To get extended image information (such as barcode information) follow the next steps:

 

Step 1: Check if the Data Source supports this kind of extended information by calling GetIExtendedImageInfo and other capability methods (e.g. GetIBarCodeDetectionEnabled if the extended information to get is related to barcodes).

 

Visual Basic example (from GenProd sample, TWControl_DoProcessMemoryAsFileData):

 

bBarCodeDetectionEnabled = False

iMaxBarCodeSearch = 0

   

bBarCodeDetectionEnabled = TWControl.GetIBarCodeDetectionEnabled

AppendLog "GetIBarCodeDetectionEnabled ok"

   

If bBarCodeDetectionEnabled Then

    iMaxBarCodeSearch = TWControl.GetCurrentIBarCodeMaxSearchPriorities

    AppendLog "GetCurrentIBarCodeMaxSearchPriorities ok"

    If iMaxBarCodeSearch <= 0 Then

        bBarCodeDetectionEnabled = False

    End If

End If

   

If False = bBarCodeDetectionEnabled Then

    AppendLog "Barcode detection disabled"

    Exit Sub

End If

   

If False = TWControl.GetIExtImageInfo Then

    AppendLog "GetIExtImageInfo ok, returned False"

    AppendLog "No GetExtImageInfo will be requested"

    Exit Sub

Else

    AppendLog "GetIcapExtImageInfo ok"

End If

 

Step 2: Construct a TWContainer object to contain the array of extended image information objects to ask the Data Source to return data into. Initialize the TWContainer object as an array specifying the desired number of extended infos as the number of array items.

 

Visual Basic example (from GenProd sample, TWControl_DoProcessMemoryAsFileData):

 

If iMaxBarCodeSearch > 6 Then

    iMaxBarCodeSearch = 6

End If

' BARCODETEXT & BARCODETYPE for each barcode, & 1 BARCODECOUNT:

iInfos = ((iMaxBarCodeSearch * 2) + 1)

   

Set ExtImageInfo = New TWContainer

ExtImageInfo.InitArray iInfos


 

Step 3: Construct the extended information objects as TWInfo objects. Initialize for each TWInfo object the InfoID property. Add the TWInfo objects to the TWContainer array.

 

Visual Basic example (from GenProd sample, TWControl_DoProcessMemoryAsFileData):

 

For i = 1 To iInfos

    Set Info(i) = New TWInfo

Next

        

Info(1).InfoID = EI_BARCODECOUNT

For i = 2 To iInfos

    Info(i).InfoID = EI_BARCODETYPE

    i = i + 1

    Info(i).InfoID = EI_BARCODETEXT

Next

   

For i = 1 To iInfos

    ExtImageInfo.Add Info(i)

Next

 

Step 4: Call the TWControl GetExtImageInfo method. If successful, the TWInfo objects in the TWContainer array shall contain the extended image information returned by the Data Source.

 

Visual Basic example (from GenProd sample, TWControl_DoProcessMemoryAsFileData):

 

TWControl.GetExtImageInfo ExtImageInfo

AppendLog "GetExtImageInfo ok"

   

If ExtImageInfo.Count > 0 Then

    For Each Temp In ExtImageInfo

        If Temp.InfoID = EI_BARCODECOUNT Then

            For Each InfoItem In Temp

                AppendLog "BarCodeCount: " & CStr(InfoItem)

            Next

        End If

           

        If Temp.InfoID = EI_BARCODETYPE Then

            For Each InfoItem In Temp

              AppendLog "BarCodeType: " & DecodeBarcode(Int(InfoItem))

            Next

        End If

           

        If Temp.InfoID = EI_BARCODETEXT Then

            For Each InfoItem In Temp

                AppendLog "BarCodeText: " & CStr(InfoItem)

            Next

        End If

    Next 'For Each Info In ExtImageInfo

End If  


 

Step 5: After finishing with the array of TWInfo objects, destroy them and free the allocated memory.

 

Visual Basic example (from GenProd sample, TWControl_DoProcessMemoryAsFileData):

 

For i = 1 To iInfos

    Set Info(i) = Nothing

Next

Set ExtImageInfo = Nothing

 

Note: For the above sequence of code (from the GenProd sample) the local variable definitions and the error handling mechanism are listed next:

 

Dim bBarCodeDetectionEnabled As Boolean

Dim iMaxBarCodeSearch As Integer

Dim iInfos As Integer

Dim ExtImageInfo As TWContainer

Dim Info(1 To 14) As TWInfo

Dim Temp As TWInfo

Dim InfoItem As Variant

Dim i As Integer

 

On Error GoTo errGetExtImageInfo

    ‘ follows the code sequence to get extended image information

    Exit Sub

errGetExtImageInfo:

    AppendLog "Get extended image info failed:"

    AppendLog Err.Description

 

 


6.10. How To Use the Automatic Document Feeder

 

To ‘manually’ check the feeder status, enable or disable the feeder, use the following TWControl methods:

 

·         To see if the feeder is enabled call GetFeederEnabled.

·         To enable or disable the feeder call SetFeederEnabled.

·         To see if the feeder is loaded call GetFeederLoaded.

·         To see if the Automatic Document Feeder is enabled call GetAutoFeed.

·         To enable or disable the Automatic Document Feeder (if present) call SetAutoFeed.

 

To use the automatic feeder loaded detect feature supported by ObjectTWAIN™ set the TWControl AutoCheckFeeder property to True (either at design or at run-time). When AutoCheckFeeder is enabled, as soon as a session is opened ObjectTWAIN™ will begin to automatically call GetFeederLoaded. Setting the TWControl property ACFInterval configures the time between two automatic GetFeederLoaded calls. When the feeder will be loaded with paper TWControl will send an OnFeederLoaded event. The application may open a session and then wait in background until it receives OnFeederLoaded, then activate and start the acquisition.

 

Delphi 3 example:

 

procedure TScanForm.TWControlFeederLoaded(Sender: TObject);

var

    TWError : tagObjectTwainError;

begin

    if (TWControl.GetState <> ACQUISITION) and

       (TWControl.AutoCheckFeeder) then

    begin

        TWControl.StartNativeAcquisition(False);

        TWError := TWControl.GetLastError;

        if TWError <> OBJTWAIN_NO_ERROR then

        begin

           Application.MessageBox(‘Unable to start acquisition.',

               'Error', MB_ICONSTOP);

           CloseSession;

           TWControl.AutoCheckFeeder := False;

        end;

    end;

end;


 

7. Library Reference

 

R.1. ObjectTWAIN™ ActiveX/COM Controls

 

Control name

Interfaces

Description

TWControl

ITWControl

Idispatch

TWControl is the main ActiveX control, insertable and invisible at run-time, exported by the ObjectTWAIN™ ActiveX Library. By using this control an application can select a TWAIN Data Source, open and control programatically a complete TWAIN image acquisition session.

TWContainer

ITWContainer

Idispatch

Implements an array or enumeration of values or COM objects or a range of values as a COM Collection. Wrapper for TWAIN capability containers and for the array of extended image attributes.

TWSourceList

ITWSourceList

Idispatch

Implements as a COM Collection a list of TWSourceInfo objects to hold information about the TWAIN Data Sources installed on system (get with GetInstalledSources).

TWSourceInfo

ITWSourceInfo

Idispatch

Wrapper COM object for TWAIN Data Source identity data structure. Describes the atributes of a Data Source.

TWImageLayout

ITWImageLayout

Idispatch

Wrapper COM object for TWAIN image layout data structure. Used to negotiate the acquisition frame layout.

TWImageInfo

ITWImageInfo

Idispatch

Wrapper COM object for the TWAIN image info data structure. Describes the attributes of the next image to transfer or the last transferred image.

TWInfo

ITWInfo

Idispatch

Wrapper COM object for the TWAIN extended information/attribute data structure. May be stored to TWContainer to create an array of infos to request extended image information from the Data Source.

TWFrame

ITWFrame

Idispatch

Wrapper COM object for the TWAIN frame data structure. May be stored to TWContainer to create an enumeration or array of frames.

TWCapQuery

ITWCapQuery

Idispatch

Wrapper COM object for the TWAIN query capability support data structure. Used with QueryCapability.

 


R.2. Other ObjectTWAIN™ COM Controls

 

The ObjectTWAIN™ ActiveX Library exports wrapper COM objects for all enumerated capability values defined by TWAIN Release v1.8. Each of these objects has as a single default property (named Value), of a type of the related ObjectTWAIN™ COM enumeration which defines the related capability values (e.g. there is a TWPixelTypeValue wrapper COM object for the defined  ICAP_PIXELTYPE capability values, TWPixelTypeValue.Value is of type PixelType, PixelType is defined as a COM Enumeration containing aliases for the TWPT_x values defined by TWAIN).

 

These objects can be very useful in Visual Basic and other development environments which may be able to display in the editor a selection with the available TWAIN defined values when typing a TWControl capability method.

 

 

IMPORTANT: These objects may be replaced in almost all cases by simple numerical values (as defined by TWAIN) when calling a TWControl method to execute a capability operation. TWControl is able to handle an enumerated capability value passed as a parameter to a capability method as either a wrapper COM object or simple numerical value. If the development environment suports this, an enumerated capability value returned by ObjectTWAIN™ as a COM object will be converted automatically by the development environment to a simple value.

 

In Visual Basic, to request set the current value of ICAP_PIXELTYPE to TWPT_BW, you may write:

 

TWControl.SetIPixelType PT_BW

‘ or:

TWControl.SetIPixelType 0

‘or:

Dim BW as new TWPixelTypeValue

‘ Here VB may be able to display automatically while typing

‘ a selection box with the available PT values so you will

‘ not have to look in documentation for the PT_BW value:

BW = PT_BW

TWControl.SetIPixelType BW

Set BW = nothing

 

When typing code in Visual Basic to compare a received ICAP_PIXELTYPE value with a constant  value, Visual Basic may display a selection list with the available values to select from and will  let you select a value or type your own:

 

Dim PixelTypes As TWContainer

Dim pt As TWPixelTypeValue

Set PixelTypes = TWControl.GetIAvailablePixelType

For Each pt In PixelTypes

    ‘ Here VB may be able to display automatically while typing

    ‘ a selection box with the available PT values so you will

    ‘ not have to look in documentation to find the PT_BW value:

    If pt = PW_BW Then

        ‘…

    End If

Next

 


 

In the following table are listed all the ObjectTWAIN™ COM wrapper objects for enumerated-type TWAIN capability values. The third column displays the ObjectTWAIN™ prefix (e.g. PT for PT_BW) and the TWAIN prefix (e.g. TWPT for TWPT_BW; PT_BW is an alias for TWPT_BW, their values are identical, 0). The values related to a single capability all have the same prefix.

 

COM Object Name

TWAIN Capability

Value Prefix

TWCompressionValue

ICAP_COMPRESSION

CMP/TWCP

TWPixelTypeValue

ICAP_PIXELTYPE

PT/TWPT

TWUnitsValue

ICAP_UNITS

UN/TWUN

TWXferMechValue

ICAP_XFERMECH

ACAP_XFERMECH

SX/TWSX

TWCapabilityName

CAP_SUPPORTEDCAPS CAP_EXTENDEDCAPS

C/CAP

IC/ICAP

AC/ACAP

TWDuplexValue

CAP_DUPLEX

DX/TWDX

TWJobControlValue

CAP_JOBCONTROL

JC/TWJC

TWFilterValue

ICAP_FILTER

FT/TWFT

TWImageFileFormatValue

ICAP_IMAGEFILTER

IF/TWIF

TWLightSourceValue

ICAP_LIGHTSOURCE

LS/TWLS

TWOrientationValue

ICAP_ORIENTATION

OR/TWOR

TWBitOrderValue

ICAP_BITORDER

BO/TWBO

TWLightPathValue

ICAP_LIGHTPATH

LP/TWLP

TWPixelFlavorValue

ICAP_PIXELFLAVOR

ICAP_PIXELFLAVORCODES

PF/TWPF

TWPlanarChunkyValue

ICAP_PLANARCHUNKY

PC/TWPC

TWSupportedSizesValue

ICAP_SUPPORTEDSIZES

SS/TWSS

TWBitDepthReductionValue

ICAP_BITDEPTHREDUCTION

BR/TWBR

TWAlarmsValue

CAP_ALARMS

AL/TWAL

TWDeviceEventsValue

CAP_DEVICEEVENT

DE/TWDE

TWClearBuffersValue

CAP_CLEARBUFERS

CB/TWCB

TWAudioFileFormatValue

ACAP_AUDIOFILEFORMAT

AF/TWAF

TWFeederAlignmentValue

CAP_FEEDERALIGNMENT

FA/TWFA

TWFeederOrderValue

CAP_FEEDERORDER

FO/TWFO

TWLanguageValue

CAP_LANGUAGE

LG/TWLG

TWPowerSupplyValue

CAP_POWERSUPPLY

PS/TWPS

TWPrinterValue

CAP_PRINTER

PR/TWPR

TWPrinterModeValue

CAP_PRINTERMODE

PM/TWPM

TWBarCodeSearchModeValue

ICAP_BARCODESEARCHMODE

BC/TWBD

TWPatchCodeSearchModeValue

ICAP_PATCHCODESEARCHMODE

PC/TWBD

TWFlashUsed2Value

ICAP_FLASHUSED2

FL/TWFL

TWFlipRotationValue

ICAP_FLIPROTATION

FR/TWFR

TWImageFilterValue

ICAP_IMAGEFILTER

IF/TWIF

TWNoiseFilterValue

ICAP_NOISEFILTER

NF/TWNF

TWOverScanValue

ICAP_OVERSCAN

OV/TWOV

TWBarCodeTypeValue

ICAP_SUPPORTEDBARCODETYPES

ICAP_BARCODESEARCHPRIORITIES

BT/TWBT

TWDeskewStatusValue