Question How Do I Get A Hook To A Form Opened By A Different Object

darkeagle03

New member
Joined
Jun 13, 2008
Messages
4
Programming Experience
3-5
OK, Here's the situation. It's kind of long so I'm bolding the parts I feel are most critical.

I have a one-function interface. Whenever an object implements this interface, I know that the implementation of that function is going to open a Form. However, there is no hook back to the Form from the interface.

I need to write a function that can take in any object implementing this interface and then do something when the corresponding Form is closed. I have written 95% of this, including implementing some basic threading to perform the check. What I can't figure out right now is how to get a hook to the Form so that I can determine whether or not it's closed.

I can not modify the interface, and I cannot extend the interface because this needs to be backward compatible with stuff that has already been written. I am open to hacks, including trolling through system memory if need be (I've done that before in VB6). I would like some direction / pointers on how to do this in .NET / what to look for to get me started if anyone has any. If it helps, I also know that the Form will be opened within the same thread as the function, so if anyone knows of a way to determine whether or not a function on a given object is in the process of executing or not, that would work just as well.
 
example where IForm is the interface (and test() is an interface method):
VB.NET:
For Each f As Form In My.Application.OpenForms
    If TypeOf f Is IForm Then
        DirectCast(f, IForm).test()
    End If
Next
 
JohnH, Thank you for the reply. Unfortunately, that's not really what I was looking for. I'll try to elaborate a little more with code. Please no comments on the code itself / the threading, etc. I'm not putting down what I'm actually doing, just enough to give an idea of what's going on.

VB.NET:
'Interface with one function that will always open a Windows Form
Interface MyInterface
     Public Sub Test()
End Interface

'Example Implementation of the interface.  It opens a Windows Form
Class InterfaceImplementer
     Implements MyInterface

     Public Sub Test()
          Dim frmMyForm As New MyForm
          frmMyForm.Show()
     End Test
End Class

'Class that calls the InterfaceImplementer through the interface
'     thereby causing a Windows form to open
'     it needs to cause some code to execute when the form closes
Class InterfaceExecuter
     Private m_Utility As Utility
     Public Sub Run()
          Dim oMyInt As MyInterface

          m_Utility = New Utility()
          oMyInt = New InterfaceImplementer()
          oMyInt.Test()
          m_Utility.CheckForMyInterfaceFormClosed(oMyInt)
     End Sub
End Class

'Utility class that I am working on that will allow the code
'     to be executed when the Windows Form opened by the
'     implementation of MyInterface is closed
Class Utility
     Private m_InterfaceToCheck As MyInterface

     'This function creates a new background thread to continuously
     '     check whether or not the form is closed
     Public Sub CheckForMyInterfaceFormClosed(oInt As MyInterface)
          Dim thrTester As Threading.Thread

          m_InterfaceToCheck = oInt

          thrTester = New Threading.Thread(AddressOf CheckForFormOpen)
          thrTester.IsBackground = True
          thrTester.Start()
     End Sub

     'This function contains the loop for the background thread that
     '     will check whether or not the form is open or closed
     Private Sub CheckForFormOpen
          While True
               If Not IsFormOpen(m_InterfaceToCheck) Then
                    'Execute Code Here
                    Exit While
               End If

               Threading.Thread.Sleep(250)
          End While
     End Sub

     'This function actually checks whether or not the form is open or closed
     Private Function IsFormOpen(oIntToCheck As MyInterface) As Boolean
          'What goes here?
          'How do I use oIntToCheck to get a handle on the Form (MyForm)
          '     that I know it opened?  All implementations of MyInterface
          '     will open a Windows Form (though not necessarily a MyForm)
     End Function
End Class
 
I'm not aware of any references that can be used in such setup, but if InterfaceImplementer can Tag the form before showing it that can be used. If not you can use the knowledge that calling the interface method shows a form, check OpenForms before and after the call to see which form was opened. You can then attach to the FormClosed event of that form to get notified. Example of the latter:
VB.NET:
Class InterfaceExecuter
    Public Sub Run()
        Dim curForms As New List(Of Form)
        For Each f As Form In My.Application.OpenForms
            curForms.Add(f)
        Next

        Dim oMyInt As MyInterface = New InterfaceImplementer()
        oMyInt.Test()

        For Each f As Form In My.Application.OpenForms
            If Not curForms.Contains(f) Then
                AddHandler f.FormClosed, AddressOf form_closed
                Exit For
            End If
        Next            
    End Sub

    Sub form_closed(ByVal sender As Object, ByVal e As FormClosedEventArgs)
        MsgBox("interface invoked form closed")
    End Sub
End Class
 
Thanks John. I was actually thinking of something like this late last night after reading the MyApplication.OpenForms post that you had made earlier. It's probably the way that I'm going to go. Unfortunately, I can't rely on the forms themselves being tagged in anyway. I could do that going forward with at least some of the code, but that wouldn't be the case with the old code. Checking the forms count before and after should still work though. One question regarding that property: Can one safely assume that the order in which the forms are pulled is the order in which they are created? (so MyApplication.OpenForms(5) would be created before MyApplication.OpenForms(6))
 
Can one safely assume that the order in which the forms are pulled is the order in which they are created?
That appears to be the case. So the above code could be replaced with just getting the last form by index to get the reference.
 
Back
Top