home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic 4 Power Pack / Visual_Basic4_Power_Pack.bin / vb4files / vbof / vbofomgr.cls < prev    next >
Encoding:
Text File  |  1996-11-20  |  68.6 KB  |  2,095 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4. END
  5. Attribute VB_Name = "VBOFObjectManager"
  6. Attribute VB_Creatable = True
  7. Attribute VB_Exposed = True
  8. Option Explicit
  9.  
  10. ' VB Object Framework
  11. '   Version 1.0a
  12. '
  13. ' (c) Copyright 1995 Ken Fitzpatrick
  14. '     All Rights Reserved
  15. '     Cannot be distributed or sold without permission
  16. '
  17. ' Please refer to the attached User's Guide in file
  18. '   "VBOF.doc" for important infomation.
  19. '   Microsoft Word v.6.0 (or later) or equivalent
  20. '   viewer is required.
  21. '
  22. ' The VB Object Framework and this demonstration
  23. '   package are provided on an as-is,
  24. '   use-at-your-own-risk basis.
  25. ' Even though thorough testing has been performed
  26. '   on this product and demonstration package and
  27. '   every resonable precaution has been taken, the
  28. '   author assumes no responsibilities of any
  29. '   actions or damages which result from the use of
  30. '   this product or demonstration package.
  31. ' The above statement is necessary because the very
  32. '   nature of VB Object Framework is to manipulate
  33. '   data in the form of objects.  Under certain
  34. '   circumstances, particularly under situations of
  35. '   misuse or where the user is unfamiliar the
  36. '   product, it would be possible to damage or
  37. '   destroy data.  The author cannot, and will not,
  38. '   be responsible for such use of this product or
  39. '   demonstration package.
  40. '
  41. ' To-Do:
  42. '   DataWrapper: support Validate event
  43. '
  44. ' Errors:
  45. '
  46. ' Done:
  47. '   Get/Let Properties for AbsolutePosition
  48. '   Full test with errors enabled
  49. '   Identify the Class Module Name which "does not
  50. '       understand" (e.g. "ObjectNewObjectOfMyClass",
  51. '       etc.) in error mesages
  52. '   Not Done (avoiding .Rebind due to invalid state
  53. '       is not informational to the user):
  54. '       Move readiness code from NewVBOF...Wrapper
  55. '           to Wrapper.Rebind
  56. '   Coll: remove need for ObjectLink.CLS
  57. '   Method Form_QueryUnload (Form, Wrappers())
  58. '   RecordSetWrapper: as a subset of the
  59. '       DataWrapper
  60. '   confirm all RegisteredEventObjects are
  61. '       cleaned-up
  62. '   check Object.ObjectDataSource before
  63. '       actually going to the database in
  64. '       OMgr.NewObject
  65. '   Addresses are missing their States, Persons
  66. '       are missing their Mothers and Fathers
  67. '   DBGrid support (remaining Unbound functions)
  68. '   use ListBoxWrappers in DBGrid example
  69. '       (for States, Genders, MaritalStatus)
  70. '   ListBoxWrapper.Rebind
  71. '   OMgr.NewListBoxWrapper: use newLBWrapper.Rebind
  72. '   Clinton's are missing their Address
  73. '   non-Access-specific SQL
  74. '   Add "Set Chelsea.Mother = Hillary" and
  75. '       "Set Chelsea.Father = Bill" to
  76. '       CreateTestData
  77. '   Add "Set Address.State = States.Item(x)" to
  78. '       CreateTestData
  79. '   PopulateCollection
  80. '       RecordSet:=, DB:=,
  81. '       invokes InstantiateFromDB or InstnatiateFromRS
  82. '   NewObject
  83. '       DB:=, SampleObject:=, SQL:=, ObjectID:=,
  84. '       ODBCPassThru:=, NullIfNotFound:=T|F,
  85. '       ANSISQL:=T|F
  86. '   elimiate ListBox:= from Property Get & Sets
  87. '       to be able to remove corresp parm from
  88. '       application calls to Wrapper
  89. '   don't Coll.DetachFromLBWrapper ... would disable
  90. '       support for 1:many (Coll:Wrappers)
  91. '       Figure another way to free the prev Wrapper
  92. '   function to return an instantiated object, given
  93. '       TypeName & ID
  94. '   single copy of StateCodes, MaritalStatus, etc.
  95. '   support Meth=SystemObject(TypeName:=, ObjectID:=)
  96. '   incorp code currently required in methods such
  97. '       as "Persons", "Addresses", etc.
  98. '       (Meth=ManageCollection)
  99. '   Support ODBC Pass Thru
  100. '   Elim redundant "With pvtCurrentPerson : .Name = efName"
  101. '       in demo forms
  102. '   Speed performance by checking for Key=(TypeName)&" "&ObjectID
  103. '       before scanning full SystemObjects
  104. '   (Error) .Replace not deleting link to previous item
  105. '   (Error) .RemoveCollection removes objects prematurely
  106. '       (try the 2 nonDataControl windows, close
  107. '       one, then go after the objects from the other)
  108. '   (Error) Coll.Remove deletes the parent linkage, but
  109. '       that should be persistent
  110. '   added ANSI SQL support (optional)
  111. '   enhanced RecordSet wrapper capability with
  112. '       MoveFirst, MoveLast, FindFirst, FindLast,
  113. '       FindNext, FindPrevious, BOF, EOF
  114. '   CollectionIndex(Where:=FindString)
  115. '   Use-at-your-own-risk message (.txt, in Intro.FRM)
  116. '   propagate code on ListBoxDemo.RefreshCustomerList
  117. '       for dealing with a removed object which had
  118. '       previously been the "pvtCurrent" object
  119. '   Test ParentsOfObject()
  120. '   Set (all) tempObject = Nothing
  121. '   Incorp State, MaritalStatus, Gender objects into
  122. '       GUI examples
  123. '   Hold position of CurrentObject in DataControl
  124. '       example
  125. '   Hold position of CurrentObject in DataControl
  126. '       example
  127. '   need to remove item from collection before
  128. '       .TriggerObjectEvent Event=RemovedItem
  129. '       (Trigger between Collections)
  130. '   Finish ListBox example: "Add", "Upd", "Del"
  131. '   Remove references to each object's own EventManager
  132. '   send "Added" trigger to objects which are
  133. '       newly added to the collection
  134. '   send "Instantiated" trigger to objects which
  135. '       are newly instantiated
  136. '   Rename to VBOF for smaller space consumption
  137. '       in the VB Object Browser
  138. '   Support EventManager interface in ObjectManager
  139. '   TriggerCollectionEvent
  140. '   Support #NoEventMgr mode
  141. '   Support #NoDebugMode mode
  142. '   Support ListBox wrapping
  143. '   Support ComboBox wrapping
  144. '   Support UnRegister from EventManager
  145. '   Execute UnRegister Me in GUI Form_QueryUnload()
  146. '   Support .pvtCloseRecordSet
  147. '   AutoDeleteOrphans
  148. '   Implement .Version method
  149. '   ObjMgr.CompleteCleanUp runs too long, redundantly
  150. '
  151. ' Deferred until a later release
  152. '   Lock Manager
  153. '       (not yet needed because Collections are still
  154. '       founded on the RecordSet)
  155. '   SynchronousCommit
  156. '       (same as above)
  157. '   Heterogenous Collections
  158. '       see also SubClasses (below)
  159. '   Instantiating SubClasses
  160. '       Do only "Vehicles", won't do "Cars" or "Buses" or "Trucks", etc.
  161. '   Collection.Sort
  162. '   Separated ComboBoxWrapper functions
  163. '   More properties for ODBC, RecordSet, ListBox,
  164. '       ComboBox, DBGrid, etc.
  165.  
  166. #If NoEventMgr = False Then
  167. Private pvtVBFWEventManager As VBOFEventManager
  168. #End If
  169. Private pvtSystemCollections As New Collection
  170. Private pvtSystemObjects As New Collection
  171. Private pvtSystemObjectsDictionary As New Collection
  172. Private pvtSystemObjectsDictionaryCollection As New Collection
  173. Private pvtDatabase As Database
  174. Private pvtWorkspace As Workspace
  175. Private pvtVBOFCollectionID As Long
  176. Private pvtDebugMode As Boolean
  177. Private pvtVerbose As Boolean
  178. Private pvtAutoDeleteOrphans As Boolean
  179. Private pvtObjectWasUnique As Boolean
  180.  
  181. Public HighestObjectID As Long
  182. Public ODBCPassThrough As Boolean
  183. Public ANSISQL As Boolean
  184.  
  185. Private Const pvtReceiverDoesNotSupportThisMethod = 438
  186.  
  187. Public Function InitializeObject(Optional Object As Variant) As Boolean
  188. Attribute InitializeObject.VB_Description = "Initializes an object for limited VBOF support"
  189. ' Initializes the object in support of
  190. '   VBOF services.
  191. '  Even though the contents of this method may seem
  192. '   trivial, it should still be used because future
  193. '   releases of VBOF will likely contained
  194. '   increased features which may have increased
  195. '   initialization requirements.  Only this method
  196. '   is guaranteed to satisfy those requirements.
  197. '   Thus, having used this method from the outset
  198. '   guarantees the user of transparent object
  199. '   initialization support across future releases.
  200. '
  201. ' Example of usage:
  202. '   Set MyObject = New <appropriateClassModule>
  203. '   ObjectManager.InitializeObject _
  204. '       Object:=MyProject
  205.     
  206.     Set Object.ObjectManager = Me
  207.     
  208.     With Object
  209.         .ObjectParentCount = 1
  210.         .ObjectChanged = False
  211.         .ObjectAdded = False
  212.         .ObjectDeleted = False
  213.     End With
  214.  
  215.     InitializeObject = True
  216. End Function
  217.  
  218. Public Function NewObject(Optional Database As Variant, Optional ObjectID As Variant, Optional Sample As Variant, Optional Parent As Variant, Optional WhereClause As Variant, Optional SQL As Variant, Optional OrderByClause As Variant, Optional ODBCPassThrough As Variant, Optional ANSISQL As Variant) As Variant
  219. Attribute NewObject.VB_Description = "Instantiates a new object from the Sample:="
  220. ' Returns an instantiated Object which occurs only
  221. '   singly.  This is typical for contained objects
  222. '   such as Employee.Manager, Address.State,
  223. '   Loan.Property, etc.
  224. '
  225. ' Parameter Description:
  226. '   see VBOFObjectManager.ManageCollection
  227. '
  228. ' Required Parameters:
  229. '   Sample:=
  230. '   ObjectID:=
  231.     
  232.     Dim tempObject As Object
  233.     Dim tempParent As Object
  234.     Dim tempIndex As Long
  235.     Dim tempRecordSet As RecordSet
  236.     Dim tempODBCPassThrough As Boolean
  237.     Dim SQLStatement As String
  238.     Dim newChildObject As Object
  239.     Dim tempCollectionEmulationMode As Boolean
  240.  
  241.     On Local Error Resume Next
  242.  
  243. ' bullet-proofing
  244.     If IsMissing(Sample) Then
  245.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewObject' method because the 'ObjectID:=' parameter is missing."
  246.         Set NewObject = Nothing
  247.         Exit Function
  248.     End If
  249.     If IsMissing(WhereClause) _
  250.     And IsMissing(ObjectID) Then
  251.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewObject' method because both the 'ObjectID:=' and 'WhereClause:=' parameters are missing."
  252.         Set NewObject = Nothing
  253.         Exit Function
  254.     End If
  255.     tempCollectionEmulationMode = False
  256.     If Sample.ObjectDataSource = "" _
  257.     Or Err = 438 Then
  258.         tempCollectionEmulationMode = True
  259.     End If
  260.     If Not tempCollectionEmulationMode _
  261.     And Not pvtIsDatabaseSpecified() Then
  262.         Set NewObject = Nothing
  263.         Exit Function
  264.     End If
  265.     If IsMissing(ODBCPassThrough) Then
  266.         tempODBCPassThrough = False
  267.     Else
  268.         tempODBCPassThrough = ODBCPassThrough
  269.     End If
  270.     If IsMissing(Parent) Then
  271.         Set tempParent = Nothing
  272.     Else
  273.         Set tempParent = Parent
  274.     End If
  275.  
  276. ' check each of the objects known at this time
  277. '   by their ObjectID
  278.     If Not IsMissing(ObjectID) Then
  279.         If CLng(ObjectID) > 0 Then
  280.             Sample.ObjectID = CLng(ObjectID)
  281.             tempIndex = _
  282.                 pvtObjectIndexInSystemObjects _
  283.                     (Object:=Sample)
  284.         Else
  285.             Set NewObject = Nothing
  286.             Exit Function
  287.         End If
  288.     Else
  289.         tempIndex = -1
  290.     End If
  291.  
  292. ' if found, return the located object
  293.     If tempIndex > 0 Then
  294.         Set tempObject = _
  295.             pvtSystemObjects.Item _
  296.                 (tempIndex)
  297.  
  298. ' increase the ParentCount of the previously
  299. '   existing object
  300.         tempObject.ObjectParentCount = _
  301.             tempObject.ObjectParentCount + 1
  302.     
  303.         Set NewObject = _
  304.             tempObject
  305.         Exit Function
  306.     End If
  307.  
  308. ' Object wasn't found.
  309. '   try the database
  310. ' Ensure the object is ready for Database access
  311.     If tempCollectionEmulationMode Then
  312.         Set NewObject = Nothing
  313.         Exit Function
  314.     End If
  315.     
  316. ' must retrieve it from the database
  317.     SQLStatement = _
  318.         "SELECT * FROM " & _
  319.         Sample.ObjectDataSource & _
  320.         " WHERE "
  321.     If Not IsMissing(ObjectID) Then
  322.         SQLStatement = _
  323.             SQLStatement & _
  324.                 "ObjectID = " & _
  325.                 CStr(ObjectID)
  326.     ElseIf Not IsMissing(WhereClause) Then
  327.         SQLStatement = _
  328.             SQLStatement & _
  329.                 WhereClause
  330.     End If
  331.     
  332. ' retrieve the data row
  333.     Set tempRecordSet = _
  334.         pvtDatabase. _
  335.             OpenRecordset( _
  336.                 SQLStatement, _
  337.                 dbOpenDynaset + pvtODBCPassThrough(tempODBCPassThrough))
  338.         
  339. ' check for NoRecords
  340.     If tempRecordSet.RecordCount < 1 Then
  341.         Set NewObject = Nothing
  342.         Exit Function
  343.     End If
  344.         
  345. ' have the Sample Object return an instantiated
  346. '   copy of itself
  347.     Set newChildObject = _
  348.         Me.pvtInstantiateNewObjectFromSample _
  349.              (Sample:=Sample)
  350.     If newChildObject Is Nothing Then
  351.         Set NewObject = Nothing
  352.         Exit Function
  353.     End If
  354.         
  355. ' initialize the NewChild.ObjectID temporarily
  356. '   so the AddUniqueObject will register the
  357. '   correct ObjectID (and avoid an endless loop
  358. '   in the case of SpouseA <-> SpouseB)
  359.     newChildObject.ObjectID = ObjectID
  360.     
  361. ' add the object to the SystemObjects Collection
  362.     Set tempObject = _
  363.         AddUniqueObject( _
  364.             Object:=newChildObject, _
  365.             Parent:=tempParent)
  366.  
  367. ' have the new instantiated object copy populate
  368. '   itself from this RecordSet row
  369.     Set newChildObject = _
  370.         Me.pvtObjectInitializeFromRecordSet( _
  371.             Object:=newChildObject, _
  372.             RecordSet:=tempRecordSet)
  373.     If newChildObject Is Nothing Then
  374.         Set NewObject = Nothing
  375.         Exit Function
  376.     End If
  377.     
  378.     Set NewObject = _
  379.         tempObject
  380. End Function
  381.  
  382. Public Function pvtObjectInitializeFromRecordSet(Optional Object As Variant, Optional RecordSet As Variant) As Variant
  383.  
  384.     On Local Error Resume Next
  385.     
  386. ' have the object copy populate
  387. '   itself from this RecordSet row
  388.     Object _
  389.         .ObjectInitializeFromRecordSet (RecordSet)
  390.     If Err = pvtReceiverDoesNotSupportThisMethod Then
  391.         pvtErrorMessage "Class Module '" & TypeName(Object) & "' does not support the method 'InitializeFromRecordSet'." & vbCrLf & "Object cannot be supported by VBOF without this method."
  392.         Set pvtObjectInitializeFromRecordSet = Nothing
  393.         Exit Function
  394.     End If
  395.  
  396.     Set pvtObjectInitializeFromRecordSet = Object
  397. End Function
  398.  
  399. Public Function pvtInstantiateNewObjectFromSample(Optional Sample As Variant) As Variant
  400.  
  401.     On Local Error Resume Next
  402.  
  403. ' instantiate the new object
  404.     Set pvtInstantiateNewObjectFromSample = _
  405.         Sample. _
  406.             ObjectNewInstanceOfMyClass
  407.     If Err = pvtReceiverDoesNotSupportThisMethod Then
  408.         pvtErrorMessage "Class Module '" & TypeName(Sample) & "' does not support the method 'ObjectNewInstanceOfMyClass'." & vbCrLf & "Object cannot be supported by " & TypeName(Me) & " without this method."
  409.         Set pvtInstantiateNewObjectFromSample = Nothing
  410.         Exit Function
  411.     End If
  412.  
  413.     Set pvtInstantiateNewObjectFromSample. _
  414.         ObjectManager = Me
  415. End Function
  416.  
  417. Public Function ManageCollection(Optional Collection As Variant, Optional ObjectID As Variant, Optional Database As Variant, Optional Sample As Variant, Optional Parent As Variant, Optional WhereClause As Variant, Optional SQL As Variant, Optional OrderByClause As Variant, Optional CollectionEmulationMode As Variant, Optional ANSISQL As Variant, Optional ODBCPassThrough As Variant) As Variant
  418. Attribute ManageCollection.VB_Description = "Manages an VBOFCollection"
  419. ' Returns the entire collection if the ObjectID
  420. '   parameter is missing,
  421. '   or
  422. ' Returns a Person object whose ObjectID matches the
  423. '   ObjectID parameter.
  424. '
  425. ' Completely manages a contained Collection of
  426. '   objects on behalf of a given containing object
  427. '
  428. ' Example of usage:
  429. '    Public Function Persons(Optional ObjectID As Variant) As Variant
  430. '    Dim tempNewPerson As New Person
  431. '    Set Persons = _
  432. '        ObjectManager. _
  433. '            ManageCollection( _
  434. ' (R)            Collection:=myPersonsCollection,
  435. ' (R)            Parent:=Me,
  436. ' (O)            ObjectID:=ObjectID,
  437. ' (O)            Sample:=tempNewPerson,
  438. ' (O)            Database:=MyDatabase,
  439. ' (O)            SQL:=sql statement,
  440. ' (O)            OrderByClause:="LastName ASC, FirstName ASC",
  441. ' (O)            WhereClause:=where clause,
  442. ' (O)            ANSISQL:=True|False,
  443. ' (O)            ODBCPassThrough:=True|False
  444. '
  445. ' Parameter Description:
  446. '   Collection:= (Required) the VBOFCollection object
  447. '       to be managed
  448. '   Parent:= (Required) defines the object which is
  449. '       the "Parent" of the objects to be collected.
  450. '       The value to specify is typically "Me".
  451. '       In OO terminology, this is the "containing"
  452. '       object
  453. '   Database:= (Optional) the VB Database Object containing
  454. '       the necessary Table
  455. '   Sample:= (Optional, but recommended) a
  456. '       throw-away object of the desired Class which
  457. '       VBOFCollection can use to help instantiate
  458. '       new objects to be placed into the
  459. '       Collection
  460. '   WhereClause:= (Optional) defines the SQL Where
  461. '       Clause to be used to select the desired
  462. '       rows from the Table.
  463. '       Normally, VBOFCollection creates all
  464. '       necessary Where Clauses to effect containment
  465. '   SQL:= (Optional, not recommended) defines the
  466. '       SQL statement to be used to select the
  467. '       desired rows from the Table.
  468. '       Normally, VBOFCollection creates the
  469. '       necessary SQL statement to effect containment
  470. '   OrderByClause:= (Optional) defines the SQL Order
  471. '       By Clause to be used to select the desired
  472. '       rows from the Table.
  473. '       Normally, VBOFCollection does not provide an
  474. '       Order By Clause
  475. '   ANSISQL:= (Optional) control whether or not
  476. '       ANSI SQL should be used when linking objects
  477. '       for containment purposes
  478. '   ODBCPassThrough:= (Optional) controls whether
  479. '       of not the SQL statements used by
  480. '       VBOFCollection to link parent and child objects
  481. '       should be executed on an ODBC database server
  482.  
  483.     Dim tempDatabase As Database
  484.  
  485.     On Local Error Resume Next
  486.  
  487. ' bullet-proofing
  488.     If IsMissing(Collection) _
  489.     Or IsMissing(Parent) _
  490.     Or IsMissing(Sample) Then
  491.         pvtErrorMessage TypeName(Me) & " cannot process the '.ManageCollection' method because either the 'Collection:=', 'Parent:=' or 'Sample:=' parameter is missing."
  492.         Set ManageCollection = Nothing
  493.         Exit Function
  494.     End If
  495.  
  496. ' use a valid Database parameter
  497.     If Not IsMissing(Database) Then
  498.         Set tempDatabase = Database
  499.     Else
  500.         Set tempDatabase = pvtDatabase
  501.     End If
  502.  
  503. ' check for never-before referenced Collection
  504.     If Collection Is Nothing Then
  505.         Set Collection = _
  506.             ObjectManager.NewVBOFCollection _
  507.                 (Parent:=Parent)
  508.     End If
  509.     
  510. ' check for the need to populate the collection
  511. '   from the database
  512.     If Not Collection. _
  513.             pvtDatabaseHasBeenReferenced Then
  514.  
  515. ' pass-along any known Database parameters
  516.         Collection. _
  517.             SetDatabaseParameters _
  518.                 Database:=tempDatabase, _
  519.                 SQL:=SQL, _
  520.                 ANSISQL:=ANSISQL, _
  521.                 WhereClause:=WhereClause, _
  522.                 OrderByClause:=OrderByClause, _
  523.                 ODBCPassThrough:=ODBCPassThrough
  524.  
  525. ' instantiate the contained objects
  526.         Set Collection = _
  527.             Collection. _
  528.                 PopulateCollection( _
  529.                     Database:=tempDatabase, _
  530.                     Parent:=Parent, _
  531.                     Sample:=Sample)
  532.     End If
  533.     
  534. ' check for a request for a specific Object
  535.     If Not IsMissing(ObjectID) Then
  536.         Set ManageCollection = _
  537.             Collection.Item(ObjectID)
  538.  
  539. ' else, return the entire collection
  540.     Else
  541.         Set ManageCollection = _
  542.             Collection
  543.     End If
  544. End Function
  545.  
  546. Public Function pvtWrapperUseCollection(Optional CollectionParm As Variant, Optional pvtCollection As Variant, Optional Verbose As Variant, Optional WrapperName As Variant) As Variant
  547.  
  548.     On Local Error Resume Next
  549.  
  550.     If Not IsMissing(CollectionParm) Then
  551.         If Not CollectionParm Is Nothing Then
  552.             If TypeName(CollectionParm) = "VBOFCollection" Then
  553.                 Set pvtCollection = CollectionParm
  554.                 Set pvtWrapperUseCollection = pvtCollection
  555.                 Exit Function
  556.             End If
  557.         End If
  558.     End If
  559.     
  560.     If Not IsMissing(pvtCollection) Then
  561.         If Not pvtCollection Is Nothing Then
  562.             If TypeName(pvtCollection) = "VBOFCollection" Then
  563.                 Set pvtWrapperUseCollection = pvtCollection
  564.                 Exit Function
  565.             End If
  566.         End If
  567.     End If
  568.     
  569. ' error
  570.     If Not IsMissing(Verbose) Then
  571.         If Verbose Then
  572.             pvtErrorMessage TypeName(Me) & " cannot process the " & WrapperName & " methods because the 'Collection' parameter is missing and no suitable default has been established." & vbCrLf & vbCrLf & "If using the VBOF" & WrapperName & "Wrapper, please ensure that the 'ObjectManager.NewVBOF" & WrapperName & "Wrapper' method has been properly executed and references the appropriate Collection and " & WrapperName & " control."
  573.         End If
  574.     End If
  575.     
  576.     Set pvtWrapperUseCollection = Nothing
  577. End Function
  578.  
  579. Public Function pvtWrapperUseControl(Optional ControlParm As Variant, Optional pvtControl As Variant, Optional SupportedNames As Variant, Optional WrapperName As Variant, Optional Verbose As Variant) As Variant
  580.  
  581.     On Local Error Resume Next
  582.  
  583.     If Not IsMissing(ControlParm) Then
  584.         If Not ControlParm Is Nothing Then
  585.             If InStr(SupportedNames, TypeName(ControlParm)) > 0 Then
  586.                 Set pvtControl = ControlParm
  587.                 Set pvtWrapperUseControl = pvtControl
  588.                 Exit Function
  589.             End If
  590.         End If
  591.     End If
  592.     
  593.     If Not IsMissing(pvtControl) Then
  594.         If Not pvtControl Is Nothing Then
  595.             If InStr(SupportedNames, TypeName(pvtControl)) > 0 Then
  596.                 Set pvtWrapperUseControl = pvtControl
  597.                 Exit Function
  598.             End If
  599.         End If
  600.     End If
  601.     
  602. ' error
  603.     If Not IsMissing(Verbose) Then
  604.         If Verbose Then
  605.             pvtErrorMessage TypeName(Me) & " cannot process the " & WrapperName & " methods because the '" & WrapperName & "' parameter is missing and no suitable default has been established." & vbCrLf & vbCrLf & "If using the VBOF" & WrapperName & "Wrapper, please ensure that the 'ObjectManager.NewVBOF" & WrapperName & "Wrapper' method has been properly executed and references the appropriate Collection and " & WrapperName & " control."
  606.         End If
  607.     End If
  608.     
  609.     Set pvtWrapperUseControl = Nothing
  610. End Function
  611.  
  612. Public Function pvtWrapperVerifyCollection(Optional Collection As Variant, Optional pvtCollection As Variant, Optional Verbose As Variant, Optional WrapperName As Variant) As Boolean
  613.  
  614.     Dim tempCollection As Variant
  615.  
  616.     If Not IsMissing(Collection) Then
  617.         Set tempCollection = Collection
  618.     Else
  619.         Set tempCollection = pvtCollection
  620.     End If
  621.  
  622.     If pvtWrapperUseCollection( _
  623.         CollectionParm:=tempCollection, _
  624.         pvtCollection:=pvtCollection, _
  625.         Verbose:=Verbose, _
  626.         WrapperName:=WrapperName) Is Nothing _
  627.     Then
  628.         pvtWrapperVerifyCollection = False
  629.     Else
  630.         pvtWrapperVerifyCollection = True
  631.     End If
  632. End Function
  633.  
  634. Public Function pvtWrapperVerifyControl(Optional Control As Variant, Optional pvtControl As Variant, Optional Verbose As Variant, Optional WrapperName As Variant) As Boolean
  635.  
  636.     Dim tempControl As Variant
  637.  
  638.     If Not IsMissing(Control) Then
  639.         Set tempControl = Control
  640.     Else
  641.         Set tempControl = pvtControl
  642.     End If
  643.  
  644.     If pvtWrapperUseControl( _
  645.         ControlParm:=tempControl, _
  646.         pvtControl:=pvtControl, _
  647.         Verbose:=Verbose, _
  648.         WrapperName:=WrapperName) Is Nothing _
  649.     Then
  650.         pvtWrapperVerifyControl = False
  651.     Else
  652.         pvtWrapperVerifyControl = True
  653.     End If
  654. End Function
  655.  
  656.  
  657. Public Function NewVBOFRecordSetWrapper(Optional Collection As Variant, Optional DataControl As Variant) As VBOFDataWrapper
  658. Attribute NewVBOFRecordSetWrapper.VB_Description = "Instantiates a new VBOFRecordSetWrapper"
  659. ' Returns a new VBOFRecordSetlWrapper for the
  660. '   specified VBOFCollection
  661. '
  662. ' Coding Example:
  663. '   Dim MyRecordSetWrapper as VBOFRecordSetWrapper
  664. '   Dim MyCollection as VBOFCollection
  665. '   Set MyRecordSetWrapper = _
  666. '       ObjectManager.NewVBOFRecordSetWrapper ( _
  667. '           Collection:=MyCollection)
  668.  
  669.     Dim tempNewRecordSetWrapper As New VBOFRecordSetWrapper
  670.     
  671.     Set tempNewRecordSetWrapper.ObjectManager = Me
  672.     
  673. ' bullet-proofing
  674.     If IsMissing(Collection) Then
  675.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewVBOFRecordSetWrapper' method because the 'Collection:=' parameter is missing."
  676.         Set NewVBOFRecordSetWrapper = Nothing
  677.         Exit Function
  678.     End If
  679.  
  680. ' initialize the Collection
  681.     If Not IsMissing(Collection) Then
  682.         If Not Collection Is Nothing Then
  683.             Set tempNewRecordSetWrapper.Collection = _
  684.                 Collection
  685.         End If
  686.     End If
  687.     
  688. ' have the new wrapper bind itself to the RecordSet
  689.     If Not tempNewRecordSetWrapper.Collection Is Nothing Then
  690.         tempNewRecordSetWrapper.Rebind
  691.     End If
  692.     
  693. ' generate a unique ObjectID for the new VBOFListBoxWrapper
  694.     pvtVBOFCollectionID = _
  695.         pvtVBOFCollectionID + 1
  696.     tempNewRecordSetWrapper.ObjectID = _
  697.         pvtVBOFCollectionID
  698.     
  699.     Set NewVBOFRecordSetWrapper = _
  700.         tempNewRecordSetWrapper
  701. End Function
  702.  
  703. Public Function NewVBOFDBGridWrapper(Optional Collection As Variant, Optional DBGrid As Variant) As VBOFDBGridWrapper
  704. Attribute NewVBOFDBGridWrapper.VB_Description = "Instantiates a new VBOFDBGridWrapper"
  705. ' Returns a new VBOFDBGridWrapper for the
  706. '   specified VBOFCollection (Required) and
  707. '   DBGrid (Optional)
  708. '
  709. ' Coding Example:
  710. '   Dim MyDBGridWrapper as VBOFDBGridWrapper
  711. '   Dim MyCollection as VBOFCollection
  712. '   Set MyDBGridWrapper = _
  713. '       ObjectManager.NewVBOFDBGridWrapper ( _
  714. '           Collection:=MyCollection, _
  715. '           DBGrid:=MyDBGrid)
  716.  
  717.     Dim tempNewDBGridWrapper As New VBOFDBGridWrapper
  718.     
  719.     Set tempNewDBGridWrapper.ObjectManager = Me
  720.     
  721. ' bullet-proofing
  722.     If IsMissing(Collection) Then
  723.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewVBOFDBGridWrapper' method because the 'Collection:=' parameter is missing."
  724.         Set NewVBOFDBGridWrapper = Nothing
  725.         Exit Function
  726.     End If
  727.     If IsMissing(DBGrid) Then
  728.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewVBOFDBGridWrapper' method because the 'DBGrid:=' parameter is missing."
  729.         Set NewVBOFDBGridWrapper = Nothing
  730.         Exit Function
  731.     End If
  732.  
  733. ' initialize the Collection
  734.     If Not IsMissing(Collection) Then
  735.         If Not Collection Is Nothing Then
  736.             Set tempNewDBGridWrapper.Collection = _
  737.                 Collection
  738.         End If
  739.     End If
  740.     
  741.     If Not IsMissing(DBGrid) Then
  742.         If Not DBGrid Is Nothing Then
  743.             Set tempNewDBGridWrapper.DBGrid = _
  744.                 DBGrid
  745.         End If
  746.     End If
  747.     
  748. ' have the new wrapper bind itself to the DBGrid
  749.     If Not tempNewDBGridWrapper.DBGrid Is Nothing Then
  750.         If Not tempNewDBGridWrapper.Collection Is Nothing Then
  751.             tempNewDBGridWrapper.Rebind _
  752.                 Collection:=Collection, _
  753.                 DBGrid:=DBGrid
  754.         End If
  755.     End If
  756.     
  757. ' generate a unique ObjectID for the new VBOFDBGridWrapper
  758.     pvtVBOFCollectionID = _
  759.         pvtVBOFCollectionID + 1
  760.     tempNewDBGridWrapper.ObjectID = _
  761.         pvtVBOFCollectionID
  762.     
  763.     Set NewVBOFDBGridWrapper = _
  764.         tempNewDBGridWrapper
  765. End Function
  766.  
  767. Private Function pvtIsDatabaseSpecified() As Integer
  768. ' Determine whether or not the database has been
  769. '   specified
  770.  
  771.     If pvtDatabase Is Nothing Then
  772.         pvtErrorMessage TypeName(Me) & " cannot function without having been provided the name of the database.  Use the 'Database:=' parameter to specify the database."
  773.         pvtIsDatabaseSpecified = False
  774.         Exit Function
  775.     End If
  776.  
  777.     pvtIsDatabaseSpecified = True
  778. End Function
  779.  
  780.  
  781. Public Function Collection(Optional ObjectID As Variant, Optional Index As Variant) As VBOFCollection
  782. Attribute Collection.VB_Description = "Private"
  783. ' Return the VBOFCollection having the specified
  784. '   ObjectID or Index
  785.  
  786.     On Local Error Resume Next
  787.     
  788.     Set Collection = Nothing
  789.     
  790. ' bullet-proofing
  791.     If IsMissing(ObjectID) And IsMissing(Index) Then
  792.         pvtErrorMessage TypeName(Me) & " cannot process the '.Collection' method because the 'ObjectID:=' and the 'Index:=' parameters were missing."
  793.         Exit Function
  794.     End If
  795.  
  796.     If Not IsMissing(Index) Then
  797.         Set Collection = _
  798.             pvtSystemCollections(Index)
  799.     
  800.     ElseIf Not IsMissing(ObjectID) Then
  801.         Set Collection = _
  802.             pvtSystemCollections(CStr(ObjectID))
  803.     End If
  804.  
  805. End Function
  806.  
  807. Public Function CompleteObjectCleanUp() As Boolean
  808. Attribute CompleteObjectCleanUp.VB_Description = "Private"
  809. ' Removes all known Collections and Objects from the
  810. '   current environment
  811. ' Note: does NOT sever the automatic object
  812. '   containment links between containing objects and
  813. '   contained objects
  814.  
  815.     Dim tempCollection As VBOFCollection
  816.     
  817.     On Local Error Resume Next
  818.     
  819.     For Each tempCollection In pvtSystemCollections
  820.         
  821.         RemoveCollection _
  822.             Collection:=tempCollection, _
  823.             NoDelete:=True, _
  824.             CleanUpMode:=True
  825.     
  826.         pvtSystemCollections.Remove 1
  827.     
  828.     Next tempCollection
  829.  
  830.     CompleteObjectCleanUp = True
  831. End Function
  832.  
  833. Public Function DisplayDebugMessage(Optional Message As Variant) As Long
  834. Attribute DisplayDebugMessage.VB_Description = "Private"
  835.  
  836. #If NoDebugMode = False Then
  837.     DisplayDebugMessage = True
  838.  
  839.     If Not pvtDebugMode Then
  840.         Exit Function
  841.     End If
  842.     
  843.     Debug.Print Format$(Now, "yyyy/mm/dd hh:nn:ss") & " " & Message
  844. #Else
  845.     DisplayErrorMessage TypeName(Me) & " (Warning) the .DisplayDebugMessage method has been executed, but the conditional compilation parameter 'NoDebugMode = -1' has been specified.  No Event code is generated unless 'NoDebugMode = 0' or 'NoDebugMode' is missing from the conditional compilation string altogether."
  846. #End If
  847. End Function
  848.  
  849.  
  850. Public Function NewVBOFListBoxWrapper(Optional Collection As Variant, Optional ListBox As Variant) As VBOFListBoxWrapper
  851. Attribute NewVBOFListBoxWrapper.VB_Description = "Instantiates a new VBOFListBoxWrapper"
  852. ' Returns a new VBOFListBoxWrapper for the
  853. '   specified VBOFCollection (Required) and
  854. '   ListBox (Optional)
  855. '
  856. ' Coding Example:
  857. '   Dim MyListBoxWrapper as VBOFListBoxWrapper
  858. '   Dim MyCollection as VBOFCollection
  859. '   Set MyListBoxWrapper = _
  860. '       ObjectManager.NewVBOFListBoxWrapper ( _
  861. '           Collection:=MyCollection, _
  862. '           ListBox:=MyListBox)
  863.  
  864.     Dim tempNewListBoxWrapper As New VBOFListBoxWrapper
  865.     
  866.     Set tempNewListBoxWrapper.ObjectManager = Me
  867.     
  868. ' bullet-proofing
  869.     If IsMissing(Collection) Then
  870.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewVBOFListBoxWrapper' method because the 'Collection:=' parameter is missing."
  871.         Set NewVBOFListBoxWrapper = Nothing
  872.         Exit Function
  873.     End If
  874.     If IsMissing(ListBox) Then
  875.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewVBOFListBoxWrapper' method because the 'ListBox:=' parameter is missing."
  876.         Set NewVBOFListBoxWrapper = Nothing
  877.         Exit Function
  878.     End If
  879.  
  880. ' initialize the Collection
  881.     If Not IsMissing(Collection) Then
  882.         If Not Collection Is Nothing Then
  883.             Set tempNewListBoxWrapper.Collection = _
  884.                 Collection
  885.         End If
  886.     End If
  887.     
  888.     If Not IsMissing(ListBox) Then
  889.         If Not ListBox Is Nothing Then
  890.             Set tempNewListBoxWrapper.ListBox = _
  891.                 ListBox
  892.         End If
  893.     End If
  894.     
  895. ' have the new wrapper bind itself to the ListBox
  896.     If Not tempNewListBoxWrapper.ListBox Is Nothing Then
  897.         If Not tempNewListBoxWrapper.Collection Is Nothing Then
  898.             tempNewListBoxWrapper.Rebind _
  899.                 Collection:=Collection, _
  900.                 ListBox:=ListBox
  901.         End If
  902.     End If
  903.     
  904. ' generate a unique ObjectID for the new VBOFListBoxWrapper
  905.     pvtVBOFCollectionID = _
  906.         pvtVBOFCollectionID + 1
  907.     tempNewListBoxWrapper.ObjectID = _
  908.         pvtVBOFCollectionID
  909.     
  910.     Set NewVBOFListBoxWrapper = _
  911.         tempNewListBoxWrapper
  912. End Function
  913.  
  914. Public Function NewVBOFDataWrapper(Optional Collection As Variant, Optional DataControl As Variant) As VBOFDataWrapper
  915. Attribute NewVBOFDataWrapper.VB_Description = "Instantiates a new VBOFDataWrapper"
  916. ' Returns a new VBOFDataWrapper for the
  917. '   specified VBOFCollection, and optionally the
  918. '   DataControl
  919. '
  920. ' Coding Example:
  921. '   Dim MyDataWrapper as VBOFDataWrapper
  922. '   Dim MyCollection as VBOFCollection
  923. '   Set MyDataWrapper = _
  924. '       ObjectManager.NewVBOFDataWrapper ( _
  925. '           Collection:=MyCollection)
  926. ' or
  927. '   Set MyDataWrapper = _
  928. '       ObjectManager.NewVBOFDataWrapper ( _
  929. '           Collection:=MyCollection, _
  930. '           DataControl:=MyDataControl)
  931.  
  932.     Dim tempNewDataWrapper As New VBOFDataWrapper
  933.     
  934.     Set tempNewDataWrapper.ObjectManager = Me
  935.     
  936. ' bullet-proofing
  937.     If IsMissing(Collection) Then
  938.         pvtErrorMessage TypeName(Me) & " cannot process the '.NewVBOFDataWrapper' method because the 'Collection:=' parameter is missing."
  939.         Set NewVBOFDataWrapper = Nothing
  940.         Exit Function
  941.     End If
  942.  
  943. ' initialize the Collection
  944.     If Not IsMissing(Collection) Then
  945.         If Not Collection Is Nothing Then
  946.             Set tempNewDataWrapper.Collection = _
  947.                 Collection
  948.         End If
  949.     End If
  950.     
  951.     If Not IsMissing(DataControl) Then
  952.         If Not DataControl Is Nothing Then
  953.             Set tempNewDataWrapper.DataControl = _
  954.                 DataControl
  955.         End If
  956.     End If
  957.     
  958. ' have the new wrapper bind itself to the DataControl
  959.     If Not tempNewDataWrapper.DataControl Is Nothing Then
  960.         If Not tempNewDataWrapper.Collection Is Nothing Then
  961.             tempNewDataWrapper.Rebind _
  962.                 Collection:=Collection, _
  963.                 DataControl:=DataControl
  964.         End If
  965.     End If
  966.     
  967. ' generate a unique ObjectID for the new VBOFListBoxWrapper
  968.     pvtVBOFCollectionID = _
  969.         pvtVBOFCollectionID + 1
  970.     tempNewDataWrapper.ObjectID = _
  971.         pvtVBOFCollectionID
  972.     
  973.     Set NewVBOFDataWrapper = _
  974.         tempNewDataWrapper
  975. End Function
  976.  
  977. Public Property Get ObjectWasUnique() As Boolean
  978. Attribute ObjectWasUnique.VB_Description = "Private"
  979.     ObjectWasUnique = pvtObjectWasUnique
  980. End Property
  981.  
  982. Public Function ParentsOfObject(Optional Object As Variant) As Collection
  983. Attribute ParentsOfObject.VB_Description = "Returns a VB Collection of all of the known Parents (containers) of the specified object"
  984. ' Returns a Collection of VBOFCollections which
  985. '   are Parents of Object.
  986. ' Note: knowledge of an Object's parents is not
  987. '   considered good object-oriented technique
  988.  
  989.     Dim tempVBOFCollection As VBOFCollection
  990.     Dim tempCollection As New Collection
  991.     Dim I As Long
  992.     
  993. ' process each VBOFCollection
  994.     I = 1
  995.     For Each tempVBOFCollection In pvtSystemCollections
  996.         
  997. ' process each object therein
  998.         If pvtObjectIndexInCollection( _
  999.             Object:=Object, _
  1000.             Collection:=tempVBOFCollection) > 0 _
  1001.         Then
  1002.             tempCollection.Add _
  1003.                 Item:=tempVBOFCollection, _
  1004.                 Key:=CStr(I)
  1005.                 
  1006.             I = I + 1
  1007.         End If
  1008.     
  1009.     Next tempVBOFCollection
  1010.  
  1011.     Set ParentsOfObject = tempCollection
  1012. End Function
  1013.  
  1014. Private Function pvtObjectIndexInCollection(Optional Object As Variant, Optional Collection As Variant) As Long
  1015. ' Returns the index of the Object within the
  1016. '   Collection
  1017.     
  1018.     Dim tempObject As Object
  1019.     Dim I As Long
  1020.     
  1021. ' check each of the Objects defined to the
  1022. '   Collection
  1023.     I = 0
  1024.     For I = 1 To Collection.Count
  1025.         Set tempObject = Collection.Item(I)
  1026.  
  1027. ' return the Collection's index position
  1028.         If TypeName(tempObject) = TypeName(Object) Then
  1029.             If tempObject.ObjectID = Object.ObjectID Then
  1030.                 pvtObjectIndexInCollection = I
  1031.                 Exit Function
  1032.             End If
  1033.         End If
  1034.     Next I
  1035.  
  1036.     pvtObjectIndexInCollection = -1
  1037. End Function
  1038.  
  1039. Private Function pvtObjectParent(Optional Object As Variant) As VBOFCollection
  1040. ' Returns the first VBOFCollection found
  1041. '   to contain Object
  1042.  
  1043.     Dim tempVBOFCollection As VBOFCollection
  1044.     Dim tempObject As Object
  1045.     
  1046. ' process each VBOFCollection
  1047.     For Each tempVBOFCollection In pvtSystemCollections
  1048.         
  1049. ' process each object therein
  1050.         If pvtObjectIndexInCollection( _
  1051.             Object:=Object, _
  1052.             Collection:=tempVBOFCollection) > 0 _
  1053.         Then
  1054.             Set pvtObjectParent = tempVBOFCollection
  1055.             Exit Function
  1056.         End If
  1057.     Next tempVBOFCollection
  1058.     
  1059. ' didn't find an Parent
  1060.     Set pvtObjectParent = Nothing
  1061. End Function
  1062.  
  1063. Private Function pvtODBCPassThrough(ODBCPassThrough As Boolean) As Long
  1064.  
  1065.     If ODBCPassThrough Then
  1066.         pvtODBCPassThrough = dbSQLPassThrough
  1067.     Else
  1068.         pvtODBCPassThrough = 0
  1069.     End If
  1070. End Function
  1071.  
  1072. Public Function RegisterForObjectEvent(Optional TriggerObject As Variant, Optional TriggerObjectType As Variant, Optional TriggerEvent As Variant, Optional RegisterObject As Variant, Optional RegisterType As Variant) As Boolean
  1073. Attribute RegisterForObjectEvent.VB_Description = "Registers an object as a recipient of certain object-related events"
  1074. ' Pass-through to the EventManager
  1075.  
  1076. #If NoEventMgr = False Then
  1077.     RegisterForObjectEvent = _
  1078.         pvtVBFWEventManager. _
  1079.             RegisterForObjectEvent( _
  1080.                 TriggerObject:=TriggerObject, _
  1081.                 TriggerObjectType:=TriggerObjectType, _
  1082.                 TriggerEvent:=TriggerEvent, _
  1083.                 RegisterObject:=RegisterObject, _
  1084.                 RegisterType:=RegisterType)
  1085. #Else
  1086.     If Verbose Then
  1087.         DisplayErrorMessage TypeName(Me) & " (Warning) the .RegisterForObjectEvent method has been executed, but the conditional compilation parameter 'NoEventMgr = -1' has been specified.  No Event code is generated unless 'NoEventMgr = 0' or 'NoEventMgr' is missing from the conditional compilation string altogether."
  1088.     End If
  1089. #End If
  1090.  
  1091.     RegisterForObjectEvent = True
  1092. End Function
  1093.  
  1094. Public Function RegisterForCollectionEvent(Optional Collection As Variant, Optional RegisterObject As Variant, Optional TriggerEvent As Variant) As Boolean
  1095. Attribute RegisterForCollectionEvent.VB_Description = "Registers an object as a recipient of certain VBOFCollection-related events"
  1096. ' Pass-through to the EventManager
  1097.  
  1098. #If NoEventMgr = False Then
  1099.     RegisterForCollectionEvent = _
  1100.         pvtVBFWEventManager. _
  1101.             RegisterForCollectionEvent( _
  1102.                 Collection:=Collection, _
  1103.                 TriggerEvent:=TriggerEvent, _
  1104.                 RegisterObject:=RegisterObject)
  1105. #Else
  1106.     If Verbose Then
  1107.         DisplayErrorMessage TypeName(Me) & " (Warning) the .RegisterForCollectionEvent method has been executed, but the conditional compilation parameter 'NoEventMgr = -1' has been specified.  No Event code is generated unless 'NoEventMgr = 0' or 'NoEventMgr' is missing from the conditional compilation string altogether."
  1108.     End If
  1109. #End If
  1110.  
  1111.     RegisterForCollectionEvent = True
  1112. End Function
  1113.  
  1114.  
  1115. Public Function RemoveCollection(Optional Collection As Variant, Optional NoDelete As Variant, Optional CleanUpMode As Variant) As Boolean
  1116. Attribute RemoveCollection.VB_Description = "Private"
  1117. ' Remove the Collection and its contents
  1118. '
  1119. ' Note: refer to the value of CleanUpMode to
  1120. '   determine whether or not the automatic object
  1121. '   containment links between containing objects and
  1122. '   contained objects will be severed
  1123.     
  1124.     On Local Error Resume Next
  1125.         
  1126.     Collection.pvtCloseRecordSet
  1127.         
  1128.     EmptyCollection _
  1129.         Collection:=Collection, _
  1130.         NoDelete:=NoDelete, _
  1131.         CleanUpMode:=CleanUpMode
  1132.         
  1133.     UnRegisterForAllEvents _
  1134.         RegisterObject:=Collection, _
  1135.         CleanUpMode:=CleanUpMode
  1136.  
  1137.     Set Collection = Nothing
  1138.     
  1139.     RemoveCollection = True
  1140. End Function
  1141.  
  1142.  
  1143. Public Function RemoveWrapper(ParamArray WrapperCollection())
  1144. Attribute RemoveWrapper.VB_Description = "Private"
  1145. ' Removes Wrapper(s) in an orderly manner.
  1146. '
  1147. ' Note: See also method "Form_QueryUnload"
  1148.  
  1149.     Dim I As Long
  1150.  
  1151.     On Local Error Resume Next
  1152.     
  1153.     For I = 0 To UBound(WrapperCollection)
  1154.         If InStr(TypeName(WrapperCollection(I)), "Wrapper") > 0 Then
  1155.             WrapperCollection(I).Unbind
  1156.             
  1157.             Me.TerminateObject _
  1158.                WrapperCollection(I)
  1159.         End If
  1160.         
  1161.         Set WrapperCollection(I) = Nothing
  1162.     Next I
  1163. End Function
  1164.  
  1165.  
  1166. Public Function SystemObject(Optional TypeName As Variant, Optional ObjectID As Variant) As Variant
  1167. Attribute SystemObject.VB_Description = "Private"
  1168. ' Returns an Object whose TypeName matches TypeName
  1169. '   and whose Object matches ObjectID
  1170. ' Note: in most cases, the results of this method
  1171. '   and the use thereof is not considered good
  1172. '   object-oriented behavior
  1173.  
  1174.     Dim tempObject As Variant
  1175.  
  1176.     On Local Error Resume Next
  1177.  
  1178. ' bullet-proofing
  1179.     If IsMissing(TypeName) _
  1180.     Or IsMissing(ObjectID) Then
  1181.         pvtErrorMessage TypeName(Me) & " cannot process the '.SystemObject' method because either the 'TypeName:=' or 'ObjectID:=' parameter is missing."
  1182.         Set SystemObject = Nothing
  1183.         Exit Function
  1184.     End If
  1185.     
  1186. ' find the desired object and return ir
  1187.     For Each tempObject In pvtSystemObjects
  1188.         If TypeName(tempObject) = TypeName Then
  1189.             If tempObject.ObjectID = ObjectID Then
  1190.                 Set SystemObject = tempObject
  1191.                 Exit Function
  1192.             End If
  1193.         End If
  1194.     
  1195.     Next tempObject
  1196.     
  1197.     Set SystemObject = Nothing
  1198. End Function
  1199.  
  1200. Public Function SystemObjects() As Collection
  1201. Attribute SystemObjects.VB_Description = "Private"
  1202. ' Returns a Collection (that's the VB4 Collection
  1203. '   object, not the VBOFCollection object)
  1204. '   which contains a reference to each object
  1205. '   currently being managed by VBOFObjectManager
  1206.     
  1207.     Set SystemObjects = pvtSystemObjects
  1208. End Function
  1209.  
  1210. Public Function SystemCollections() As Collection
  1211. Attribute SystemCollections.VB_Description = "Private"
  1212. ' Returns a Collection (that's the VB4 Collection
  1213. '   object, not the VBOFCollection object)
  1214. '   which contains a reference to each
  1215. '   VBOFCollection currently being managed by
  1216. '   VBOFObjectManager
  1217.  
  1218.     Set SystemCollections = pvtSystemCollections
  1219. End Function
  1220.  
  1221. Private Function pvtIsExactlyTheSameObject(Optional Object1 As Variant, Optional Object2 As Variant) As Boolean
  1222. ' Determines whether two objects are exactly the
  1223. '   same.
  1224. ' Note: this is a kind of kludge, but necessary
  1225. '   because VB doesn't return pointers to the objects
  1226.  
  1227.     Dim tempObjectID As Long
  1228.     
  1229. ' test by changing one, then checking the other
  1230.     tempObjectID = Object1.ObjectID
  1231.     Object1.ObjectID = -1
  1232.     If Object2.ObjectID = -1 Then
  1233.         pvtIsExactlyTheSameObject = True
  1234.     Else
  1235.         pvtIsExactlyTheSameObject = False
  1236.     End If
  1237.  
  1238. ' reinstate the previous value
  1239.     Object1.ObjectID = tempObjectID
  1240. End Function
  1241.  
  1242. Public Function RemoveObject(Optional Object As Variant, Optional Parent As Variant, Optional Collection As Variant, Optional NoDelete As Variant, Optional CleanUpMode As Variant) As Boolean
  1243. Attribute RemoveObject.VB_Description = "Removes an object from VBOF and from the databse"
  1244. ' Remove the Object from the specified Parent.
  1245. '   Delete the Object if its ParentCount = 0
  1246. ' Note: if a Table is supporting the Collection
  1247. '   then the VBOF automatic containment link to
  1248. '   the contained object (Collection.Parent) is also
  1249. '   severed (unless CleanUpMode:=True)
  1250.     
  1251.     Dim tempIndex As Long
  1252.     Dim tempParent As VBOFCollection
  1253.     Dim tempNoDelete As Boolean
  1254.     Dim tempCleanUpMode As Boolean
  1255.     
  1256.     On Local Error Resume Next
  1257.     
  1258. ' bullet-proofing
  1259.     If IsMissing(Object) And IsMissing(Parent) And IsMissing(Collection) Then
  1260.         pvtErrorMessage TypeName(Me) & " cannot process the '.RemoveObject' method for this object because either the 'Object:=', 'Collection:=' or the 'Parent:=' parameter is missing"
  1261.         RemoveObject = False
  1262.         Exit Function
  1263.     End If
  1264.     If Object.ObjectID < 0 Then
  1265.         RemoveObject = False
  1266.         Exit Function
  1267.     End If
  1268.     
  1269.     If IsMissing(NoDelete) Then
  1270.         tempNoDelete = False
  1271.     Else
  1272.         tempNoDelete = NoDelete
  1273.     End If
  1274.     
  1275.     If IsMissing(CleanUpMode) Then
  1276.         tempCleanUpMode = False
  1277.     Else
  1278.         tempCleanUpMode = CleanUpMode
  1279.     End If
  1280.  
  1281. ' if the Parent:= is missing, find the first Parent
  1282. '   Note: herein, a Parent is an VBOFCollection
  1283.     If Not IsMissing(Parent) Then
  1284.         Set tempParent = Parent
  1285.     ElseIf Not IsMissing(Collection) Then
  1286.         Set tempParent = Collection
  1287.     Else
  1288.         Set tempParent = _
  1289.             pvtObjectParent(Object)
  1290.     End If
  1291.     
  1292. ' remove event registrations
  1293. #If NoEventMgr = False Then
  1294.     UnRegisterForAllEvents _
  1295.         RegisterObject:=Object, _
  1296.         CleanUpMode:=CleanUpMode
  1297. #End If
  1298.  
  1299. ' schedule orphans to be deleted
  1300.     If tempParent Is Nothing Then
  1301.         Object.ObjectParentCount = 0
  1302.     End If
  1303.     
  1304. ' if there's only 1 Parent (or less)
  1305.     If ParentsOfObject(Object).Count <= 1 Then
  1306.     
  1307. ' remove the Object from the specified Parent,
  1308. '   and delete it according to NoDelete
  1309.         If Not tempParent Is Nothing Then
  1310.             tempParent.Remove _
  1311.                 Item:=Object, _
  1312.                 NoDelete:=tempNoDelete, _
  1313.                 CleanUpMode:=CleanUpMode
  1314.         End If
  1315.         
  1316. ' free the Object
  1317.         pvtFreeObject _
  1318.             Object:=Object
  1319.         
  1320. #If NoDebugMode = False Then
  1321.         If DebugMode Then
  1322.             DisplayDebugMessage _
  1323.                 TypeName(Me) & " 'RemoveObject' has removed the ObjectType=" & _
  1324.             TypeName(Object) & _
  1325.             ", ObjectID=" & _
  1326.             Object.ObjectID
  1327.         End If
  1328. #End If
  1329.         
  1330.         RemoveObject = True
  1331.         Exit Function
  1332.     
  1333. ' remove the Object from the specified Parent,
  1334. '   but don't delete it
  1335.     Else
  1336.         Parent.Remove _
  1337.             Item:=Object, _
  1338.             NoDelete:=True, _
  1339.             CleanUpMode:=CleanUpMode
  1340.  
  1341. ' drop Object's ParentCount by 1
  1342.         Object.ObjectParentCount = _
  1343.             Object.ObjectParentCount - 1
  1344.         
  1345. #If NoDebugMode = False Then
  1346.         If DebugMode Then
  1347.             DisplayDebugMessage _
  1348.                 TypeName(Me) & " 'RemoveObject' has decremented the ObjectParentCount to " & Object.ObjectParentCount & " for ObjectType=" & _
  1349.             TypeName(Object) & _
  1350.             ", ObjectID=" & _
  1351.             Object.ObjectID
  1352.         End If
  1353. #End If
  1354.         
  1355.         RemoveObject = True
  1356.         Exit Function
  1357.     End If
  1358. End Function
  1359.  
  1360. Private Function pvtErrorMessage(Optional ErrorMessage As Variant) As Long
  1361.     pvtErrorMessage = _
  1362.         DisplayErrorMessage(ErrorMessage)
  1363. End Function
  1364.  
  1365.  
  1366. Private Function pvtObjectIndexInSystemObjects(Optional Object As Variant) As Long
  1367. ' Return the Index of Object in the collection
  1368. '   of system objects
  1369.     
  1370.     Dim tempObject As Object
  1371.     Dim I As Long
  1372.     
  1373.     On Local Error Resume Next
  1374.     
  1375. ' quick-check to see if the object exists
  1376.     Set tempObject = _
  1377.         pvtSystemObjects(TypeName(Object) & " " & _
  1378.         CStr(Object.ObjectID))
  1379.     If Err = 5 Then
  1380.         pvtObjectIndexInSystemObjects = -1
  1381.         Exit Function
  1382.     End If
  1383.     
  1384. ' the object likely exists in the SystemObjects.
  1385. '   find its Index.
  1386.  
  1387. ' check each of the objects known at this time
  1388.     I = 0
  1389.     For Each tempObject In pvtSystemObjects
  1390.         I = I + 1
  1391.  
  1392. ' return the collection's index position
  1393.         If TypeName(tempObject) = TypeName(Object) Then
  1394.             If tempObject.ObjectID = Object.ObjectID Then
  1395.                 pvtObjectIndexInSystemObjects = I
  1396.                 Exit Function
  1397.             End If
  1398.         End If
  1399.     Next tempObject
  1400.  
  1401.  ' return "not found"
  1402.     pvtObjectIndexInSystemObjects = -1
  1403.     Exit Function
  1404. End Function
  1405.  
  1406.  
  1407. Public Function AddUniqueObject(Optional Object As Variant, Optional Parent As Variant) As Variant
  1408. Attribute AddUniqueObject.VB_Description = "(Private) Ensures no duplicate instances of a given object exist"
  1409. ' Return a system-wide unique object which is the
  1410. '   Item, or an already existing, functionally
  1411. '   equivalent of the Item
  1412. ' Note: this method, while public, is designed to be
  1413. '   invoked only by the .Add method of an instance
  1414. '   of VBOFCollection.  Any other use must make
  1415. '   allowances for Object to have been freed and
  1416. '   replaced by an equivalent object which was
  1417. '   found to have already existed under the control
  1418. '   of VBOFObjectManager
  1419.     
  1420.     Dim tempObject As Object
  1421.     Dim tempIndex As Long
  1422.     
  1423.     On Local Error Resume Next
  1424.     pvtObjectWasUnique = False
  1425.     
  1426. ' bullet-proofing
  1427.     If IsMissing(Object) Then
  1428.         pvtErrorMessage TypeName(Me) & " cannot process the '.AddUniqueObject' method for this object because the 'Object:=' parameter is missing"
  1429.         AddUniqueObject = False
  1430.         Exit Function
  1431.     End If
  1432.     
  1433. ' initialize all objects that pass through here,
  1434. '   in support of VBOF services
  1435.     Set Object.ObjectManager = _
  1436.         Me
  1437.  
  1438. ' check each of the objects known at this time
  1439.     tempIndex = _
  1440.         pvtObjectIndexInSystemObjects _
  1441.             (Object:=Object)
  1442.  
  1443. ' if found, return the located object
  1444.     If tempIndex > 0 Then
  1445.         Set tempObject = _
  1446.             pvtSystemObjects.Item _
  1447.                 (tempIndex)
  1448.         
  1449. ' if these are exactly the same object
  1450.         If pvtIsExactlyTheSameObject( _
  1451.             Object1:=Object, _
  1452.             Object2:=tempObject) _
  1453.         Then
  1454.  
  1455. ' increase the ParentCount of the previously
  1456. '   existing object
  1457.             Object.ObjectParentCount = _
  1458.                 Object.ObjectParentCount + 1
  1459.  
  1460. #If NoDebugMode = False Then
  1461.             If DebugMode Then
  1462.                 DisplayDebugMessage _
  1463.                     TypeName(Me) & " 'Add Object' attempt found exact same (already existing) Object.  ObjectType=" & _
  1464.                     TypeName(Object) & _
  1465.                     ", ObjectID=" & _
  1466.                     Object.ObjectID
  1467.             End If
  1468. #End If
  1469.             
  1470.         Else
  1471. ' else, free the Object (the parameter)
  1472.             Object.ObjectID = -1
  1473.             Set Object = Nothing
  1474.         End If
  1475.         
  1476. ' return the located object
  1477.         Set AddUniqueObject = _
  1478.             pvtSystemObjects.Item _
  1479.                 (tempIndex)
  1480.  
  1481. #If NoDebugMode = False Then
  1482.         If DebugMode Then
  1483.             DisplayDebugMessage _
  1484.                 TypeName(Me) & " 'Add Object' attempt found an existing Object.  ObjectType=" & _
  1485.                 TypeName(Object) & _
  1486.                 ", ObjectID=" & _
  1487.                 Object.ObjectID
  1488.         End If
  1489. #End If
  1490.  
  1491.         GoTo AddUniqueObject_Exit
  1492.     End If
  1493.     
  1494. ' else, the object is unique
  1495. '   add the object to the collection of system objects
  1496.     pvtSystemObjects.Add _
  1497.         Item:=Object, _
  1498.         Key:=TypeName(Object) & " " & CStr(Object.ObjectID)
  1499.         
  1500. ' mark the object as "Added"
  1501.     Object.ObjectAdded = True
  1502.  
  1503. ' trigger the "Instantiated" event for the new object
  1504. #If NoEventMgr = False Then
  1505.     TriggerObjectEvent _
  1506.         Event:="Instantiated", _
  1507.         Object:=Object
  1508. #End If
  1509.  
  1510. #If NoDebugMode = False Then
  1511.     If DebugMode Then
  1512.         DisplayDebugMessage _
  1513.             TypeName(Me) & " 'Add Object' attempt did not find any existing Object.  The Object was added, ObjectType=" & _
  1514.             TypeName(Object) & _
  1515.             ", ObjectID=" & _
  1516.             Object.ObjectID
  1517.     End If
  1518. #End If
  1519.  
  1520. ' initialize the new object in support of
  1521. '   VBOF services
  1522.     InitializeObject _
  1523.         Object:=Object
  1524.  
  1525. ' return the original object
  1526.     Set AddUniqueObject = Object
  1527.     pvtObjectWasUnique = True
  1528.  
  1529. AddUniqueObject_Exit:
  1530.     Set tempObject = Nothing
  1531. End Function
  1532.  
  1533. Public Function DisplayErrorMessage(Optional ErrorMessage As Variant) As Long
  1534. Attribute DisplayErrorMessage.VB_Description = "Private"
  1535.  
  1536.     Dim RC As Long
  1537.  
  1538.     If Err <> 0 Then
  1539.         RC = MsgBox( _
  1540.             ErrorMessage & vbCrLf & "Err=" & Err & ", Msg=" & Error(Err) & _
  1541.             vbCrLf & "Version=" & Version & ", Date=" & VersionDate, _
  1542.             vbOK + vbExclamation, _
  1543.             TypeName(Me) & " Run-Time Message")
  1544.     Else
  1545.         RC = MsgBox( _
  1546.             ErrorMessage & _
  1547.             vbCrLf & "Version=" & Version, _
  1548.             vbOK + vbExclamation, _
  1549.             TypeName(Me) & " Run-Time Message")
  1550.     End If
  1551.     
  1552.     Err = 0
  1553.     DisplayErrorMessage = RC
  1554. End Function
  1555.  
  1556.  
  1557. Public Property Get ObjectManager() As VBOFObjectManager
  1558. Attribute ObjectManager.VB_Description = "Private"
  1559.     Set ObjectManager = Me
  1560. End Property
  1561.  
  1562.  
  1563.  
  1564.  
  1565. Public Function ObjectID() As Long
  1566. Attribute ObjectID.VB_Description = "Private"
  1567.     ObjectID = -1
  1568. End Function
  1569.  
  1570.  
  1571.  
  1572. Public Function NewVBOFCollection(Optional Database As Variant, Optional Parent As Variant, Optional Owner As Variant) As VBOFCollection
  1573. Attribute NewVBOFCollection.VB_Description = "Instantiates a new VBOFCollection"
  1574. '  Return a new, properly instantiated
  1575. '   VBOFCollection object
  1576.  
  1577.     Dim tempVBOFCollection As New VBOFCollection
  1578.     
  1579.     On Local Error Resume Next
  1580.     
  1581. ' generate a unique ObjectID for the new VBOFCollection
  1582.     pvtVBOFCollectionID = pvtVBOFCollectionID + 1
  1583.     
  1584. ' initialize
  1585.     Set tempVBOFCollection.ObjectManager = Me
  1586.     With tempVBOFCollection
  1587.         .ObjectID = pvtVBOFCollectionID
  1588.         .AutoDeleteOrphans = Me.AutoDeleteOrphans
  1589.     End With
  1590.     
  1591. ' set any known parameters
  1592.     If Not IsMissing(Database) Then
  1593.         Set pvtDatabase = Database
  1594.     End If
  1595.     If Not IsMissing(Owner) Then
  1596.         Set tempVBOFCollection.Parent = Owner
  1597.     End If
  1598.     If Not IsMissing(Parent) Then
  1599.         Set tempVBOFCollection.Parent = Parent
  1600.     End If
  1601.  
  1602. ' pass-along any known database parms
  1603.     tempVBOFCollection. _
  1604.         SetDatabaseParameters _
  1605.             ODBCPassThrough:=ODBCPassThrough, _
  1606.             ANSISQL:=ANSISQL, _
  1607.             Database:=pvtDatabase
  1608.  
  1609. ' add the new VBOFCollection to the
  1610. '   system-wide collection of
  1611. '   VBOFCollections, for management
  1612. '   purposes
  1613.     pvtSystemCollections.Add _
  1614.         Item:=tempVBOFCollection
  1615.  
  1616. #If NoDebugMode = False Then
  1617.     If DebugMode Then
  1618.         DisplayDebugMessage _
  1619.             TypeName(Me) & " 'NewVBOFCollection' completed, new ObjectID=" & _
  1620.             tempVBOFCollection.ObjectID
  1621.     End If
  1622. #End If
  1623.  
  1624.     Set NewVBOFCollection = tempVBOFCollection
  1625. End Function
  1626.  
  1627.  
  1628. Public Sub Form_QueryUnload(Form As Variant, ParamArray WrapperCollection())
  1629. Attribute Form_QueryUnload.VB_Description = "Manages the termination of a Form"
  1630. ' Cleans-up while a Form is being Unloaded
  1631. '
  1632. ' Programming Example:
  1633. '   Private Sub Form_QueryUnload(...)
  1634. '       If Not ObjectManager Is Nothing Then
  1635. '           ObjectManager.Form_QueryUnload _
  1636. '               Me, _
  1637. '               MyListBoxWrapper, _
  1638. '               MyListBoxOtherWrapper, _
  1639. '               MyDBGridWrapper, _
  1640. '               MyDBGridOtherWrapper, _
  1641. '               . . .
  1642. '       End If
  1643.     
  1644. ' remove event registrations
  1645. #If NoEventMgr = False Then
  1646.     UnRegisterForAllEvents _
  1647.         RegisterObject:=Form, _
  1648.         CleanUpMode:=False
  1649. #End If
  1650.  
  1651.     Me.RemoveWrapper _
  1652.         WrapperCollection()
  1653.  
  1654. End Sub
  1655.  
  1656. Public Function TerminateForm(Form As Variant, ParamArray WrapperCollection())
  1657. Attribute TerminateForm.VB_Description = "Private"
  1658. ' Cleans-up while a Form is being Unloaded.
  1659. '
  1660. ' Note:  This is the equivalent of the method
  1661. '   "Form_QueryUnload" but this method's name
  1662. '   might be easier for the programmer to remember,
  1663. '   given that there is a method named
  1664. '   "TerminateObject", as well, used for
  1665. '   terminating objects
  1666. '
  1667. ' Programming Example:
  1668. '   Private Sub Form_QueryUnload(...)
  1669. '       If Not ObjectManager Is Nothing Then
  1670. '           ObjectManager.TerminateForm _
  1671. '               Me, _
  1672. '               MyListBoxWrapper, _
  1673. '               MyListBoxOtherWrapper, _
  1674. '               MyDBGridWrapper, _
  1675. '               MyDBGridOtherWrapper, _
  1676. '               . . .
  1677. '       End If
  1678.  
  1679.     Me.Form_QueryUnload _
  1680.         Form, _
  1681.         WrapperCollection()
  1682.  
  1683. End Function
  1684.  
  1685.  
  1686. Public Function TerminateObject(Object As Variant) As Boolean
  1687. Attribute TerminateObject.VB_Description = "Terminates an object from VBOF and the databse"
  1688. ' Cleans-up while an object is being terminated.
  1689. '
  1690. ' Programming Example:
  1691. '   Private Sub Class_Terminate()
  1692. '       If Not ObjectManager Is Nothing Then
  1693. '           ObjectManager.TerminateObject _
  1694. '               Object:=Me
  1695. '       End If
  1696.  
  1697.     Me.RemoveObject _
  1698.         Object:=Object, _
  1699.         NoDelete:=True, _
  1700.         CleanUpMode:=False
  1701.  
  1702. End Function
  1703.  
  1704. Public Function TriggerObjectEvent(Optional Event As Variant, Optional Object As Variant, Optional Verbose As Variant) As Boolean
  1705. Attribute TriggerObjectEvent.VB_Description = "Triggers an object event"
  1706. ' Pass-through to the EventManager
  1707.  
  1708. #If NoEventMgr = False Then
  1709.     TriggerObjectEvent = _
  1710.         pvtVBFWEventManager. _
  1711.             TriggerObjectEvent( _
  1712.                 Event:=Event, _
  1713.                 Object:=Object, _
  1714.                 Verbose:=Verbose)
  1715. #Else
  1716.     If Verbose Then
  1717.         DisplayErrorMessage TypeName(Me) & " (Warning) the .TriggerObjectEvent method has been executed, but the conditional compilation parameter 'NoEventMgr = -1' has been specified.  No Event code is generated unless 'NoEventMgr = 0' or 'NoEventMgr' is missing from the conditional compilation string altogether."
  1718.     End If
  1719. #End If
  1720.             
  1721.     TriggerObjectEvent = True
  1722. End Function
  1723.  
  1724. Public Function TriggerCollectionEvent(Optional Event As Variant, Optional Object As Variant, Optional Collection As Variant, Optional Verbose As Variant, Optional NoDelete As Variant) As Boolean
  1725. Attribute TriggerCollectionEvent.VB_Description = "Private"
  1726. ' Pass-through to the EventManager
  1727.  
  1728. #If NoEventMgr = False Then
  1729.     pvtVBFWEventManager. _
  1730.         TriggerCollectionEvent _
  1731.             Event:=Event, _
  1732.             Object:=Object, _
  1733.             Collection:=Collection, _
  1734.             Verbose:=Verbose, _
  1735.             NoDelete:=NoDelete
  1736. #Else
  1737.     If Verbose Then
  1738.         DisplayErrorMessage TypeName(Me) & " (Warning) the .TriggerCollectionEvent method has been executed, but the conditional compilation parameter 'NoEventMgr = -1' has been specified.  No Event code is generated unless 'NoEventMgr = 0' or 'NoEventMgr' is missing from the conditional compilation string altogether."
  1739.     End If
  1740. #End If
  1741.             
  1742.     TriggerCollectionEvent = True
  1743. End Function
  1744.  
  1745.  
  1746. Public Function UnRegisterForAllEvents(Optional RegisterObject As Variant, Optional CleanUpMode As Variant) As Boolean
  1747. Attribute UnRegisterForAllEvents.VB_Description = "Private"
  1748. ' Unregisters the UnregisterObject from all
  1749. '   events
  1750. '   (a wrapper method for
  1751. '       Me.UnRegisterForCollectionEvent and
  1752. '       Me.UnRegisterForObjectEvent
  1753.  
  1754.     Dim tempCleanUpMode As Boolean
  1755.  
  1756.     If IsMissing(CleanUpMode) Then
  1757.         tempCleanUpMode = False
  1758.     Else
  1759.         tempCleanUpMode = CleanUpMode
  1760.     End If
  1761.  
  1762. #If NoEventMgr = False Then
  1763.     Me.UnRegisterForCollectionEvent _
  1764.         RegisterObject:=RegisterObject, _
  1765.         CleanUpMode:=tempCleanUpMode
  1766.  
  1767.     Me.UnRegisterForObjectEvent _
  1768.         RegisterObject:=RegisterObject, _
  1769.         CleanUpMode:=tempCleanUpMode
  1770. #End If
  1771. End Function
  1772.  
  1773. Public Function UnRegisterForObjectEvent(Optional RegisterObject As Variant, Optional CleanUpMode As Variant) As Boolean
  1774. Attribute UnRegisterForObjectEvent.VB_Description = "Private"
  1775. ' UnRegister the Object for Events
  1776.  
  1777. ' don't bother doing this during "CleanUpMode"
  1778. '   because ObjectManager is being killed, anyway
  1779.     If Not IsMissing(CleanUpMode) Then
  1780.         If CleanUpMode Then
  1781.             UnRegisterForObjectEvent = True
  1782.             Exit Function
  1783.         End If
  1784.     End If
  1785.  
  1786. #If NoEventMgr = False Then
  1787.     pvtVBFWEventManager. _
  1788.         UnRegisterForObjectEvent _
  1789.             RegisterObject:=RegisterObject
  1790. #Else
  1791.     If Verbose Then
  1792.         DisplayErrorMessage TypeName(Me) & " (Warning) the .UnRegisterForObjectEvent method has been executed, but the conditional compilation parameter 'NoEventMgr = -1' has been specified.  No Event code is generated unless 'NoEventMgr = 0' or 'NoEventMgr' is missing from the conditional compilation string altogether."
  1793.     End If
  1794. #End If
  1795.  
  1796.     UnRegisterForObjectEvent = True
  1797. End Function
  1798.  
  1799.  
  1800. Public Function Version() As String
  1801. Attribute Version.VB_Description = "Returns the current version of VBOF"
  1802.     Version = "1.0a"
  1803. End Function
  1804.  
  1805. Public Function VersionDate() As String
  1806. Attribute VersionDate.VB_Description = "Returns the current version date of VBOF"
  1807.     VersionDate = "1996-01-01"
  1808. End Function
  1809.  
  1810.  
  1811. Private Sub Class_Initialize()
  1812.  
  1813. #If NoEventMgr = False Then
  1814.     Set pvtVBFWEventManager = _
  1815.         New VBOFEventManager
  1816.     Set pvtVBFWEventManager. _
  1817.         ObjectManager = Me
  1818. #End If
  1819.     
  1820.     Set pvtDatabase = Nothing
  1821.     
  1822.     pvtSynchronousCommit = False
  1823.     pvtDebugMode = False
  1824.     pvtVerbose = False
  1825.     AutoDeleteOrphans = False
  1826.     pvtObjectWasUnique = False
  1827.     pvtVBOFCollectionID = 0
  1828.     HighestObjectID = 0
  1829.     ANSISQL = False
  1830.     ODBCPassThrough = False
  1831.  
  1832. End Sub
  1833.  
  1834.  
  1835.  
  1836. Public Property Get ObjectEventManager() As Variant
  1837. Attribute ObjectEventManager.VB_Description = "Private"
  1838. ' Returns my pvtEventManager
  1839.     
  1840. #If NoEventMgr = False Then
  1841.     Set ObjectEventManager = pvtVBFWEventManager
  1842. #Else
  1843.     Set ObjectEventManager = Nothing
  1844. #End If
  1845. End Property
  1846.  
  1847. Private Function pvtFreeObject(Optional Object As Variant, Optional Index As Variant) As Boolean
  1848. ' Free the Object and remove it from the collection
  1849. '   of known system objects
  1850.         
  1851.     On Local Error Resume Next
  1852.         
  1853.     If Not IsMissing(Index) Then
  1854.         pvtSystemObjects.Remove Index
  1855.     Else
  1856.         pvtSystemObjects.Remove _
  1857.             pvtObjectIndexInSystemObjects(Object:=Object)
  1858.     End If
  1859.         
  1860.     Set Object = Nothing
  1861.     pvtFreeObject = True
  1862. End Function
  1863.  
  1864.  
  1865.  
  1866. Private Function pvtCommitObjects() As Boolean
  1867. ' NOT CURRENTLY SUPPORTED
  1868. '
  1869. ' Coordinates a synchronous database Commit across
  1870. '   all currently instantiated objects.
  1871. ' Returns True or False, depending on whether or not
  1872. '   the Commit was successful (False means that a
  1873. '   Rollback has been issued)
  1874. ' Note: requires use of SynchronousCommit:=True
  1875. '   in a parameter to VBOFObjectManager
  1876.  
  1877.     Dim tempVBOFCollection As VBOFCollection
  1878.     
  1879. ' bullet-proofing
  1880.     If pvtSynchronousCommit = False Then
  1881.         pvtErrorMessage TypeName(Me) & " cannot process the '.CommitObjects' method because the 'SynchronousCommit' environment does not exist.  Execute 'ObjectManager.SynchronousCommit = True'to establish the correct environment."
  1882.         pvtCommitObjects = False
  1883.         Exit Function
  1884.     End If
  1885.      
  1886. #If NoDebugMode = False Then
  1887.     If DebugMode Then
  1888.         DisplayDebugMessage _
  1889.             TypeName(Me) & " Starting 'CommitObjects' processing."
  1890.     End If
  1891. #End If
  1892.  
  1893. ' start the transaction
  1894.     pvtWorkspace.BeginTrans
  1895.     
  1896. ' process each VBOFCollection
  1897.     For Each tempVBOFCollection In pvtSystemCollections
  1898.         
  1899. ' have each commit
  1900.         If Not tempVBOFCollection.Commit Then
  1901.             pvtWorkspace.Rollback
  1902.             pvtCommitObjects = False
  1903.             Exit Function
  1904.         End If
  1905.     Next tempVBOFCollection
  1906.     
  1907. ' commit the transaction
  1908.     pvtWorkspace.CommitTrans
  1909.      
  1910. #If NoDebugMode = False Then
  1911.     If DebugMode Then
  1912.         DisplayDebugMessage _
  1913.             TypeName(Me) & " 'CommitObjects' finished successfully."
  1914.     End If
  1915. #End If
  1916.  
  1917.     pvtCommitObjects = True
  1918.     Exit Function
  1919. End Function
  1920.  
  1921. Public Property Set Database(aDatabase As Database)
  1922. Attribute Database.VB_Description = "Sets the Database property"
  1923.     Set pvtDatabase = aDatabase
  1924.      
  1925. #If NoDebugMode = False Then
  1926.     If DebugMode Then
  1927.         DisplayDebugMessage _
  1928.             TypeName(Me) & " 'Database' set to " & TypeName(aDatabase)
  1929.     End If
  1930. #End If
  1931.  
  1932. End Property
  1933.  
  1934. Public Property Get Workspace() As Workspace
  1935. Attribute Workspace.VB_Description = "Maps to the Workspace property"
  1936.     Set Workspace = pvtWorkspace
  1937. End Property
  1938.  
  1939. Public Property Set Workspace(aWorkspace As Workspace)
  1940.     Set pvtWorkspace = aWorkspace
  1941. End Property
  1942.  
  1943. Public Function EmptyCollection(Optional Collection As Variant, Optional NoDelete As Variant, Optional CleanUpMode As Variant) As Boolean
  1944. Attribute EmptyCollection.VB_Description = "Private"
  1945. ' Empty the VBOFCollection of all its Objects.
  1946. '
  1947. ' Note: if a DataSource is supporting the Collection
  1948. '   then the VBOF automatic containment links to
  1949. '   the contained objects are also severed
  1950.     
  1951.     Dim tempIndex As Long
  1952.     Dim tempVBOFCollection As VBOFCollection
  1953.     Dim tempObject As Object
  1954.     Dim I As Long
  1955.     
  1956.     On Local Error Resume Next
  1957.     
  1958. ' bullet-proofing
  1959.     If IsMissing(Collection) Then
  1960.         pvtErrorMessage TypeName(Me) & " cannot process the '.EmptyCollection' method for this object because the 'Collection:=' parameter is missing"
  1961.         EmptyCollection = False
  1962.         Exit Function
  1963.     End If
  1964.     
  1965. ' free all of its referenced Objects
  1966.     For I = 1 To Collection.Count
  1967.         
  1968.         Set tempObject = Collection.Item(I)
  1969.         
  1970. #If NoDebugMode = False Then
  1971.         If DebugMode Then
  1972.             DisplayDebugMessage _
  1973.                 TypeName(Me) & " 'RemoveCollection' is removing the Collection.ObjectID=" & _
  1974.                 tempObject.ObjectID
  1975.         End If
  1976. #End If
  1977.  
  1978.         RemoveObject _
  1979.             Object:=tempObject, _
  1980.             Parent:=Collection, _
  1981.             NoDelete:=NoDelete, _
  1982.             CleanUpMode:=CleanUpMode
  1983.             
  1984.     Next I
  1985.     
  1986.     EmptyCollection = True
  1987. End Function
  1988.  
  1989. Public Property Let DebugMode(aBoolean As Boolean)
  1990. Attribute DebugMode.VB_Description = "Maps to the DebugMode property"
  1991.     pvtDebugMode = aBoolean
  1992.     
  1993. #If NoDebugMode = False Then
  1994.     If pvtDebugMode Then
  1995.         DisplayDebugMessage TypeName(Me) & " starting debug mode"
  1996.     End If
  1997. #Else
  1998.     If aBoolean Then
  1999.         DisplayErrorMessage TypeName(Me) & " (Warning) DebugMode has been requested, but the conditional compilation parameter 'NoDebugMode = -1' has been specified.  No debug code is generated unless 'NoDebugMode = 0' or 'NoDebug' is missing from the conditional compilation string altogether."
  2000.     End If
  2001. #End If
  2002. End Property
  2003.  
  2004. Public Property Get DebugMode() As Boolean
  2005.     DebugMode = pvtDebugMode
  2006. End Property
  2007.  
  2008.  
  2009. Public Property Get Verbose() As Boolean
  2010. Attribute Verbose.VB_Description = "Maps to the Verbose property"
  2011.     Verbose = pvtVerbose
  2012. End Property
  2013. Public Property Let Verbose(aBoolean As Boolean)
  2014.     pvtVerbose = aBoolean
  2015. End Property
  2016.  
  2017.  
  2018. Private Property Get pvtSynchronousCommit()
  2019. ' NOT CURRENTLY SUPPORTED
  2020. '
  2021. ' Return the current state of the
  2022. '   SynchronousCommit environment (True or False)
  2023.     
  2024. '    SynchronousCommit = pvtSynchronousCommit
  2025. End Property
  2026.  
  2027. Private Property Let pvtSynchronousCommit(aBoolean)
  2028. ' NOT CURRENTLY SUPPORTED
  2029. '
  2030. ' Set the SynchronousCommit environment to aBoolean
  2031.         
  2032. '#If NoDebugMode = False Then
  2033. '    If DebugMode Then
  2034. '        DisplayDebugMessage _
  2035. '            TypeName(Me) & " 'SynchronousCommit' mode has been set to " & aBoolean
  2036. '    End If
  2037. '#End If
  2038.     
  2039. '    pvtSynchronousCommit = aBoolean
  2040. End Property
  2041.  
  2042. Public Function UnRegisterForCollectionEvent(Optional RegisterObject As Variant, Optional CleanUpMode As Variant) As Boolean
  2043. Attribute UnRegisterForCollectionEvent.VB_Description = "Private"
  2044. ' UnRegister the Collection for Events
  2045.  
  2046. ' don't bother doing this during "CleanUpMode",
  2047. '   because ObjectManager is being killed, anyway
  2048.     If Not IsMissing(CleanUpMode) Then
  2049.         If CleanUpMode Then
  2050.             UnRegisterForCollectionEvent = True
  2051.             Exit Function
  2052.         End If
  2053.     End If
  2054.  
  2055. #If NoEventMgr = False Then
  2056.     pvtVBFWEventManager. _
  2057.         UnRegisterForCollectionEvent _
  2058.             RegisterObject:=RegisterObject, _
  2059.             CleanUpMode:=CleanUpMode
  2060. #Else
  2061.     If Verbose Then
  2062.         DisplayErrorMessage TypeName(Me) & " (Warning) the .UnRegisterForCollectionEvent method has been executed, but the conditional compilation parameter 'NoEventMgr = -1' has been specified.  No Event code is generated unless 'NoEventMgr = 0' or 'NoEventMgr' is missing from the conditional compilation string altogether."
  2063.     End If
  2064. #End If
  2065.  
  2066.     UnRegisterForCollectionEvent = True
  2067. End Function
  2068.  
  2069.  
  2070.  
  2071. Public Property Get AutoDeleteOrphans() As Boolean
  2072. Attribute AutoDeleteOrphans.VB_Description = "Maps to the AutoDeleteOrphans property"
  2073.     AutoDeleteOrphans = pvtAutoDeleteOrphans
  2074. End Property
  2075.  
  2076. Public Property Let AutoDeleteOrphans(aBoolean As Boolean)
  2077.     pvtAutoDeleteOrphans = aBoolean
  2078. End Property
  2079.  
  2080.  
  2081.  
  2082.  
  2083. Private Sub Class_Terminate()
  2084. #If NoEventMgr = False Then
  2085.     Set pvtVBFWEventManager = Nothing
  2086. #End If
  2087.  
  2088.     Set pvtSystemCollections = Nothing
  2089.     Set pvtSystemObjects = Nothing
  2090.     Set pvtSystemObjectsDictionary = Nothing
  2091.     Set pvtSystemObjectsDictionaryCollection = Nothing
  2092. End Sub
  2093.  
  2094.  
  2095.