views:

443

answers:

3

I have a VB.NET application and use some third party (closed source) ActiveX controls. One of the controls represents a "camera" (connected over several interfaces) and I try to write an example how to work with several cameras in one application. To do this I allocate multiple "camera" objects dynamically as an array which works as expected like this:

Const NUM_CAMERAS = 2
Private MyCameras(NUM_CAMERAS ) As xxx.MCamera

But the camera objects needs to be allocated with WithEvents because they raise events when a new image was taken. I found out that WithEvents variables cannot be typed as arrays and this is a pretty common problem so I also found some workarounds: http://www.dreamincode.net/code/snippet885.htm http://www.xtremevbtalk.com/archive/index.php/t-223970.html

This is already pretty helpful and I adopted this to my concept. So I have a MyCameras array and a MyCamera all "without Events", first allocate a new MyCamera object, add a event handler and then put it into the array. Unfortunately I get an error when calling

AddHandler Camera.ProcessModifiedImage, AddressOf MyHook

Normally "MyHook" is declared as

Private Sub MyHook (ByVal sender As Object, ByVal ModifiedBuffer As xxx.ProcessModifiedImageEvent) Handles Camera.ProcessModifiedImage

Like in the "Button examples" I just removed the "Handles Camera.ProcessModifiedImage" but I get an error that "MyHook" has not the same signature as the Delegate

Delegate Sub ICameraEvents_ProcessModifiedImageEventHandler(ImageIndex as Integer)

Has anyone an idea how to get around this and what to change? I can post more code and details tomorrow if necessary.

+1  A: 

The "MyHook" event handler needs to have the same signature (i.e. accept the same argument types in the same order) as the delegate. Since the desired delegate accepts an integer argument called ImageIndex you could declare the the MyHook event handler as:


Private Sub MyHook(ImageIndex as Integer)

End Sub
With multiple cameras, how will he then figure out which camera raised the event?
Joel Coehoorn
It's not clear to me from the original post that that is necessary. Is it a requirement to know which camera is invoking the hook? From the posted code a handler is being added to a generic "camera" object. If you need to know which camera is being invoked then you would need a separte handler...
... (continued) for each of the "camera objects" in your MyCamera() array. AddHandler MyCamera(0), AddressOf MyHook0; AddHandler MyCamera(1), AddressOf MyHook1; etc.. etc..
Of course, without seeing the actuall third party ActiveX control's class/interface, I can only speculate and offer generic advice.
I edited the original post, the handler is not added to a generic object and I need to know in the event which camera raised it.
asdrubael
Then, given my limited knowledge of the situation, you would need a separate handler for each Camera object.
A: 

The error is telling you what you need -- your event handler's signature must match the delegate they've specified (a subroutine with one ImageIndex parameter)

So you want

Private Sub MyHook(ImageIndex as Integer)

You've probably seen all event handlers be in the format sub myhook(sender as object, e as XXEventArgs)

This is a convention microsoft uses for their .NET events, but not required. Your third party tool apparently doesn't follow that convention. Just follow the message when it tells you what the delegate signature must look like.

Clyde
+1  A: 

Following up on the comments to Waves' post, you can elegantly handle the missing "sender" argument with a lambda expression:

  Public Sub New()
    InitializeComponent()
    For camera As Integer = 1 To 4
      Dim cam As Camera = DirectCast(Me.Controls("Camera" + camera.ToString), Camera)
      AddHandler cam.ProcessModifiedImage, Function(index As Integer) ProcessImage(cam, index)
    Next
  End Sub

  Private Function ProcessImage(ByVal cam As Camera, ByVal ImageIndex As Integer) As Integer
    ' Your code here
    '...
    Return 0
  End Function
Hans Passant
What version of .NET are you using? I can't seem to get the "lambda" anonymous "Function(index as integer)" construct to work under .NET 2.0.
You'll need VB.NET version 9, the one that shipped in VS2008. Worth the upgrade, if only for Linq.
Hans Passant