Overriding Twain Source Behavior in DTWAIN
There are some Twain sources that do not behave properly when asked to query certain capability settings. Many times, these sources cause unrecoverable errors when certain capability values are retrieved or set. Sometimes this leaves the Twain Data Source Manager (DSM) to behave incorrectly such as infinite loops, access violations, etc. For the most part, this is caused by using the wrong containers (TW_ONEVALUE, TW_ARRAY, TW_ENUMERATION, TW_RANGE) to retrieve or set the capabilities with accordance to the Twain 1.8 specification. Since Twain is neither regulated and there is no certification of Twain Source behavior, this will continue to be a problem but is becoming more stabilized
To discover these errors, it is advisable to log all errors to a file. From the log, it is possible to determine that a problem with incompatible capabilities exists, and corrections described below can be made.
The usual error log file will contain something similar to the following at the end of the log file:
TW_MEMREF is TW_CAPABILITY:
Cap=ICAP_FRAMES ConType=TW_ONEVALUE hContainer=0H
This indicates that a capability was being set or retrieved using one of the DG_CONTROL/DAT_CAPABILITY/MSG_xxx Twain triplets. The Cap= is the capability in question. The ConType= is the Twain container used for the capability. This denotes that the ICAP_FRAMES does not behave correctly, and possible corrections must be made described below. The hContainer is the handle to the data that TWAIN will use to set or get values from. This is not a concern if hContainer is 0 for MSG_GET, MSG_GETCURRENT, MSG_GETDEFAULT.
Another problem is that some Sources do not support the DG_CONTROL/DAT_CAPABILITY/MSG_QUERYSUPPORT Twain triplet. This triplet is responsible for discovering what operations can be performed on each capability. By default, DTWAIN relies on this capability to determine which operations can be performed on certain capabilities. According to the Twain specification, this triplet must be supported by a compliant Source, however many Sources do not follow this rule. A sign that a Source does not support this option is if your program calls DTWAIN_OpenSource, and your application receives a message box stating that a "Bad Protocol" error has occurred.
The DTWAIN32.INI file can include information concerning capabilities of Sources that need information on the following:
To do this you have the option of specifying a particular Source to override behavior, or allow DTWAIN to apply the setting to all Sources To specify a particular Source, the DTWAIN32.INI file must have the following syntax:
[ProductName1] CapName1=g1,g2,g3,s1,s2 CapName2=g1,g2,g3,s1,s2 ;... ;etc.
QUERYSUPPORT=x
CapName1_STATES=n1,n2,n3,... CapName1_DATATYPE=d1
[ProductName2] CapName1=g1,g2,g3,s1,s2 CapName2=g1,g2,g3,s1,s2 ;... ;etc.
QUERYSUPPORT=x
ProductNamex section This is is the Product name of the Source. The Product Name of the source is the name that appears when you Select a source from the Twain dialog. The name specified here much match exactly with the name specified in the Select Source dialog. Anything under this section will pertain to the product name specified
CapNamex goes under the ProductName section. This name must be one of the standard Twain capability names. For example, ICAP_XFERMECH, ICAP_FRAMES, etc. For each TWAIN capability for the [ProductName] that you want to override, place a seperate setting for each capability. Consult the TWAIN.H file for the proper name of each capability.
g1, g2, g3 - These are the containers to use for MSG_GET, MSG_GETCURRENT, and MSG_GETDEFAULT capability operations, respectively. Each CapNamex setting must specify the containers to use for the 'GET' operation.
s1, s2 - Containers to use for setting the current value (SETCURRENT) and available values (SETAVAILABLE), respectively. Even though Twain actually has only one type of set operation, DTWAIN divides this into setting the current value and also setting a range of values (also know as limiting the range of available values to set). Each CapNamex setting must specify the containers to use for the 'SET' operation.
If g1, g2, g3, s1, or s2 is 0, the capability operation cannot be performed. The names of the containers for g1, g2, g3, s1, or s2 must be either TW_ONEVALUE, TW_ARRAY, TW_RANGE, TW_ENUMERATION or 0.
QUERYSUPPORT=x If the Source does not support MSG_QUERYSUPPORT, this setting will signal DTWAIN to not use the MSG_QUERYSUPPORT operation. If x=0, then MSG_QUERYSUPPORT is not supported. If x=1, then MSG_QUERYSUPPORT is supported. If the QUERYSUPPORT entry is missing, the default is that MSG_QUERYSUPPORT is not supported.
CapNamex_STATES If a capability can only be negotiated in specific Twain states, this setting allows DTWAIN to recognize that CapNamex can only be negotiated in these states. Usually, all capabilities (except for extended capabilities) can be negotiated in states 4 and above. However a few Sources do not handle some capability negotiations in state 4. Some capabilities can only be negotiated safely in state 5 (the Source is ready to acquire an image).
n1,n2,n3, etc. - The numeric states where the capability can be safely negotiated.
CapNamex_DATATYPE If a capability needs to have its data type set, this setting allows DTWAIN to recognize that CapNamex has one of the following data types:
TWTY_INT8 TWTY_UINT8 TWTY_BOOL TWTY_INT16 TWTY_INT32 TWTY_UINT16 TWTY_UINT32 TWTY_FIX32 TWTY_STR32 TWTY_STR64 TWTY_STR128 TWTY_STR255 TWTY_STR1024 TWTY_UNI512 TWTY_FRAME
The d1 must be one of the data types above. Once the data type is set, negotiating the capability will always use the the data type specified. So for example:
CAP_SUPPORTEDCAPS_DATATYPE=TWTY_UINT16
This specified that the CAP_SUPPORTEDCAPS data type will be a TWTY_UINT16.
Custom Capabilities
If the CapName specified a custom capability, the custom capability must be specified with the following format:
CUSTOMBASE+n
where n is equivalent to the custom capability number minus 32768. Note that there are no spaces between the '+' character, the 'CUSTOMBASE', and the number. The rule of no whitespace characters when specifying custom capabilities must be followed, if not DTWAIN will not recognize the capability name.
So for example, if the custom capability has the capability number of the hexadecimal number 0x8020 (decimal 32800), to specify that custom capability 0x8020 has a data type of TWTY_BOOL,
CUSTOMBASE+32_DATATYPE=TWTY_BOOL
To specify that you want all Sources, the following syntax is used:
[AllSources] QUERYSUPPORT=x
Note that [AllSources] has only one entry, namely QUERYSUPPORT. The value of QUERYSUPPORT can either be '1' to turn on MSG_QUERYSUPPORT for all Sources, or '0' to turn off MSG_QUERYSUPPORT for all Sources. If a Source has defined a QUERYSUPPORT option in the [ProductName] section, the QUERYSUPPORT in the [ProductName] section takes precedence.
Example of DTWAIN INI settings to override Source capability negotiation. |