[AccessD] USING CLSMSGDEMO

jwcolby jwcolby at colbyconsulting.com
Fri Feb 13 09:57:02 CST 2009


Unlike all of the previous lectures, THIS ONE is heavy duty.  the reason is simply that you will be 
stepping through the code line by line to watch and understand the program flow.  you MUST do this 
if you ever hope to truly understand classes, methods, Raising an event, sinking an event and how it 
all interacts.  Do NOT skip over stepping through the code or all that you have learned will be so 
much less helpful.  Understanding in your head how it all plays together will be very useful, and 
perhaps critical to becoming a first class user of classes.  I am sure that there will be plenty of 
questions when we are done so go to it.

In the previous lecture we created a class that will sink and source events from clsMsg.  This 
lecture will show you how to set up, cleanup and use freestanding classes (which includes clsMsg by 
the way).

•	In the database window, click Insert / Module.  This will be a plain module, not a class.
•	In the module header insert the following code:

Private mclsDemoMsgSteve As clsDemoMsg
Private mclsDemoMsgGeorge As clsDemoMsg
Private mclsDemoMsgLinda As clsDemoMsg

This code simply dimensions three variables to hold instances of clsDemoMsg.  Notice we dimension 
them private.  In general it is good practice to make variables private unless there is a good 
reason to make them public, and then expose those variables through functions if they need to be 
used outside of the current module.

•	In the module body, type in the following code:

Function mDemoMsgInit()
     If mclsDemoMsgSteve Is Nothing Then
         Set mclsDemoMsgSteve = New clsDemoMsg
         mclsDemoMsgSteve.pName = "Steve"

         Set mclsDemoMsgGeorge = New clsDemoMsg
         mclsDemoMsgGeorge.pName = "George"

         Set mclsDemoMsgLinda = New clsDemoMsg
         mclsDemoMsgLinda.pName = "Linda"
     End If
End Function

This code SETs the class instances to a new instance of clsDemoMsg and immediately sets the 
instances pName property.  It does so three times, once for each instance of the class that we will 
be playing with.

Function mDemoMmsgTerm()
     Set mclsDemoMsgSteve = Nothing
     Set mclsDemoMsgGeorge = Nothing
     Set mclsDemoMsgLinda = Nothing
End Function

This function allows us to clean up the class instances when we are done playing.

Function cDemoMsgSteve() As clsDemoMsg
     mDemoMsgInit
     Set cDemoMsgSteve = mclsDemoMsgSteve
End Function

Function cDemoMsgGeorge() As clsDemoMsg
     mDemoMsgInit
     Set cDemoMsgGeorge = mclsDemoMsgGeorge
End Function

Function cDemoMsgLinda() As clsDemoMsg
     mDemoMsgInit
     Set cDemoMsgLinda = mclsDemoMsgLinda
End Function

These three functions get pointers to the three instances of clsDemo dimensioned in the header of 
the module.  It first makes sure that the class instances are initialized by calling mDemoMsgInit.

That is all that is required to dimension, initialize, terminate and use instances of ANY class. 
You can have a single instance of the class, or many instances – in this case three.  By the way, we 
could have stored the instances in a collection and created as many as we wanted but that would have 
made the code less readable for this demo.

•	Now… I want you to step through the code to see exactly what is going on so please set a 
breakpoint on the mDemoMsgInit line of EACH function cDemoMsg() function.
•	In the debug window type in the following code and hit enter:

cDemoMsgSteve.mSendMsg "George", "Tuesday's meeting", "Tuesday morning the entire teem will meet in 
the conference room at 09:00 am"

When you hit enter you should stop at the mDemoMsgInit() line in cDemoMsgSteve().  Start to step 
through the code.

The first thing that will happen is to run mDemoMmsgInit().  The first time through the code the 
private variables at the top of the module will be Nothing and you will fall into the code that 
initializes each class instance.  Continue to step into the code.

You should step into the Class_Initialize for each clsDemoMsg instance, and of course that code 
initializes the message class itself for THIS instance of clsDemoMsg.  Once you step out of that 
_Initialize code you should be back in mDemoMsgInit().

The next thing that happens is that you step into the pName property and store a name string into 
the mstrName variable in the top of the class header.  When you step out of pName you will be back 
in mDemoMsgInit.  You will then do the next instance and the next.

