Hello,
I am working on an application to scan in VB.NET using TWAIN. but I am having problems with the structures and am getting incorrect data. I created a class in C++ and found that one of the VB structures (twsIdentity) is 156 bytes using Marshal.SizeOf. i even tried eliminating the new method and declaring Version as new but it didn't matter.
<StructLayout(LayoutKind.Sequential, Pack:=2, CharSet:=CharSet.Ansi)> Friend Class twsIdentity '***MAR
Public Id As IntPtr '4
Public Version As twsVersion '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
Public Sub New()
MyBase.New()
Version = New twsVersion
End Sub
End Class
<StructLayout(LayoutKind.Sequential, Pack:=2, CharSet:=CharSet.Ansi)> Friend Class twsVersion '***MAR
Public MajorNum As Short
Public MinorNum As Short
Public Language As Short
Public Country As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=34)> Public Info As String
End Class
I can't pass the structure between C++ and VB. I assume because the structure in C is 160 bytes using sizeof.
typedef unsigned short TW_UINT16;
typedef unsigned long TW_UINT32;
typedef char TW_STR32[34];
struct TW_VERSION{
TW_UINT16 MajorNum; /* Major revision number of the software. */
TW_UINT16 MinorNum; /* Incremental revision number of the software. */
TW_UINT16 Language; /* e.g. TWLG_SWISSFRENCH */
TW_UINT16 Country; /* e.g. TWCY_SWITZERLAND */
TW_STR32 Info; /* e.g. "1.0b3 Beta release" */
};
struct TW_IDENTITY{
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" */
};
Although when I use this structure (twsIdentity) in VB (calling twain_32.dll) and pass it to the dll, I get it back OK. I get problems from another structure () when I try to set the capabilities of the scanner. I was going to set the capabilities in a C dll to see if that fixes if, but then I can't pass the twsIdentity structure between C and VB. I could try moving all the functionality to a C DLL, but the boss wants the app done in VB. I just want to know what I am doing wrong. Any ideas?
Here is the VB structure that I can't get any good data from:
<StructLayout(LayoutKind.Sequential, Pack:=2)> Private Structure twsCapability '***MAR
Public Cap As twCap 'short
Public ConType As twContainerTyoe 'short
Public Handle As IntPtr 'Pointer to a container
End Structure
copied from this structure:
typedef struct {
TW_UINT16 Cap; /* id of capability to set or get, e.g. CAP_BRIGHTNESS */
TW_UINT16 ConType; /* TWON_ONEVALUE, _RANGE, _ENUMERATION or _ARRAY */
TW_HANDLE hContainer; /* Handle to container of type Dat */
} TW_CAPABILITY, FAR * pTW_CAPABILITY;
And here is the code that tries to get the data from the dll (which allocates the space for it)
...other code comes before
twCapability = New twsCapability
With twCapability
.Cap = twCap.IPhysicalWidth
'.ConType = 7 'TWON_DONTCARE16
'.Handle = Nothing
End With
strWidth = GetOneValue(twCapability)
...other code follows
Private Function GetOneValue(ByVal twCapability As twsCapability) As String
Dim rc As twRC
Dim strTemp As String
Dim twOneValue As TW_ONEVALUE
rc = DS_Capability(mtwApp, mtwSource, twDG.Control, twDAT.Capability, twMSG.Get, twCapability)
If rc = twRC.Success Then
strTemp = vbNullString
Select Case twCapability.ConType
Case twContainerTyoe.One
twOneValue = New TW_ONEVALUE
Marshal.PtrToStructure(twCapability.Handle, twOneValue)
strTemp = CType(twOneValue.Item, String)
Case Else
MsgBox("Error, one value expected; " & twCapability.ConType & " returned.")
End Select
Marshal.FreeHGlobal(twCapability.Handle)
Return strTemp
Else
ErrorStatus()
Return vbNullString
End If
End Function
Any help is appreciated, if anyone can direct me to any dull reading that may help me I will read it!!
Thanks for looking
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.