Yes, it is possible, easy even. But you have to be able to do it safely
otherwise you'll create the classic circular reference with associated
memory leak. In brief, if the parent holds a reference to the child and
the child hold a reference to the parent, teardown doesn't occur
because the COM reference count never reaches zero. If you are not
releasing memory you application will soon crash.
There are various solutions to the problem and I seem to have tried
most of them: explicit teardown code that must be called in the correct
order every time (not a joy to use, a bit like DAO <g>); using a single
instance of a messenger class to raise an event in the parent from the
child (better but the extra coding is a pain); and others.
The approach I'm current using is from Matt Curland's book Advanced
Visual Basic 6. In a nutshell, the child holds a 'dumb' reference being
the parent's ObjPtr (i.e. does not affect the COM reference count on
the parent). When a 'real' reference to the parent is required, it uses
the win32 API CopyMemory method to 'rehydrate' the dumb pointer; you
must ensure you bump up the reference count at the same time, though.
Using CopyMemory to rehydrate a parent that no longer exists (e.g. has
been set to Nothing) will cause you application to immediately crash,
however it is fairly easy to make safe. I've been using this approach
for a while now and I'm very satisfied with it.
Here's the bare bones:
' ---<code in CParent class module>---
Option Explicit
Private m_Child As CChild
Private Sub Class_Initialize()
Set m_Child = New CChild
m_Child.SetParent ObjPtr(Me)
End Sub
Private Sub Class_Terminate()
m_Child.SetParent 0
End Sub
Public Property Get Child() As CChild
Set Child = m_Child
End Property
' ---</code in CParent class module>---
' ---<code in CChild class module>---
Option Explicit
Private Declare Sub CopyMemory _
Lib "kernel32" Alias "RtlMoveMemory" _
(pDst As Any, pSrc As Any, _
ByVal ByteLen As Long)
Private m_pParent As Long
Friend Function SetParent( _
ByVal Ptr As Long _
) As Boolean
m_pParent = Ptr
SetParent = True
End Function
Public Property Get Parent() As CParent
If m_pParent = 0 Then
Exit Property
End If
Set Parent = CParentFromPtr(m_pParent)
End Property
Private Function CParentFromPtr( _
ByVal Ptr As Long _
) As CParent
Dim tmp As CParent
CopyMemory tmp, Ptr, 4
Set CParentFromPtr = tmp
CopyMemory tmp, 0&, 4
End Function
' ---</code in CChild class module>---
Jamie.
--