
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 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
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.
·
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.
·
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).
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.
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.
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.
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.
· 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.
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:
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);
}
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.
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(""));
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"
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
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.
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.
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.
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).
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
}
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;
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:
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
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
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).
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
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;
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
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.
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.
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) .
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
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;
|
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. |
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 |