jwcolby
jwcolby at colbyconsulting.com
Sun Feb 15 21:03:30 CST 2009
> Should the name be clsDemoMsg (as the first 3 line of code are, or clsMsgDemo as the earlier lesson had us save it? Well... The name of the class is clsDemoMsg, at least in my demo database, and also where it is referenced in basDemoMsgTest. Looking back at the lecture where we create the class however, I do say to "immediately save as clsMsgDemo". My apologies. Part of what goes on is that occasionally I have to write more than one lecture at a time because I am breaking the lectures down into such small pieces. I can't know whether the class actually runs correctly unless I then write the code that excercises the class, and in order to do that I also have to write the initialization module. In the process I saved the class as one thing (in my demo database) and wrote another when I told you to save it in the lecture. 8-( To fix it we have a couple of choices. One would be to simply change the lecture to save it to clsDemoMsg. The other would be to change everywhere where I use it to say clsMsgDemo. Since changing the name of the class "fixes" the later lessons to work correctly, that seems the simplest thing to do. So... in the database window, rename clsMsgDemo to clsDemoMsg. I will fix my lecture where we create that class to say "immediately save as clsDemoMsg". Again my apologies, John W. Colby www.ColbyConsulting.com MACE, Terry wrote: > JC, > > Should the name be clsDemoMsg (as the first 3 line of code are, or > clsMsgDemo as the earlier lesson had us save it? > > Regards > > Terry Mace > Logistics Support Officer & Maintenance Supervisor > > -----Original Message----- > From: accessd-bounces at databaseadvisors.com > [mailto:accessd-bounces at databaseadvisors.com] On Behalf Of jwcolby > Sent: Saturday, 14 February 2009 2:57 AM > To: Access Developers discussion and problem solving > Subject: [AccessD] USING CLSMSGDEMO > > 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. > >