After initializing every private variable in the top of the module, control should return to 
cDemoMsgSteve and you will get an instance of the class itself, properly initialized.

Now that you have an instance of the clsMsgDemo, you will step into the .mSendMsg method of the 
class.  You have passed in some information to this method and basically you will just send a 
message using the mclsMsg.  NOTICE that when you execute mClsMsg.Send, control passes into clsMsg 
send method.

This is where the event is generated (raised) that all the class instances are sinking.  Once the 
event is raised, control will pass to EVERY event sink for that event.  We have THREE instances of 
clsDemoMsg, and each one of them sinks this event so every one of these instances will get control, 
in the order that they were dimensioned.

Go ahead and step into the mclsMsg.Send and step into the RaiseEvent.  Control is transferred to 
some event sink somewhere.  You should now be in mclsMsg_Message, about to check “If varTo = 
mstrName Then”.

The first thing I want you to do is to use intellisense to hover over VarTo and mstrName.  VarTo 
(George) is of course the intended recipient of this message, and mstrNname (Steve) is the name of 
the class instance that currently has control.

Step the code.  Since they do not match you do not fall into the code to display the message but 
rather just fall down to where you will exit.  Step out of this function.

Notice that code control immediately transfers to the next event sink.  Again step down to the If 
statement, and hover your mouse cursor over VarTo (George) and mstrName (George).  Since George is 
the class instance that this message is directed to, control will fall into the If Then statement 
and we will build the message and display it.

Figure out and understand the code that generates the message.  Continue stepping until the message 
box pops up and read it.

Continue stepping until you exit this function and notice that you are right back in the event sink 
for the last class instance.  Step on through (no message will be built) until you exit the function.

Notice that you are back in the clsMsg.Send method and about to exit that method.  Step out of that 
method.

Notice that you are back in the mSendMsg() method of clsDemoMsg and about to exit.  Step out of that 
method.

Notice that you are back in the debug window.

WOAAAAAH.  What a rush eh?  You have just watched an event be raised, and sunk in three different 
places.  The original message was created by cDemoMsgSteve.mSendMsg (Steve), and the message caused 
clsMmsg to RAISE an event.  That message was sunk by ALL THREE instances of clsDemoMsg, first Steve, 
then George, then Linda.

The ORDER that these instances got control was caused by the ORDER that you instantiated them in 
mDemoMsgInit().  Had you instantiated them in some other order then they would receive control in 
that some other order.

George was the intended recipient so only George processed the message in the event sink.

Now I want you to do this again, stepping through the code.  Notice that I am using a different 
instance of the class (George) to send the message, and a different recipient (Linda).

This time use the following code in the debug window:

cDemoMsgGeorge.mSendMsg "Linda", "Lunch Today", "After the meeting we will all be meeting for lunch 
at the deli one building over."

Notice first that the mDemoMsgInit does not perform the initialization because the classes were 
already initialized, so it just steps back out.

Finally I want you to use the following code to send a message that no one picks up and displays:

cDemoMsgGeorge.mSendMsg "John", "Lunch Today", "After the meeting we will all be meeting for lunch 
at the deli one building over."

The reason no one picks up the message is that there is no class instance with the name of John in 
mstrName, and so none of the instances process the message.

This is about as heavy duty as you will ever get.  You would be wise to step through this code as 
many times as you need to fully understand what is going on at each step.  How control passes to a 
method of a class and parameters are passed in.  How an event is raised, and IMMEDIATELY control 
starts to pass to the event sinks.  What order the event sinks process and why they process in that 
order.

If you understand this lesson, you will have class events down pat.  I KNOW it will be confusing, 
but just do it over and over until it sinks in.  Then raise an event to pat yourself on the back.

This lecture has been the most complex so far in terms of your being able to trace code execution. 
We have learned how to use a function that initializes our class instances and return an instance of 
a class.  We then step into a method of that class.  We watched the method call out to another class 
(clsMsg).  We watched clsMsg RAISE an event.  We watched the code control transfer to each of the 
three event sinks, and we watched the code be processed differently in each event sink because of 
logic inside of the event sink.  We then watched the code unwind back to the calling code and 
finally back out to the debug window.

Congratulations, you are now Class / Event gurus.  A diploma will be awarded.


-- 
John W. Colby
www.ColbyConsulting.com



More information about the AccessD mailing list