Solved

Events from multiple COM objects into same form

Posted on 2002-05-20
9
133 Views
Last Modified: 2013-11-25

I have a com object that has a callback interface.  I would like to have multiple com objects instanced in a form with all of them having their callback interfaces sinked on that form.  

The way I have tried to do it so far is to have a tmp variable defined public with events on the form and I new multiple objects onto that varaible (being sure to store the objects onto a collection).  The problem I am having is that as soon as I new a new object, the old object releases.  

How do I keep multiple objects firing events into the same form?  Im guessing I need to up the ref count on the object so it doesn't go away?  How do I do that?

0
Comment
Question by:Adept
  • 4
  • 3
  • 2
9 Comments
 
LVL 28

Expert Comment

by:AzraSound
ID: 7021579
It sounds like maybe you are doing something like:

Public WithEvents t As COMObject


Private Sub Command_Click()
    Dim x As New COMObject

    Set t = x
End Sub


Each time you do that, you reset t to a new COMObject, regardless of whether you are adding to a collection or not.  The t object only points to one place in memory, and it cannot reference multiple places.  You need to create an additional "collection" type class that handles your events.  You will need some value to distinguish each COM object so that you know which one is firing the event.

0
 
LVL 28

Expert Comment

by:AzraSound
ID: 7021603
BTW, sample at the following link demonstrating this idea (called objArrays.zip)

http://www.mvps.org/vb/index2.html?samples.htm
0
 

Author Comment

by:Adept
ID: 7023169

either I don't fully understand your answer or I didn't phrase the question very well.  I'm not having a hard time sinking the event, that is working fine.  I'm having a hard time sinking multiple events to one form from muiltple instances of a COM object.  Currently this is what I'm doing (that isn't working)


Dim WithEvents casTmp As CasFileTransfer

Public Sub formTransfers_InitiateTransfer(tmpResult As CasSearchResult)

    Dim strKey As String
    strKey = tmpResult.bstrFileName
   
   
    mapTransfers.Add casTmp, strKey
    listDownloads.ListItems.Add 1, strKey, strKey

    Set casTmp = New CasFileTransfer
    casTmp.AddSource tmpResult.bstrIP, tmpResult.nPort, tmpResult.nFileSize, tmpResult.nHashCode, tmpResult.bstrFileName

End Sub





0
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

 
LVL 28

Expert Comment

by:AzraSound
ID: 7023268
>>Set casTmp = New CasFileTransfer

This "resets" the variable each time it is called.  Any sources you have added via the AddSource method have been lost.

It looks like you have your collection, mapTransfers, so that is somewhat ok, but you still cannot use a plain collection.  You must define your OWN collection type class, that keeps track of each COM object instantiated, and it is this custom collection class that will raise events, not an individual CasFileTransfer object.
0
 

Author Comment

by:Adept
ID: 7023303

k, I'm modestly new to VB but I'm experienced at c++ (so please bear with me).  :)

how could I make a collection class that could sink these events?  is that what you mean that I create a seperate collection class that accepts the events and then pass them on (if so how would I do this)?  any code examples would help too.

ty
0
 
LVL 28

Accepted Solution

by:
AzraSound earned 100 total points
ID: 7024079
Ok, here is a quick sample I worked up.  The only problem with this approach is that there is a circular reference because the item object must know who his parent is.  The sample uses a form with two command buttons and two classes:


'First Class - CItem
Event ItemEvent(ByVal Name As String)


Public ParentObject As CCollection
Public Name         As String


Public Function EventRaisingFunction()
    Call ParentObject.ItemEvent(Name)
End Function



'Second Class - CCollection
Event CollectionEvent(ByVal ItemName As String)



Private m_colItems  As Collection


Public Property Get NewEnum() As IUnknown
   Set NewEnum = m_colItems.[_NewEnum]
End Property


Public Function GrabItem(ByVal ItemName As String) As CItem
    Set GrabItem = m_colItems.Item(ItemName)
End Function


Friend Function ItemEvent(ByVal Name As String)
    RaiseEvent CollectionEvent(Name)
End Function


Public Function AddItem(ByVal Item As CItem, ByVal ItemName As String)
    Set Item.ParentObject = Me
    Item.Name = ItemName
    m_colItems.Add Item, ItemName
End Function




Private Sub Class_Initialize()
    Set m_colItems = New Collection
End Sub

Private Sub Class_Terminate()
    Set m_colItems = Nothing
End Sub




'Form Code
Private WithEvents objColl  As CCollection
Private lngIncrement        As Long


Private Sub Command1_Click()
    Dim objItem As New CItem
   
    Call objColl.AddItem(objItem, Chr$(lngIncrement + 48) & "-Item")
    lngIncrement = lngIncrement + 1
End Sub


Private Sub Command2_Click()
    Dim i       As Integer
    Dim objItem As CItem
   
   
    For i = 48 To 48 + lngIncrement - 1
        'raise events for even numbered items
        If i Mod 2 = 0 Then
            Set objItem = objColl.GrabItem(Chr$(i) & "-Item")
            Call objItem.EventRaisingFunction
        End If
    Next
End Sub

Private Sub Form_Load()
    Set objColl = New CCollection
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set objColl = Nothing
End Sub


Private Sub objColl_CollectionEvent(ByVal ItemName As String)
    MsgBox "The item " & ItemName & " raised an event."
End Sub




The "NewEnum" function of CCollection just lets you use the For Each syntax should you ever need it (I ended up not using it in my sample).  In addition, you will need to go to Tools -> Procedure Attributes, select NewEnum, set is ProcedureID to -4 and check the option to "Hide this Member".

To test, just click the first button a few times to add some items, then click the second which causes the even numbered item objects to raise their events.
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7818279
Hi Adept,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Accept AzraSound's comment(s) as an answer.

Adept, if you think your question was not answered at all or if you need help, just post a new comment here; Community Support will help you.  DO NOT accept this comment as an answer.

EXPERTS: If you disagree with that recommendation, please post an explanatory comment.
==========
DanRollins -- EE database cleanup volunteer
0
 

Author Comment

by:Adept
ID: 7818398
I did forget about this question.  I had set my email filter to look for answers proposed and missed the comment/answer.

thanks
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 7818656
No blame attached :)  That's why i say "it appears..."
-- Dan
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

775 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question