I have an COM Class, used for Twain Scanning, that I want to use. The creation of the COM Object is working fine. Also calling methods on this object is okay.
But the problem is that I need to add an EventHandler to this object. With as extra difficulty that one of the types is a custom time from within this COM Object.
The problem is now, when I attach the handler. The error message is :
Object of type 'System.EventHandler' cannot be converted to type 'TwainCOMWrapper.AcquirePageEventHandler'
I have tried several solutions found on google. Like:
Call a method when a generic event occurs
https://msdn.microsoft.com/en-us/library/ms228976%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396
Also I tried to build my sample application in VB.NET and C#.NET. But no result.
Other error message I had:
Cannot implicitly convert type 'TwainCOMWrapperTester.Form1.AcquirePageDelegate' to 'TwainCOMWrapper.AcquirePageEventHandler'
Unable to cast object of type VB$AnonymousDelegate to type
...
I guess the problem is that my method "AcquirePageHandler" is not with the exact correct type from the COM Object.
What I also tried is to create the class in my own project. With same specs. But this also gives an error.
Relevant part of COM Class:
namespace TwainCOMWrapper
{
// Use to create COM events
public delegate void AcquirePageEventHandler(Object sender, COM_TwainAcquirePageEventArgs e);
// Create IDispatch Interface for COM events
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("4ac3c1a3-3407-4730-8c27-06e894b172d1")]
public interface IEventsInterface
{
[DispId(1)]
void AcquirePage(Object sender, COM_TwainAcquirePageEventArgs e);
}
[Guid("d98471bb-34ad-4efc-8fe7-ffc9c35f2289")]
[ComSourceInterfaces(typeof(IEventsInterface))]
[ComVisible(true)]
[ProgId("Leadtools.TwainCOMWrapper")]
public class TwainCOMClass : UserControl
{
// .NET Twain class (This is what we are wrapping)
public TwainSession _twSession = null;
// The COM event
public event AcquirePageEventHandler AcquirePage;
// Twain COM constructor
public TwainCOMClass()
{
_twSession = new TwainSession();
}
[HandleProcessCorruptedStateExceptions]
public string Acquire(bool ShowUI, bool ShowModal)
{
try
{
if (_twSession != null)
{
TwainUserInterfaceFlags flags = TwainUserInterfaceFlags.None;
if (ShowUI)
{
flags = TwainUserInterfaceFlags.Show;
if (ShowModal)
flags |= TwainUserInterfaceFlags.Modal;
}
_twSession.AcquirePage += new EventHandler<TwainAcquirePageEventArgs>(_twSession_AcquirePage);
_twSession.Acquire(flags);
_twSession.AcquirePage -= _twSession_AcquirePage;
return "Scan OK";
}
else
return "Twain Session is null";
}
catch (Exception ex)
{
return ex.Message;
}
}
[HandleProcessCorruptedStateExceptions]
void _twSession_AcquirePage(object sender, TwainAcquirePageEventArgs e)
{
try
{
if (AcquirePage != null)
{
COM_TwainAcquirePageEventArgs args = new COM_TwainAcquirePageEventArgs(e.Image, _isBW, _compression);
AcquirePage(this, args);
}
}
catch
{
return;
}
}
}
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("b356f142-8781-46bb-8343-44674eac86b0")]
[ComVisible(true)]
public class COM_TwainAcquirePageEventArgs : EventArgs
{
private byte[] _buffer;
private String _error = "";
private String _log = "";
public String Log
{
get { return _log; }
}
public String Error
{
get { return _error; }
}
public byte[] Image
{
get { return _buffer; }
}
public COM_TwainAcquirePageEventArgs()
{
_buffer = null;
}
public COM_TwainAcquirePageEventArgs(RasterImage image, Boolean bw, int iQuality)
{
try
{
MemoryStream ms = new MemoryStream();
RasterCodecs codecs = new RasterCodecs();
try
{
if (bw)
{
codecs.Save(image, ms, RasterImageFormat.CcittGroup4, image.BitsPerPixel, 1, image.PageCount, 1, CodecsSavePageMode.Append);
}
else
{
codecs.Options.Jpeg.Save.QualityFactor = (int)(iQuality * 2.55 + 2);
codecs.Save(image, ms, RasterImageFormat.Jpeg, image.BitsPerPixel, 1, image.PageCount, 1, CodecsSavePageMode.Append);
}
}
catch (Exception)
{
if (!bw)
{
MemoryStream nms = new MemoryStream();
codecs.Save(image, nms, RasterImageFormat.Png, image.BitsPerPixel, 1, image.PageCount, 1, CodecsSavePageMode.Append);
codecs.Convert(nms, ms, RasterImageFormat.Jpeg, 0, 0, 0, null);
}
}
_buffer = ms.GetBuffer();
ms.Dispose();
}
catch (Exception ex)
{
_error = ex.Message;
_buffer = null;
}
}
}
}
My test program:
Imports System.Reflection
Public Class Form1
Private TwainSession As Object
Public Delegate Sub AcquirePageEventHandler(sender As Object, e As Object)
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Try
Initialize()
Catch ex As Exception
MessageBox.Show(ex.Message & Environment.NewLine & ex.StackTrace)
End Try
End Sub
Private Sub Initialize()
Dim comType As Type = Type.GetTypeFromProgID("Leadtools.TwainCOMWrapper")
TwainSession = Activator.CreateInstance(comType)
If TwainSession.IsAvailable() Then
TwainSession.Startup("manufacturer", "productFamily", "version", "application")
Else
MessageBox.Show("TwainSession.IsAvailable = false(1) ")
Exit Sub
End If
Dim evAcquirePage As EventInfo = comType.GetEvent("AcquirePage")
evAcquirePage.AddEventHandler(TwainSession, New EventHandler(AddressOf AcquirePageHandler))
If TwainSession IsNot Nothing Then
TwainSession.GetColors()
Else
Exit Sub
End If
Dim tScanError As String = TwainSession.Acquire(False, False)
MessageBox.Show("OK!") '"Scan OK"
End Sub
Private Sub AcquirePageHandler(sender As Object, e As Object)
Try
MessageBox.Show("[Debug info]" & vbCrLf & "Error Information: " & IIf(e.Error = "", "All OK!", e.Error) & vbCrLf & "Log:" & vbCrLf & e.Log)
Catch ex As Exception
End Try
End Sub
End Class