[AccessD] Building a control class

Charlotte Foust cfoust at infostatsystems.com
Thu Mar 12 17:10:03 CDT 2009


>IMO classes really need to *try* to be independent of each other.  
>Sometimes it is not possible, sometimes specific sets of classes form a
system and need each other to perform the whole task.   

I agree with the first statement, John.  But I can't think of a reason
it wouldn't be possible.  When two independent objects need to
coordinate, they do it through another class.  

Charlotte Foust

-----Original Message-----
From: accessd-bounces at databaseadvisors.com
[mailto:accessd-bounces at databaseadvisors.com] On Behalf Of John W Colby
Sent: Thursday, March 12, 2009 2:39 PM
To: Access Developers discussion and problem solving
Subject: Re: [AccessD] Building a control class

AD,

 >In your view, what could be the best strategy for projecting the
events pertaining to form object variable in form class, into the
control class ?

In general a control class should not be aware of the form and
particularly its events.  If the form needs to have a control do
something in response to one of the form's events, you should expose a
method in the control class to call from the form's event.  Let's take
an example:

I use a combo control to cause the form to select a record.  The form
and the combo should "stay in sync" or it is visually confusing.  IOW,
if the form moves to a specific record, the record selector combo should
"move to" and display that same record.  Obviously if the combo selects
a record, the form should move to that record.  The form and combo "stay
in sync".

I created a "mSyncToForm(lngPKID)" method in the combo class.  In the
form's Current event the clsCboRecSel.mSyncToForm is called passing in
the form's PKID.  The combo class then causes the combo control to
display the record with that value in column 0.  Thus the combo "syncs" 
to the form.

OTOH, if the user selects a record that they want to move to, the form
should move to that record.  clsCboRecSel defines an Event
evAfterUpdate(lngPKID as long).  The clsCboRecSel raises the
'evAfterUpdate event in the combo's AfterUpdate event stub in the class.
clsCboRecSel is declared Withevents back in the form.  An event stub is
created in clsFrm sinking evAfterUpdate.  When evAfterUpdate fires,
control passes back to the form's evAfterUpdate event stub and the form
has to grab a copy of the RecordsetClone, move to that record, grab the
bookmark, then set the form's bookmark to that bookmark, causing the
form to move to the right place.

Notice that the clsCboRecSel doesn't need to know anything about the
form in either case.  It can sync to the form simply by exposing a
method for the form to call, and the form can sync to the record
selector simply by sinking an event raised by the record selector class.

So the answer is to build functionality into the control class, and
expose that functionality via methods of the control class.  Raise
events in the control class as required to notify the form that the
control class did something that the form class might want to know
about.

Often times the control class behaviors simply don't matter to the form.
For example my combo control wrapper class can be programmed to open a
specific list form in the dbl-click event so that the list behind the
form can be programmed.  The form that carries the combo control doesn't
care about that, in fact that is a behavior that might be useful in any
combo in any form.  It is the combo control classes' business, not the
form class' business.

IMO classes really need to *try* to be independent of each other.  
Sometimes it is not possible, sometimes specific sets of classes form a
system and need each other to perform the whole task.  On the other hand
even when they might need to know about each other, you should try to
use an interface - an exposed method or raising an event - to allow the
partner object to get something done.  Programming an interface helps to
disentangle the objects themselves.

 >If a WithEvents variable of form type is declared in control class and
is set equal to the form variable belonging to form class, it hampers
proper closing.

Yes, it definitely can.  a circular reference is formed where the form
refers to the form class which refers to the control class and the
control class refers to the form.  The answer is being rigorous in your
cleanup.  Sometimes just setting the pointer to the control class to
nothing back in the form class is enough to cause the control class to
close properly.  The class terminate MUST set pointers to all objects to
nothing.  If the terminate event fires then the form pointer is cleaned
up as is the pointer to the wrapped control(s).  If this cleanup is not
performed then things start to break.  Occasionally I have had to expose
a mTerm() method that I explicitly called back in the parent class
before setting the pointer to the child class to nothing.  That mTerm
class performs all of the cleanup.  The Class_Terminate() event then
calls mTerm in cases where the pointer in the parent is just set to
nothing.

Cleanup is CRITICAL.  If you do cleanup correctly, then it is quite
possible to grab pointers to the form, and even sink form events.  
Sinking form events can be risky though in the earlier versions of
Access, and can cause page faults in weird situations.

 >On the other hand, if a custom event is raised in form object's event
(say current event) in form class, thereby enabling setting up of
WithEvents object of form class type (set equal to the form class) in
the control class, the said event does come up in the intellisense but
does not show any activity.

The event should fire in the control class, as long as the event
property is set to [Event Property].  I have done so before and it does
work.  It is not clear whether you intend for the clsFrm to raise an
event and be sunk in the control class, or for the form itself to have
an event sunk in the control class.  Either one *should* work.  I have
never tried to sink an event raised by my clsFrm inside of a control
class, nor have I even declared clsFrm Withevents in a control class.


I have to say I am heartened to have you asking so many questions about
classes and events.  From your general Access knowledge level I long ago
assumed that you were probably way above me in this stuff.  From the way
you study stuff I assume that you soon will be anyway.  ;)


John W. Colby
www.ColbyConsulting.com





More information about the AccessD mailing list