[AccessD] Building a control class

A.D.Tejpal adtp at airtelmail.in
Mon Mar 9 08:30:09 CDT 2009


John, Charlotte,

    Thanks for your kind advice. I intend to follow your recommendation for adhering to one class per control type. Just for internal study and comparison, I would also try to build a single omnibus class covering all control types. Any specific instance of this class will  function just as a single control type, depending upon the argument passed to it.

    Your views are requested on certain additional points mentioned below (Access 2000 / 2003 desktop on Win XP):

    1 - Hooking events:
    There should be no harm in hooking all events available in a control, by assigning "[Event Procedure]" wherever the value is found blank. As and when particular events are required to be sunk, pertinent stubs can be inserted in the class module, without having to worry about matched hooking.

    2 - Precautions for ensuring proper termination of all classes:
    2.1 - Parent-Child linkage:
    2.1.1 - As each control class has the form class as its parent, it is found that mere clearing of local object variable holding the parent property (setting it to nothing) in terminate event of control class, is by itself not adequate and does not ensure proper termination. 
    2.1.2 - It is observed that in the form class, if parent property of each instance of child control class is set to nothing, BEFORE setting the form object variable (pointer to real form) to nothing, it ensures proper termination.
    2.1.3 - In case of Access 2000, failure to comply with 2.1.2 above, can lead to application freeze or crash. (No such problem in Access 2003).

    2.2 - Forms with subforms:
    2.2.1 - In Access 2000, if the parent form as well as the form serving as its subform are both set to the form class (even though these are different instances of the same class), application freeze / crash can take place on eventual closing of parent form. (No such problem in Access 2003).
    2.2.2 - The above problem can be overcome by off-loading the SourceObject of subform controls, BEFORE setting the form object variable (pointer to real form) to nothing.

    2.3 - Role of form class object variable in real form's module:
    2.3.1 - In Access 2000, setting the form class variable to nothing, in close event of real form's module, while the form object variable is also set to nothing in close event of this variable in module of form class, can lead to application freeze / crash on eventual closing of form. Apparently, the phenomenon is related to circular reference that exists between the form and form class. (No such problem in Access 2003). 
    2.3.2 - On the other hand, if form class variable is set to nothing in close event of real form's module, while the form object variable is NOT set to nothing in close event of this variable in module of form class, proper termination of child control classes fails to take place.
    2.3.3 - In conclusion, it seems preferable not to set form class variable to nothing in real form's module.

    3 - Global Interface for use in conjunction with control classes:
    3.1 - Performance-wise, both the alternatives suggested in JC's post appear to be equally effective. In either case (whether a class or general module), the developer has to ensure that the interface is bundled along with the set of control classes.
    3.2 - Use of general module as global interface would minimize the extent of interference to existing code in client classes. The interface module could be named in such a manner as to reflect its association with the given set of classes. As an added reminder, name of this module could be mentioned as part of the comments at beginning of each control class.
    3.3 - Use of general module as global interface would also avoid the need for setting up parent/child linkage, leading to improved robustness. Tests show that if a class is used as global interface, additional precaution becomes necessary for proper termination (in the context of Access 2000). In form class module, setting the parent to nothing, for each instance of global interface class, BEFORE setting the parent to nothing for each instance of control class has to be done, which in turn has to be carried out BEFORE setting the form variable (pointer to real form) to nothing in its close event.

    Note - In order to verify inherent stability, the above tests have been conducted without resorting to deletion of individual objects in various collections. With the stated measures, simple setting of collection object to nothing in terminate event is found adequate. For regular use, step-wise deletion from collection, could be included as abundant precaution.

Best wishes,
A.D. Tejpal
------------

  ----- Original Message ----- 
  From: jwcolby 
  To: Access Developers discussion and problem solving 
  Sent: Wednesday, March 04, 2009 01:11
  Subject: Re: [AccessD] Building a control class


  A.D.

  If you are determined to move in this direction and you want to sink events, you would have to coerce the generic control object passed in to a specific control type using a case statement that determines the control type.  I believe you could also use a variant to pass in the actual control (textbox, combo etc) and not have to do a coercion.

  I truly do not recommend this approach however.  The number of control types is fixed, so a class for each type is usable.  Additionally it turns out that you are really mostly interested in an even smaller subset of all of the controls, for example you probably not build a class for the line control, the rectangle, the page break, unbound object, picture etc.  To this point I have mostly worked with bound controls, as well as the tab, page and command button.  Thus I only have 9 control classes.

  I guess it really depends on how deep you get into the controls in your forms.

  Additionally I use what I call (for lack of a better name) clsGlobalInterface.  It contains code that truly is common across the control classes.  As an example it is almost critical to empty collections before setting the pointer to the collection to nothing.  So I have a method of clsGlobalInterface that will iterate a collection and remove anything in it, calling the term event of whatever is in there just in case the object is a class.  This is a mEmptyClass method that could reside in each and every control class (or as a function out in a module) but since the code is identical, I simply place the code in clsGlobalInterface.

  I then dim an instance of clsGlobalInterface in the header of each control class.  I actually expose the clsGlobalInterface instance using a property sub in each control class, but mostly it is used by the class itself to get at such common code.

  It is also possible of course to place code out in a module of the library and call it from the 
  control classes, however we are supposed to try really hard to make classes self contained where possible.  Thus I prefer to place such code in clsGlobalInterface.

  Using this clsGlobalInterface I encapsulate truly global code while keeping my control class specific to each control.

  John W. Colby
  www.ColbyConsulting.com


More information about the AccessD mailing list