Scan
Scan
Scan
Bear in mind that it was my second VB.NET project, so you will find some older VB
styles:
'Imports System
Imports System.Drawing
Imports System.Runtime.InteropServices 'required for <[In](), Out()> & MarshalAs
'NOTES: A structure can be allocated on the heap, a class will never be. An outside
app (or dll) can not write to this app's heap so that is why sometimes classes
' are used instead of structures. Otherwise there is no difference except that
classes need to be instanciated, and some classes have constructors.
'A scanner or camera is a Data Source (DS). The Data Source Manager (DSM) talks to
the DS. The app talks to the DSM via the single entry in the DLL.
'Category PrefixMART
'------------------- -------------------
'Data Groups DG_
'Data Argument Types DAT_
'Messages MSG_
'Capabilities CAP_, ICAP_ or ACAP_
'Return Codes TWRC_
'Condition Codes TWCC_
'Type Definitions TW_
'Structure Definitions TW_
'File Types TWFF_
Inherits System.Windows.Forms.Form
Implements IMessageFilter
Return mScan.FilterMessage(m)
End Function
Try
mLog.EnterProc(conProc, mconModule)
If bIntercept Then
Application.AddMessageFilter(Me)
Else
Application.RemoveMessageFilter(Me)
End If
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
End Class
#End Region
'***********************************************************************
****
'* *
'* CONSTANTS *
'* *
'***********************************************************************
****
'Strings to return when requesting the source and an explicit one is not selected
Public Const mconSouceUserSelect As String = "[UserSelect]"
Public Const mconSouceDefault As String = "[Default]"
'***********************************************************************
****
'* *
'* PUBLIC ENUMERATIONS *
'* *
'***********************************************************************
****
UInt16 = &H4
''' <summary>
''' a 32-bit unsigned integer
'''
''' TW_UINT32
''' </summary>
''' <remarks></remarks>
UInt32 = &H5
''' <summary>
''' a 16-bit unsigned integer
'''
''' TW_BOOL
''' </summary>
''' <remarks></remarks>
Bool = &H6
''' <summary>
''' TW_FIX32
''' </summary>
''' <remarks></remarks>
Fix32 = &H7
''' <summary>
''' TW_FRAME
''' </summary>
''' <remarks></remarks>
Frame = &H8
''' <summary>
''' an array of 8-bit signed integers with 34 elements
'''
''' TW_STR32
''' </summary>
''' <remarks></remarks>
Str32 = &H9
''' <summary>
''' an array of 8-bit signed integers with 66 elements
'''
''' TW_STR64
''' </summary>
''' <remarks></remarks>
Str64 = &HA
''' <summary>
''' an array of 8-bit signed integers with 130 elements
''' TW_STR128
''' </summary>
''' <remarks></remarks>
Str128 = &HB
''' <summary>
''' an array of 8-bit signed integers with less than 256 elements
''' TW_STR128
''' </summary>
''' <remarks></remarks>
Str255 = &HC
''' <summary>
''' an array of 8-bit signed integers with 1026 elements
''' TW_STR1024
''' ...added 1.9
''' </summary>
''' <remarks></remarks>
Str1024 = &HD
''' <summary>
''' an array of a 16-bit unsigned integer with 512 elements
'''
''' TW_UNI512
''' ...added 1.9
''' </summary>
''' <remarks></remarks>
Str512 = &HE
End Enum
'***********************************************************************
****
'* *
'* PRIVATE ENUMERATIONS *
'* *
'***********************************************************************
****
<Flags()> Private Enum twDG As Short
Control = &H1
Image = &H2
Audio = &H4
End Enum
ImageInfo = &H101
ImageLayout = &H102
ImageMemXfer = &H103
ImageNativeXfer = &H104
ImageFileXfer = &H105
CieColor = &H106
GrayResponse = &H107
RGBResponse = &H108
JpegCompression = &H109
Palette8 = &H10A
ExtImageInfo = &H10B
SetupFileXfer2 = &H301
End Enum
XFerReady = &H101
CloseDSReq = &H102
CloseDSOK = &H103
DeviceEvent = &H104
CheckStatus = &H201
OpenDSM = &H301
CloseDSM = &H302
OpenDS = &H401
CloseDS = &H402
UserSelect = &H403
DisableDS = &H501
EnableDS = &H502
EnableDSUIOnly = &H503
ProcessEvent = &H601
EndXfer = &H701
StopFeeder = &H702
ChangeDirectory = &H801
CreateDirectory = &H802
Delete = &H803
FormatMedia = &H804
GetClose = &H805
GetFirstFile = &H806
GetInfo = &H807
GetNextFile = &H808
Rename = &H809
Copy = &H80A
AutoCaptureDir = &H80B
PassThru = &H901
End Enum
'***********************************************************************
****
'* *
'* EXPORTED CALLS *
'* *
'***********************************************************************
****
'***********************************************************************
****
'* Function: DSM_Entry, the only entry point into the Data Source Manager.
'*
'* Parameters:
'* pOrigin Identifies the source module of the message. This could
'* identify an Application, a Source, or the Source Manager.
'*
'* pDest Identifies the destination module for the message.
'* This could identify an application or a data source.
'* If this is NULL, the message goes to the Source Manager.
'*
'* DG The Data Group.
'* Example: DG_IMAGE.
'*
'* DAT The Data Attribute Type.
'* Example: DAT_IMAGEMEMXFER.
'*
'* MSG The message. Messages are interpreted by the destination module
'* with respect to the Data Group and the Data Attribute Type.
'* Example: MSG_GET.
'*
'* pData A pointer to the data structure or variable identified
'* by the Data Attribute Type.
'* Example: (TW_MEMREF)&ImageMemXfer
'* where ImageMemXfer is a TW_IMAGEMEMXFER structure.
'*
'* Returns:
'* ReturnCode
'* Example: TWRC_SUCCESS.
'*
'***********************************************************************
****
'***********************************************************************
****
'* *
'* STRUCTURES / CLASSES *
'* *
'***********************************************************************
****
<StructLayout(LayoutKind.Sequential, Pack:=2, CharSet:=CharSet.Ansi)> Friend
Class twcIdentity
#Region "C++ Source"
'/* DAT_IDENTITY. Identifies the program/library/code resource. */
'typedef struct {
' TW_UINT32 Id; /* Unique number. In Windows, application hWnd
*/
' TW_VERSION Version; /* Identifies the piece of code */
' TW_UINT16 ProtocolMajor; /* Application and DS must set to
TWON_PROTOCOLMAJOR */
' TW_UINT16 ProtocolMinor; /* Application and DS must set to
TWON_PROTOCOLMINOR */
' TW_UINT32 SupportedGroups; /* Bit field OR combination of DG_ constants */
' TW_STR32 Manufacturer; /* Manufacturer name, e.g. "Hewlett-Packard" */
' TW_STR32 ProductFamily; /* Product family name, e.g. "ScanJet" */
' TW_STR32 ProductName; /* Product name, e.g. "ScanJet Plus" */
'} TW_IDENTITY, FAR * pTW_IDENTITY;
#End Region
Public Id As IntPtr '4
Public Version As twcVersion '42
Public ProtocolMajor As Short '2
Public ProtocolMinor As Short '2
Public SupportedGroups As Integer '4
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=34)> Public Manufacturer As
String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=34)> Public ProductFamily
As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=34)> Public ProductName As
String
'Flaw with this structure. Impossible to represent a negative fraction with out a whole
number.
<StructLayout(LayoutKind.Sequential, Pack:=2)> Friend Structure twsFix32
'Stores a fraction with 2 integers. The first carries the sign and is a whole number.
' The second is a fraction expressed as the numerator of a fraction with a
denominator of 65536.
#Region "C++ Source"
'/* Fixed point structure type. */
'typedef struct {
' TW_INT16 Whole; /* maintains the sign */
' TW_UINT16 Frac;
'} TW_FIX32, FAR *pTW_FIX32;
#End Region
Public Whole As Short
Public Frac As UInt16
End Sub
End Function
With Me
CapValueCopy.CapNumber = .CapNumber
CapValueCopy.ContainerType = .ContainerType
CapValueCopy.ItemType = .ItemType
CapValueCopy.Default = .Default
CapValueCopy.Current = .Current
CapValueCopy.NewValue = .NewValue
CapValueCopy.NumItems = .NumItems
CapValueCopy.MinValue = .MinValue
CapValueCopy.MaxValue = .MaxValue
CapValueCopy.StepSize = .StepSize
CapValueCopy.ItemList = .ItemList
End With
End Sub
Inherits CollectionBase
End Property
MyBase.List.Add(CapValue)
mintCount = mintCount + 1
End Sub
End Sub
Return List.Contains(CapValue)
End Function
List.CopyTo(array, intIndex)
End Sub
List.Insert(intIndex, CapValue)
mintCount = mintCount + 1
End Sub
Return List.IndexOf(CapValue)
End Function
MyBase.List.Remove(CapValue)
mintCount = mintCount - 1
End Sub
End Sub
End Sub
End Sub
End Class
'***********************************************************************
****
'* *
'* LOCAL VARIABLES *
'* *
'***********************************************************************
****
Private meState As scanTwainState 'Used in an attempt to track what state
TWAIN is in. May not be accurate if an error occurs.
Private mbDebugMessages As Boolean 'If true will display msgboxes.
Private mbSetCaps As Boolean 'If true will set the capabilities according to
the collection.
Private mbDS_Selected As Boolean 'Source gets selected in state 3. doesn't
change the state.
Private mintPageNumber As Integer 'Page number/counter. Used in the file
name.
Private mstrSourceName As String 'Name of the source that will attempt to be
explicitly opened.
Private mstrOpenedDSName As String 'Name of the actual source that gets
opened.
Private mstrScanDir As String 'Name of the directory will scanned files are
put.
Private mstrScanFileName As String 'Actual file name.
Private mstrScanFileNamePrefix As String 'Prefix of the name of the scanned file
(Batch number or ID).
Private meSourceSelect As scanSourceSelect 'Determines how the source will be
selected.
Private meSourceUI As scanSourceUI 'Determines if we will display the source's
UI.
Private meDestination As scanDestination 'Where should TWAIN put the image.
Private meFileType As scanFileType 'What format to dsave the file as.
Private frmMessageLoop As frmMessageIntercept
Private mtwApp As twcIdentity 'Structure to identify the calling app (this
code).
Private mtwSource As twcIdentity 'Used to identify the source the calling app is
talking to.
Private mtwImageInfo As twsImageInfo 'Holds info about the transfered image
Private mcolCaps As colCapValue 'Collection to hold capabilities to set befoer
a scan.
Private mLog As clsLogging 'Class to log errors and/or just any information.
Private mfrmCaller As frmMain 'Instanciates this class and functions as a
message pump for TWAIN.
'***********************************************************************
****
'* *
'* READ-ONLY PROPERTIES *
'* *
'***********************************************************************
****
Public ReadOnly Property CapsLoaded() As Boolean
Get
If Not mcolCaps Is Nothing Then
Return mcolCaps.Loaded
Else
Return False
End If
End Get
End Property
'***********************************************************************
****
'* *
'* PROPERTIES *
'* *
'***********************************************************************
****
'***********************************************************************
****
'* *
'* PRIVATE METHODS *
'* *
'***********************************************************************
****
Private Function DSM_Open() As Boolean
'***********************************************************************
******************
'* PURPOSE: Opens the DSM if it isn't already opened. *
'***********************************************************************
******************
'* RETURNS: TRUE if the DSM is open, or the command to open it succedes.
*
'***********************************************************************
******************
Const conProc As String = "DSM_Open"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* RETURNS: TRUE if the DS is selected, or the command to select one succedes.
*
'***********************************************************************
******************
Const conProc As String = "DS_Selected"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* PURPOSE: Opens a DS if it isn't already opened. *
'***********************************************************************
******************
'* RETURNS: TRUE if the DS is open, or the command to open it succedes.
*
'***********************************************************************
******************
Const conProc As String = "DS_Open"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* PURPOSE: Enables a DS if it isn't already enabled. *
'***********************************************************************
******************
'* RETURNS: TRUE if the DS is enabled, or the command to enable it succedes.
*
'***********************************************************************
******************
Const conProc As String = "DS_Enabled"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a OneValue container's data and fills a rctCapValue.
*
'***********************************************************************
******************
'* PARAMETERS: twCapability - A populated capability. *
'***********************************************************************
******************
'* RETURNS: A generic capability. *
'***********************************************************************
******************
Dim pOneValue As IntPtr
Dim intPosition As Integer
Dim CapValue As rctCapValue
Const conProc As String = "GetOneValue"
CapValue = New rctCapValue
Try
mLog.EnterProc(conProc, mconModule)
CapValue.CapNumber = twCapability.Cap
pOneValue = GlobalLock(twCapability.Handle)
With CapValue
.ContainerType = scanContainerType.OneValue
.ItemType = CType(GetInteger16(pOneValue, intPosition), scanItemType)
.Default = GetSpecificValue(CapValue.ItemType, pOneValue, intPosition)
.Current = GetSpecificValue(CapValue.ItemType, pOneValue, intPosition)
'.Default
End With
GlobalUnlock(CType(twCapability.Handle, Integer))
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return CapValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets an Enumeration container's data and fills a rctCapValue.
*
'***********************************************************************
******************
'* PARAMETERS: twCapability - A populated capability. *
'***********************************************************************
******************
'* RETURNS: A generic capability. *
'***********************************************************************
******************
Dim pEnum As IntPtr
Dim intPosition As Integer
Dim CapValue As rctCapValue
Const conProc As String = "GetEnum"
Try
mLog.EnterProc(conProc, mconModule)
CapValue.CapNumber = twCapability.Cap
pEnum = GlobalLock(twCapability.Handle)
With CapValue
.ContainerType = scanContainerType.Enumeration
.ItemType = CType(GetInteger16(pEnum, intPosition), scanItemType)
.NumItems = GetInteger32(pEnum, intPosition)
.Current = GetInteger32(pEnum, intPosition)
.Default = GetInteger32(pEnum, intPosition)
.ItemList = GetArrayMember(CapValue.ItemType, .NumItems, pEnum,
intPosition)
End With
GlobalUnlock(CType(twCapability.Handle, Integer))
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return CapValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets an Array container's data and fills a rctCapValue. *
'***********************************************************************
******************
'* PARAMETERS: twCapability - A populated capability. *
'***********************************************************************
******************
'* RETURNS: A generic capability. *
'***********************************************************************
******************
Dim pArray As IntPtr
Dim intPosition As Integer
Dim CapValue As rctCapValue
Const conProc As String = "GetArray"
Try
mLog.EnterProc(conProc, mconModule)
CapValue.CapNumber = twCapability.Cap
pArray = GlobalLock(twCapability.Handle)
With CapValue
.ContainerType = scanContainerType.Array
.ItemType = CType(GetInteger16(pArray, intPosition), scanItemType)
.NumItems = GetInteger32(pArray, intPosition)
.ItemList = GetArrayMember(CapValue.ItemType, .NumItems, pArray,
intPosition)
End With
GlobalUnlock(CType(twCapability.Handle, Integer))
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return CapValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a Range container's data and fills a rctCapValue. *
'***********************************************************************
******************
'* PARAMETERS: twCapability - A populated capability. *
'***********************************************************************
******************
'* RETURNS: A generic capability. *
'***********************************************************************
******************
Dim pRange As IntPtr
Dim intPosition As Integer
Dim CapValue As rctCapValue
Const conProc As String = "GetRange"
Try
mLog.EnterProc(conProc, mconModule)
CapValue.CapNumber = twCapability.Cap
pRange = GlobalLock(twCapability.Handle)
With CapValue
.ContainerType = scanContainerType.Range
.ItemType = CType(GetInteger16(pRange, intPosition), scanItemType)
.MinValue = CType(GetSpecificValue(CapValue.ItemType, pRange,
intPosition), Integer)
.MaxValue = CType(GetSpecificValue(CapValue.ItemType, pRange,
intPosition), Integer)
.StepSize = CType(GetSpecificValue(CapValue.ItemType, pRange,
intPosition), Integer)
.Default = GetSpecificValue(CapValue.ItemType, pRange, intPosition)
.Current = GetSpecificValue(CapValue.ItemType, pRange, intPosition)
End With
GlobalUnlock(CType(twCapability.Handle, Integer))
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return CapValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a value from a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: eItemType - The datatype of the read bytes. *
'* pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: An object containing the appropriate data type. *
'***********************************************************************
******************
Dim intWhole As Integer
Dim intFrac As Integer
Dim sngTemp As Single
Const conProc As String = "GetSpecificValue"
Try
mLog.EnterProc(conProc, mconModule)
Select Case eItemType
Case scanItemType.Int32
Return GetInteger32(pPointer, intOffset)
Case scanItemType.Frame
Return GetFrame(pPointer, intOffset)
Case scanItemType.UInt32
'Return GetInteger32(pPointer, intOffset)
Return Nothing
Case scanItemType.UInt16
Return GetUInteger16(pPointer, intOffset)
Case scanItemType.Str32
Return GetString32(pPointer, intOffset)
Case scanItemType.Str128
Return GetString128(pPointer, intOffset)
Case scanItemType.Str255
Return GetString255(pPointer, intOffset)
Case Else
MsgBox("Unexpected Item Type. Ignored")
Return Nothing
End Select
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return Nothing
End Function
'***********************************************************************
******************
'* PURPOSE: Gets an array from a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: eItemType - The datatype of the array element.
*
'* intCount - The number of elements. *
'* pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: An array with intCount items. *
'***********************************************************************
******************
Dim r As Integer
Dim aList() As Object
Const conProc As String = "GetArrayMember"
intCount -= 1
ReDim aList(intCount)
Try
mLog.EnterProc(conProc, mconModule)
For r = 0 To intCount
aList(r) = GetSpecificValue(eItemType, pPointer, intOffset)
Next
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return aList
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a short integer from a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A short integer. *
'***********************************************************************
******************
Dim shtReturnValue As Short
Const conProc As String = "GetInteger16"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return shtReturnValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets an unsigned short integer from a container class or structure.
*
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: An unsigned short integer. *
'***********************************************************************
******************
Dim shtReturnValue As Short
Dim ushtReturnValue As UInt16
Const conProc As String = "GetUInteger16"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return ushtReturnValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a integer from a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A integer. *
'***********************************************************************
******************
Dim intReturnValue As Integer
Const conProc As String = "GetInteger32"
Try
mLog.EnterProc(conProc, mconModule)
intReturnValue = Marshal.ReadInt32(pPointer, intOffset)
intOffset += 4
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return intReturnValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets an unsigned integer from a container class or structure.
*
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: An unsigned integer. *
'***********************************************************************
******************
Dim intReturnValue As Integer
Dim uintReturnValue As UInt32
Const conProc As String = "GetUInteger32"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return uintReturnValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a long integer from a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A long integer. *
'***********************************************************************
******************
Dim lngReturnValue As Long
Const conProc As String = "GetInteger64"
Try
mLog.EnterProc(conProc, mconModule)
lngReturnValue = Marshal.ReadInt64(pPointer, intOffset)
intOffset += 8
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return lngReturnValue
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a string from a container class or structure with a max length
of *
'* 32. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A string. *
'***********************************************************************
******************
Dim r As Integer
Dim origPosition As Int32 = intOffset
Dim byt As Byte
Dim strReturnedString As New System.Text.StringBuilder(34)
Dim strChar As Char
Const conProc As String = "GetString32"
Try
mLog.EnterProc(conProc, mconModule)
For r = 0 To 33
Next
intOffset = origPosition + 34
Return strReturnedString.ToString
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return strReturnedString.ToString
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a string from a container class or structure with a max length
of *
'* 128. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A string. *
'***********************************************************************
******************
Dim r As Integer
Dim origPosition As Int32 = intOffset
Dim byt As Byte
Dim strReturnedString As New System.Text.StringBuilder(130)
Dim strChar As Char
Const conProc As String = "GetString128"
Try
mLog.EnterProc(conProc, mconModule)
For r = 0 To 129
Next
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return strReturnedString.ToString
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a string from a container class or structure with a max length
of *
'* 255. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A string. *
'***********************************************************************
******************
Dim r As Integer
Dim origPosition As Int32 = intOffset
Dim byt As Byte
Dim strReturnedString As New System.Text.StringBuilder(257)
Dim strChar As Char
Const conProc As String = "GetString128"
Try
mLog.EnterProc(conProc, mconModule)
For r = 0 To 256
Next
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return strReturnedString.ToString
End Function
Friend Function GetFrame(ByVal pPointer As IntPtr, ByRef intOffset As Integer) As
twsFrame
'***********************************************************************
******************
'* PURPOSE: Gets a frame structure from a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A frame structure. *
'***********************************************************************
******************
Dim Frame As twsFrame
Return Frame
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a Fix32 structure from a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to read from. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE READ. IT IS PASSED ByRef. *
'***********************************************************************
******************
'* RETURNS: A Fix32 structure. *
'***********************************************************************
******************
Dim Fix32 As twsFix32
Const conProc As String = "GetFix32"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* PURPOSE: Puts a value into a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: eItemType - The datatype of the written bytes. *
'* pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutSpecificValue"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
Private Sub PutInteger8(ByVal byt As Byte, ByVal pPointer As IntPtr, ByRef intOffset
As Integer)
'***********************************************************************
******************
'* PURPOSE: Puts a byte into a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutInteger8"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Puts a short integer into a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutInteger16"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Puts a integer into a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutInteger32"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Puts a long integer into a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutInteger64"
Try
mLog.EnterProc(conProc, mconModule)
Marshal.WriteInt64(pPointer, intOffset, lng)
intOffset += 8
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Puts an unsigned short integer into a container class or structure.
*
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutUInteger16"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Puts an unsigned integer into a container class or structure. *
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutUInteger32"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
Private Sub PutUInteger64(ByVal ulng As UInt64, ByVal pPointer As IntPtr, ByRef
intOffset As Integer)
'***********************************************************************
******************
'* PURPOSE: Puts an unsigned long integer into a container class or structure.
*
'***********************************************************************
******************
'* PARAMETERS: pPointer - Pointer to the class or structure. *
'* intOffset - Number of bytes from the begining to write to. THIS *
'* PARAMETER WILL BE INCREMENTED BY THE NUMBER
OF BYTES THAT *
'* ARE WRITTEN. IT IS PASSED ByRef. *
'***********************************************************************
******************
Const conProc As String = "PutUInteger64"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Converts a decimal number into a Fix32 structure. *
'***********************************************************************
******************
'* PARAMETERS: sngValue - Number to convert. *
'***********************************************************************
******************
'* RETURNS: A Fix32 structure. *
'***********************************************************************
******************
Dim intWhole As Short
Dim uintFrac As UInt16
Dim twFix32 As twsFix32
Const conProc As String = "ConvertToFix32"
Try
mLog.EnterProc(conProc, mconModule)
Return twFix32
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* PURPOSE: Gets the current value of a capability no matter what type of
container *
'* it is in. *
'***********************************************************************
******************
'* PARAMETERS: sngValue - Number to convert. *
'***********************************************************************
******************
'* RETURNS: An object containing the appropriate value type. *
'***********************************************************************
******************
Const conProc As String = "GetCapValue"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return Nothing
End Function
Private Sub ErrorStatus()
'***********************************************************************
******************
'* PURPOSE: To gether error codes and possibly display them. *
'***********************************************************************
******************
Dim rc As twRC
Dim strMsg As String
Dim twStatus As twsStatus
Const conProc As String = "ErrorStatus"
Try
mLog.EnterProc(conProc, mconModule)
strMsg = "Failed because: CC = " & twStatus.ConditionCode & " and reserved =
" & twStatus.Reserved & "."
mLog.WriteMessage(strMsg)
If mbDebugMessages Then
MsgBox(strMsg)
End If
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Parses the windows message to determine: 1) If twain is responsible
AND *
'* 2) what twain is saying. *
'***********************************************************************
******************
'* PARAMETERS: m - Windows message. *
'***********************************************************************
******************
'* RETURNS: An enum indicating the twain command if there is one, or
specifically *
'* RETURNS: that it is not a twain command. *
'***********************************************************************
******************
Dim rc As twRC
Dim intPos As Integer
Dim WinMsg As WINMSG_S
Dim twEventMsg As twsEvent
Const conProc As String = "PassMessage"
Try
mLog.EnterProc(conProc, mconModule)
twEventMsg.EventPtr = Marshal.AllocHGlobal(Marshal.SizeOf(WinMsg))
intPos = GetMessagePos()
With WinMsg
.hwnd = m.HWnd
.message = m.Msg
.wParam = m.WParam
.lParam = m.LParam
.time = GetMessageTime()
.x = intPos
.y = CType(Int(intPos / 2 ^ 16), Integer)
End With
Return twTwainCommand.Null
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* PURPOSE: Gets the actual data (handle to a DIB; file transfer would be done
here *
'* also). *
'***********************************************************************
******************
'* RETURNS: An arraylist of handles to DIBs. *
'***********************************************************************
******************
Dim rc As twRC
Dim pics As ArrayList = New ArrayList()
Dim hbitmap As IntPtr 'pointer to a handle of a DIB
'Dim twFileXfer As twsSetupFileXfer
Dim twImageInfo As twsImageInfo
Dim twPendingXfers As twcPendingXfers
Const conProc As String = "TransferPictures"
Try
mLog.EnterProc(conProc, mconModule)
hbitmap = IntPtr.Zero
mintPageNumber = 1
Do
meState = scanTwainState.escanTransfering
twPendingXfers = New twcPendingXfers
twPendingXfers.Count = 0
hbitmap = IntPtr.Zero
'Begin transfer
'If meDestination = scanDestination.escanDestinationDIB Then
rc = DS_ImageNativeXfer(mtwApp, mtwSource, twDG.Image,
twDAT.ImageNativeXfer, twMSG.Get, hbitmap)
If (rc <> twRC.XferDone) Then
CleanUp()
Return pics
End If
'Else
' rc = DS_ImageFileXfer(mtwApp, mtwSource, twDG.Image,
twDAT.ImageFileXfer, twMSG.Get, vbNull)
' If (rc <> twRC.XferDone) Then
' CleanUp()
' Return pics
' End If
'End If
Catch ex As Exception
mLog.AddError(ex)
Return Nothing
Finally
mLog.ExitProc(conProc)
End Try
End Function
'***********************************************************************
******************
'* PURPOSE: Informs the DS (scanner) that we are done getting data.
*
'***********************************************************************
******************
Dim rc As twRC
Dim twPendingXfers As twcPendingXfers
Const conProc As String = "EndXfer"
Try
mLog.EnterProc(conProc, mconModule)
If rc = twRC.Success Then
If meState >= scanTwainState.escanTransferReady Then
meState = scanTwainState.escanDS_Enabled
End If
Else
If mbDebugMessages Then
MsgBox("Failed to disable the source, going to state 4 with a rc of " & rc)
End If
End If
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
****
'* *
'* PUBLIC METHODS *
'* *
'***********************************************************************
****
''' <summary>
''' Create an instance of the Scanner object
''' </summary>
''' <remarks></remarks>
Public Sub New(ByVal objLog As clsLogging)
Try
mLog = objLog
mLog.EnterProc(conProc, mconModule)
meState = scanTwainState.escanPresentation
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
''' <summary>
''' Creates the form to intercept windows messages
''' </summary>
''' <remarks></remarks>
Public Sub InstanciateMessageForm()
'***********************************************************************
******************
'* PURPOSE: Instanciates the form that will intercept windows messages.
*
'***********************************************************************
******************
Const conProc As String = "InstanciateMessageForm"
Try
mLog.EnterProc(conProc, mconModule)
If Not frmMessageLoop Is Nothing Then
frmMessageLoop.Dispose()
End If
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
''' <summary>
''' Opens the Data Source Manager (DSM)
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function OpenDSM() As Boolean
'***********************************************************************
******************
'* PURPOSE: Opens the DSM. App's Identity class gets filled here. *
'***********************************************************************
******************
'* RETURNS: TRUE on success. *
'***********************************************************************
******************
Dim rc As twRC
Dim myBuildInfo As FileVersionInfo
Const conProc As String = "OpenDSM"
Try
mLog.EnterProc(conProc, mconModule)
myBuildInfo = FileVersionInfo.GetVersionInfo(Application.ExecutablePath)
InstanciateMessageForm()
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
''' <summary>
''' Coose the Data Source (DS) that you wish to use
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function SelectDS() As Boolean
'***********************************************************************
******************
'* PURPOSE: Select a DS. Either the default, a user selected or an explicitly
*
'* entered name entered in the options form. *
'***********************************************************************
******************
'* RETURNS: TRUE on success. *
'***********************************************************************
******************
Dim rc As twRC
Dim twSourceOfSource As twMSG
Dim strMessage As String
Const conProc As String = "SelectDS"
Try
mLog.EnterProc(conProc, mconModule)
strMessage = ""
'Select the source. 0 for id and null for ProductName gets the default source. Can
be passed with twMSG.OpenDS to open the default, skipping twMSG.GetDefault
mtwSource = New twcIdentity
With mtwSource
.Id = CType(0, IntPtr)
If meSourceSelect = scanSourceSelect.escanSourceSpecific And
mstrSourceName <> vbNullString Then
.ProductName = mstrSourceName
Else
.ProductName = Chr(0) ' vbNullString
End If
.SupportedGroups = CType(twDG.Control Or twDG.Image, Integer)
End With
Return mbDS_Selected
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
''' <summary>
''' Opens the Data Source (DS)
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function OpenDS() As Boolean
'***********************************************************************
******************
'* PURPOSE: Opens a DS. Negociates any capabilities here. *
'***********************************************************************
******************
'* RETURNS: TRUE on success. *
'***********************************************************************
******************
Dim rc As twRC
Const conProc As String = "OpenDS"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
'''' <summary>
'''' Sets up the source for transfering data to a file
'''' </summary>
'''' <returns></returns>
'''' <remarks></remarks>
'Public Function NegociateFileXfer() As Boolean
' Try
' MsgBox("The scanner does not report that it supports file transfers",
MsgBoxStyle.Critical)
' Return False
' End If
' mLog.AddError(ex)
' Return False
' Finally
' mLog.ExitProc(conProc)
'End Function
''' <summary>
''' Sets up the source with capabilities from a passed in collection
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function NegociateCaps() As Boolean
'***********************************************************************
******************
'* PURPOSE: Goes through the collection of capabilities and attempts to set them.
*
'***********************************************************************
******************
'* RETURNS: TRUE if no errors encountered. *
'***********************************************************************
******************
Dim bCapsLoaded As Boolean
Dim INICapValue As rctCapValue
Dim NewCapValue As rctCapValue
Const conProc As String = "NegociateCaps"
Try
mLog.EnterProc(conProc, mconModule)
mcolCaps.Loaded = True
bCapsLoaded = True
End If
Return bCapsLoaded
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
''' <summary>
''' Kicks off the image capturing
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function EnableDS() As Boolean
'***********************************************************************
******************
'* PURPOSE: Enables the DS (allows it to start capturing) *
'***********************************************************************
******************
'* RETURNS: TRUE on success. *
'***********************************************************************
******************
Dim rc As twRC
Dim twInterface As twcUserInterface
Const conProc As String = "EnableDS"
Try
mLog.EnterProc(conProc, mconModule)
twInterface = New twcUserInterface
With twInterface
If meSourceUI = scanSourceUI.escanSourceHide Then
.ShowUI = CType(False, Short)
Else
.ShowUI = CType(True, Short)
End If
.ParentHand = mfrmCaller.Handle
End With
rc = DSM_EnableSource(mtwApp, mtwSource, twDG.Control,
twDAT.UserInterface, twMSG.EnableDS, twInterface)
If rc = twRC.Success Then
If mbDebugMessages Then MsgBox("Enabled: '" & mtwSource.ProductName
& "'"", State = " & meState & ".")
meState = scanTwainState.escanDS_Enabled
Return True
Else
ErrorStatus()
MsgBox(mconDSM_FailedToEnableSource & " with a rc of " & rc & ", State =
" & meState & "; and Name is " & mtwSource.ProductName, MsgBoxStyle.Critical)
Return False
End If
Catch ex As Exception
mLog.AddError(ex)
Return False
Finally
mLog.ExitProc(conProc)
End Try
End Function
''' <summary>
''' All steps required to capture an image using the defaults.
''' </summary>
''' <remarks></remarks>
Public Function Scan() As Boolean
'***********************************************************************
******************
'* PURPOSE: Calls all the methods required to scan. They may be called
individually *
'* or this method may be called. Operation would be the same. *
'***********************************************************************
******************
'* RETURNS: TRUE if state is raised to 5 (enable DS). *
'***********************************************************************
******************
Dim bAbort As Boolean
Dim strAppContext As String
Const conProc As String = "Scan"
strAppContext = vbNullString
Try
mLog.EnterProc(conProc, mconModule)
'Set some attributes that get set automatically thru the scanner's UI
If meSourceUI = scanSourceUI.escanSourceHide Then
strAppContext = "Pre NegociateCaps; meState = " & meState
If mbSetCaps Then
bAbort = Not NegociateCaps()
End If
End If
'Scan
If Not bAbort Then
strAppContext = "Pre DS_Enabled; meState = " & meState
If DS_Enabled() Then
'We wait for a message in the system message loop indicating that
the source is ready.
' When it is ready, it will be in state 6
' TWAIN 1.9; 7-224: That is, the Source should assert
MSG_XFERREADY as soon as it has data to transfer.
Return True
Else
MsgBox("Scan failed. " & mconDSM_FailedToEnableSource &
", State = " & meState & ".", MsgBoxStyle.Critical)
CleanUp()
End If
End If
Else
MsgBox("Scan failed. " & mconDSM_FailedToOpenSource & ", State
= " & meState & ".", MsgBoxStyle.Critical)
CleanUp()
End If
Else
MsgBox("Scan failed. " & mconDSM_FailedToSelectSource & ", State =
" & meState & ".", MsgBoxStyle.Critical)
CleanUp()
End If
Else
MsgBox("Scan failed. " & mconDSM_FailedToOpen & ", State = " &
meState & ".", MsgBoxStyle.Critical)
CleanUp()
End If
Else
MsgBox("No caller specified, operation cancelled.", MsgBoxStyle.Critical)
End If
Catch ex As Exception
mLog.AddError(ex, strAppContext)
Finally
mLog.ExitProc(conProc)
End Try
End Function
''' <summary>
''' Used in the message loop
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function FilterMessage(ByRef m As Message) As Boolean
'***********************************************************************
******************
'* PURPOSE: This is called from the callers message loop handler. After
PassMessage *
'* determines if it is a twain command, this will take the appropriate *
'* action depending on the message. Conclude the transfer when it is *
'* and Start transfering when the state reaches 6. *
'***********************************************************************
******************
'* RETURNS: FALSE if the message was for/from twain. Otherwise returns
TRUE (a *
'* windows message. *
'***********************************************************************
******************
Dim strContext As String
Dim pics As ArrayList
Dim cmd As twTwainCommand
Const conProc As String = "FilterMessage"
strContext = vbNullString
Try
mLog.EnterProc(conProc, mconModule)
cmd = PassMessage(m)
strContext = "After PassMessage"
If (cmd = twTwainCommand.Not) Then
Return False
End If
End Select
Return True
Catch ex As Exception
mLog.AddError(ex, strContext)
Finally
mLog.ExitProc(conProc)
End Try
End Function
''' <summary>
''' Call this when all images are captured.
''' </summary>
''' <remarks></remarks>
Public Sub DisalbeDS()
'***********************************************************************
******************
'* PURPOSE: Puts twain in a state to not receive transfers. Call this when *
'* capabilities need to be changed between captures. *
'***********************************************************************
******************
Dim rc As twRC
Dim twUI As twcUserInterface
Const conProc As String = "DisalbeDS"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
''' <summary>
''' Call this when finished with the source.
''' </summary>
''' <remarks></remarks>
Public Sub CloseDS()
'***********************************************************************
******************
'* PURPOSE: After the DS is disabled, it should be closed. *
'***********************************************************************
******************
Dim rc As twRC
Const conProc As String = "CloseDS"
Try
mLog.EnterProc(conProc, mconModule)
mbDS_Selected = False
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
''' <summary>
''' Call this when completely finished capturing all images.
''' </summary>
''' <remarks></remarks>
Public Sub CloseDSM()
'***********************************************************************
******************
'* PURPOSE: After the DS is closed, the DSM should follow suit. *
'***********************************************************************
******************
Dim rc As twRC
Const conProc As String = "CloseDSM"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
''' <summary>
''' Will try close everything in the proper order.
''' </summary>
''' <remarks></remarks>
Public Sub CleanUp()
'***********************************************************************
******************
'* PURPOSE: Calls all the ending procedures in order. *
'***********************************************************************
******************
Const conProc As String = "CleanUp"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
''' <summary>
''' Returns all the supported capabilities as a collection of objects.
''' </summary>
''' <remarks></remarks>
Public Function QueryCapabilities() As colCapValue
'***********************************************************************
******************
'* PURPOSE: Returns all the supported capabilities and values for a source.
*
'***********************************************************************
******************
'* RETURNS: Collection of capabilities. *
'***********************************************************************
******************
Dim r As Integer
Dim strContext As String
Dim CapValue As rctCapValue
Dim SupportedCaps As rctCapValue
Dim AllCapValues As colCapValue
Const conProc As String = "QueryCapabilities"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex, strContext)
Finally
mLog.ExitProc(conProc)
End Try
Return AllCapValues
End Function
''' <summary>
''' Do not need to call this.
''' </summary>
''' <remarks></remarks>
Protected Overrides Sub Finalize()
'***********************************************************************
******************
'* PURPOSE: Closes/disables everything we opened/enabled. *
'***********************************************************************
******************
Const conProc As String = "Finalize"
Try
mLog.EnterProc(conProc, mconModule)
CleanUp()
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Sub
'***********************************************************************
******************
'* PURPOSE: Gets a specific capability. *
'***********************************************************************
******************
'* RETURNS: Generic capability. *
'***********************************************************************
******************
Dim rc As twRC
Dim twCapability As twcCapability
Const conProc As String = "GetCapability"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return Nothing
End Function
'***********************************************************************
******************
'* PURPOSE: Gets a list of the file types that a source supports. *
'***********************************************************************
******************
'* RETURNS: An array of file types (extensions). *
'***********************************************************************
******************
Dim r As Integer
Dim intMaxIndex As Integer
Dim astrFileTypes() As String
Dim ReturnedFileTypes As rctCapValue
Const conProc As String = "GetFileTypes"
Try
mLog.EnterProc(conProc, mconModule)
ReturnedFileTypes = GetCapability(scanCap.ImageFileFormat)
intMaxIndex = ReturnedFileTypes.NumItems - 1
ReDim astrFileTypes(intMaxIndex)
For r = 0 To intMaxIndex
astrFileTypes(r) = CType(ReturnedFileTypes.ItemList(r),
scanFileType).ToString
Next
Return astrFileTypes
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
Return Nothing
End Function
'***********************************************************************
******************
'* PURPOSE: Sets a specific capability passed in by a generic capability. *
'***********************************************************************
******************
'* RETURNS: TRUE if successfull. *
'***********************************************************************
******************
Dim rc As twRC
Dim pOneValue As IntPtr
Dim intOffest As Integer
Dim twCapability As twcCapability
'Dim twArray As twsArray
'Dim twEnum As twsEnumeration
Dim twOneValue As twsOneValue
'Dim twRange As twsRange
Const conProc As String = "SetCapability"
Try
mLog.EnterProc(conProc, mconModule)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
If rc = twRC.Success Then
Return True
Else
ErrorStatus()
Return False
End If
End Function
End Class
[/CODE]
Right now it requires this class for logging, although it isn't complete, it served my
purpose:
[CODE]' From Access 2000 Developer's Handbook, Volume I
' by Getz, Litwin, and Gilbert. (Sybex)
' Copyright 1999. All Rights Reserved.
' Converted to .Net by John Maher
'Instructions
'------------
'
'1). Instanciate a new instance of this object (clsLogging)
'2). Set the output location for errors, default is AppPath
'3). Set the output location for logs, default is AppPath
'4). Upon entering a sub or function, call clsProcedureStack.EnterProc("Sub or
Function Name", "Module Name", optional context)
'5). Upon exiting a sub or function, call clsProcedureStack.ExitProc("Sub or Function
Name", optional context)
'6). When encountering an error, call AddError(ex) where ex is the exception
'
'Modifications
'-------------
'
'1/25/10 - JPM modified to get the logged in user instead of relying on a global. Also
excluded the database info since we use only one.
' Added a New methoid to set the objects. Also added 2 methods and changed
global to private. This is planned to be a relocatable mod.
' Eliminated object ProcedureStack and move the functions and modular-level
ProcStach object to the root of this object
'
'1/26/10 - Added logging of procs.
'
'
'TODO
'----
MyBase.New()
mcolErrors = New colSavedErrors
End Sub
mcolErrors.Add(ex, strAppContext)
HandleError(bSupressMessage)
End Sub
'If this is the top proc then start the string from scratch
If mobjTopProc Is Nothing Then
mstrProcLog = vbNullString
End If
End Function
Public Function ExitProc(ByVal strName As String, Optional ByVal strContext As
String = vbNullString) As Boolean
' This pops a procedure off the stack--
' To enforce FILO behavior we check the
' strName passed in against that of the top
' procedure
mobjTopProc = mobjTopProc.NextProc
ExitProc = True
Else
MsgBox("Error. Trying to pop wrong procedure. " & _
"You passed '" & strName & "'. " & _
"Current procedure is '" & _
mobjTopProc.Name & "'.", vbCritical)
End If
End If
End Function
intFile = FreeFile()
If mstrLogPath <> vbNullString Then
strLogPath = mstrLogPath
Else
strLogPath = System.AppDomain.CurrentDomain.BaseDirectory &
mconProcLogFile
End If
FileOpen(intFile, strLogPath, OpenMode.Append)
PrintLine(intFile, StrDup(60, "="))
PrintLine(intFile, "Date: " & Now & ", ")
Print(intFile, mstrProcLog)
PrintLine(intFile, vbNullString)
FileClose(intFile)
End Sub
'JPM MOD 1/26/10 END
' LOHCo Modified to print only, not use their error reporting form.
Public Function HandleError(Optional ByVal bSupressMessage As Boolean = False)
As Integer
'JPM MOD - added optional parameter to supress printing of the general error
message. Useful if the app displays a more meaningfull message.
'JPM MOD 3/10/10 Moved this from above the FreeFile command to display
some more meaningful information
' Set pointer to last error that occurred.
objLastError = mcolErrors.LastError
objProc = TopProc()
strProcList = "Procedure Stack:" & vbCrLf
Do Until objProc Is Nothing
strProcList = strProcList & " Module: " & objProc.Module _
& " Procedure: " & objProc.Name & vbCrLf
objProc = objProc.NextProc
Loop
intFile = FreeFile()
FileOpen(intFile, ErrorLogPath, OpenMode.Append)
PrintLine(intFile, StrDup(60, "-"))
PrintLine(intFile, "Date: " & Now & ", ")
'JPM MOD 1/25/10 BEGIN3 of 4
Print(intFile, "User: " & strBuffer & ", ")
'Print(intFile, "DataBase: " & CurrentDb().Name)
'JPM MOD 1/25/10 END3 of 4
Print(intFile, strProcList)
Print(intFile, "Description: " & objLastError.Description & " ")
Print(intFile, "Application Context: " & objLastError.AppContext)
PrintLine(intFile, vbNullString)
FileClose(intFile)
'LOHCo Mod End
'LOHCo Mod
' Return constant to exit through the procedure's Exit_Procedure.
Return mconExitSub
'LOHCo Mod End
End Function
strBuffer = SystemInformation.UserName
intFile = FreeFile()
FileOpen(intFile, ErrorLogPath, OpenMode.Append)
PrintLine(intFile, StrDup(60, "="))
PrintLine(intFile, "Date: " & Now & ", ")
Print(intFile, "User: " & strBuffer & ", ")
Print(intFile, strMsg)
PrintLine(intFile, vbNullString)
FileClose(intFile)
End Sub
'JPM MOD 3/17/10 END
strDrives = vbNullString
For i = 256 To 65535 Step 256
strDrives = Space(i)
lngRet = GetLogicalDriveStrings(Len(strDrives), strDrives)
If lngRet < Len(strDrives) Then
Exit For
End If
Next i
Erase atyp
iBeg = 1
iEnd = InStr(iBeg, strDrives, Chr(0))
Do Until iEnd = iBeg
ReDim Preserve atyp(UBound(atyp) + 1)
iatyp = UBound(atyp)
atyp(iatyp).strDrive = Mid$(strDrives, iBeg, iEnd - iBeg)
atyp(iatyp).intType = GetDriveType(atyp(iatyp).strDrive)
fRet = DiskSpace(atyp(iatyp).strDrive, atyp(iatyp).curSize, atyp(iatyp).curFree)
If fRet Then
atyp(iatyp).fValid = True
Else
atyp(iatyp).curFree = 0
atyp(iatyp).curSize = 0
atyp(iatyp).fValid = False
End If
iBeg = iEnd + 1
iEnd = InStr(iBeg, strDrives, Chr(0))
Loop
Exit Sub
adhFreeDiskSpaceErr:
Select Case Err.Number
Case 9 'Subscript out of range
ReDim atyp(0)
Resume Next
'LOHCo Mod 11/15/06
'Case Else
'Stop
'LOHCo Mod End
End Select
End Sub
hModule = LoadLibrary("kernel32.DLL")
If hModule <> 0 Then
lngAddress = GetProcAddress(hModule, "GetDiskFreeSpaceExA")
End If
IsGetDiskFreeSpaceExOK = (lngAddress <> 0)
End Function
If IsGetDiskFreeSpaceExOK() Then
Dim curFreeToMe As Decimal
Dim curTotalBytes As Decimal
Dim curFreeBytes As Decimal
If GetDiskFreeSpaceEx(strDrive, _
curFreeToMe, curTotalBytes, curFreeBytes) Then
curTotal = curTotalBytes * 10000
curFree = curFreeBytes * 10000
DiskSpace = True
End If
Else
Dim intSectorsPerCluster As Integer
Dim intBytesPerSector As Integer
Dim intNumberOfFreeClusters As Integer
Dim intTotalNumberOfClusters As Integer
If GetDiskFreeSpace(strDrive, intSectorsPerCluster, _
intBytesPerSector, intNumberOfFreeClusters, intTotalNumberOfClusters) Then
curTotal = intBytesPerSector * intSectorsPerCluster *
intTotalNumberOfClusters
curFree = intBytesPerSector * intSectorsPerCluster *
intNumberOfFreeClusters
DiskSpace = True
End If
End If
End Function
'***********************************************************************
**********************
'* *
'* clsProcedure *
'* *
'***********************************************************************
**********************
End Class
'***********************************************************************
**********************
'* *
'* clsSavedError *
'* *
'***********************************************************************
**********************
Class clsSavedError
' Source.
Public Property Source() As String
Get
Return mstrSource
End Get
Set(ByVal value As String)
mstrSource = value
End Set
End Property
' Description.
Public Property Description() As String
Get
Return mstrDescription
End Get
Set(ByVal value As String)
mstrDescription = value
End Set
End Property
' DateTime.
Public Property DateTime() As Date
Get
Return mdatDateTime
End Get
Set(ByVal value As Date)
mdatDateTime = value
End Set
End Property
' Procedure.
Public Property Procedure() As String
Get
Return mstrProcedure
End Get
Set(ByVal value As String)
mstrProcedure = value
End Set
End Property
' EmpID.
Public Property EmpID() As String
Get
Return mstrEmpID
End Get
Set(ByVal value As String)
mstrEmpID = value
End Set
End Property
'LOHCo Mod End
Return mstrID
End Function
End Class
'***********************************************************************
**********************
'* *
'* colSavedErrors *
'* *
'***********************************************************************
**********************
Class colSavedErrors
MyBase.New()
Reset()
mcolErrors = New Collection
End Sub
'mcolErrors.Add(objSavedError, objSavedError.ID)
mcolErrors.Add(objSavedError)
Return objSavedError
End Function
Reset()
mcolErrors = New Collection
End Sub
Reset()
Return CType(Me, IEnumerator)
End Function
End Function
End Function
mintIndex += 1
Return (mintIndex <= mcolErrors.Count)
End Function
End Sub
Public Sub Reset() Implements IEnumerator.Reset
mintIndex = 0
End Sub
End Class
End Class
[/CODE]
Useage:
[CODE] Private mScan As clsScan
Try
mLog.EnterProc(conProc, mconModule)
If mbBatchScan Then
mbBatchScan = False
MsgBox("Unable to save file. Please check that the capabilities are set
correctly and permissions / disk space")
mLog.AddError(ex, "System.ArgumentException: Sometimes caused when
trying to convert a color BMP to TIFF", True)
Catch ex As Exception
mLog.AddError(ex)
Finally
mLog.ExitProc(conProc)
End Try
End Set
End Property
[/CODE]
[DataAccess]
Database=TestERP
[Debug]
MessagesDisplay=False
[Destination]
Return=0
DIBSaveAsFileType=JPEG
ScannerSaveAsFileType=TIFF
[Source]
Select=0
UI=0
[Capabilities]
1= 0
257= 0
4098= 0
4099= 0
4103= 0
4109= 0
4110= 0
4111= 0
4112= 0
4116= 0
4117= 0
4369= 0
4370= 0
4376= 150
4377= 150
4378= 0
4399= 0
4400= 0
4401= 0
4432= 0
4433= 0
32797= 0
32817= 1
32876= 0
[/CODE]
Return colCaps
End Function
[/CODE]
Although that may be unnecessary, you can go with the defaults and manually change
things as you need. Just trying to give you everything I can think of.