Kyle123
Well-known Member
- Joined
- Jan 24, 2012
- Messages
- 2,774
Ok, before I start, this is cross posted here: Tearing down circular references and a simplified version here: vba - Tearing Down Circular References - Stack Overflow
I've yet to get a definitive answer, so I'd appreciate any input anyone has.
The following code creates a circular reference for each element in the array. Is the code in the<code style="margin: 0px; padding: 1px 5px; border: 0px; font-size: 14px; vertical-align: baseline; background-color: rgb(238, 238, 238); font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; background-position: initial initial; background-repeat: initial initial; ">UserForm_Terminate</code> routine sufficient to tear down the relationships to allow the memory to be released? Or is there a requirement to use pointers and weak references?
If so/not what is the best method for testing whether the objects have been released?
The terminate routines in both the Parent form object and the child class objects do execute, however I'm not sure where the garbage collector steps in.
To create the below, add a new userform to a new project with a button on called btnReset
UserForm Code:
Class CLightButton:
Class ILightsOut
A simplified version of the above which demonstrates the same concept can be found on my question here: vba - Tearing Down Circular References - Stack Overflow
I've yet to get a definitive answer, so I'd appreciate any input anyone has.
The following code creates a circular reference for each element in the array. Is the code in the<code style="margin: 0px; padding: 1px 5px; border: 0px; font-size: 14px; vertical-align: baseline; background-color: rgb(238, 238, 238); font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; background-position: initial initial; background-repeat: initial initial; ">UserForm_Terminate</code> routine sufficient to tear down the relationships to allow the memory to be released? Or is there a requirement to use pointers and weak references?
If so/not what is the best method for testing whether the objects have been released?
The terminate routines in both the Parent form object and the child class objects do execute, however I'm not sure where the garbage collector steps in.
To create the below, add a new userform to a new project with a button on called btnReset
UserForm Code:
Rich (BB code):
Option Explicit
Implements ILightsOut
Private p_btns(1 To 7, 1 To 7) As CLightButton
Private Sub btnReset_Click()
Reset
End Sub
Private Sub ILightsOut_BtnClick(x As Long, y As Long)
Dim ii As Long
Dim r As Long
Dim c As Long
If Not x + 1 > UBound(p_btns) Then p_btns(x + 1, y).Toggle
If Not x - 1 < LBound(p_btns) Then p_btns(x - 1, y).Toggle
If Not y + 1 > UBound(p_btns, 2) Then p_btns(x, y + 1).Toggle
If Not y - 1 < LBound(p_btns, 2) Then p_btns(x, y - 1).Toggle
For r = LBound(p_btns) To UBound(p_btns)
For c = LBound(p_btns, 2) To UBound(p_btns, 2)
If p_btns(r, c).btn.BackColor = &H80000012 Then ii = ii + 1
Next c
Next r
If ii = UBound(p_btns) * UBound(p_btns, 2) Then
MsgBox "You Win!!!" & vbCr & vbCr & "Click Ok to Reset", vbDefaultButton1
Reset
End If
End Sub
Private Sub UserForm_Initialize()
Dim x As Long
Dim y As Long
Dim cls As CLightButton
For x = 1 To 7
For y = 1 To 7
Set cls = New CLightButton
cls.Register Me
Set cls.btn = Me.Controls.Add("forms.commandbutton.1")
cls.x = x
cls.y = y
With cls.btn
.Width = 36
.Height = 36
.Left = (y * .Width) - .Width
.Top = (x * .Height) - .Height
If (y = x Or y = (UBound(p_btns) - (x - 1))) Then .BackColor = &H80FFFF Else .BackColor = &H80000012
End With
Set p_btns(x, y) = cls
Next y
Next x
p_btns(4, 4).btn.BackColor = &H80000012
Me.Height = (36 * x) - 36 + 60
Me.Width = (36 * y) - 36 + 4
Me.btnReset.Top = (36 * x) - 36 + 10
Me.btnReset.Left = 30
End Sub
Private Sub Reset()
Dim x As Long
Dim y As Long
For x = LBound(p_btns) To UBound(p_btns)
For y = LBound(p_btns, 2) To UBound(p_btns, 2)
If (y = x Or y = (UBound(p_btns) - (x - 1))) Then p_btns(x, y).btn.BackColor = &H80FFFF Else p_btns(x, y).btn.BackColor = &H80000012
Next y
Next x
p_btns(4, 4).btn.BackColor = &H80000012
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Dim x As Long
Dim y As Long
For x = LBound(p_btns) To UBound(p_btns)
For y = LBound(p_btns, 2) To UBound(p_btns, 2)
p_btns(x, y).UnRegister
Next y
Next x
End Sub
Class CLightButton:
Rich (BB code):
Option Explicit
Private WithEvents p_btn As MSForms.CommandButton
Private BtnClick As ILightsOut
Private p_y As Long
Private p_x As Long
Public Sub Register(callback As ILightsOut)
Set BtnClick = callback
End Sub
Public Sub UnRegister()
Set BtnClick = Nothing
End Sub
Public Property Let x(value As Long)
p_x = value
End Property
Public Property Let y(value As Long)
p_y = value
End Property
Public Property Set btn(value As MSForms.CommandButton)
Set p_btn = value
End Property
Public Property Get btn() As MSForms.CommandButton
Set btn = p_btn
End Property
Public Sub Toggle()
If btn.BackColor = &H80FFFF Then
btn.BackColor = &H80000012
Else
btn.BackColor = &H80FFFF
End If
End Sub
Private Sub p_btn_Click()
BtnClick.BtnClick p_x, p_y
End Sub
Class ILightsOut
Rich (BB code):
Option Explicit
Public Sub BtnClick(x As Long, y As Long)
End Sub
A simplified version of the above which demonstrates the same concept can be found on my question here: vba - Tearing Down Circular References - Stack Overflow
Last edited: