jwcolby
jwcolby at colbyconsulting.com
Wed Feb 11 11:02:48 CST 2009
This lecture will add another control class to our system to wrap the text box control and add some functionality to that control. I am going to cut and paste the entire lecture about the clsCtlCbo into this lecture, change the cbo with txt and go from there. There are two reasons I am doing this. The first is because I am smart (lazy) and the other is to demonstrate how “cookie cutter” classes are. This stuff is NOT rocket science. You need the same things in the header of each class so why not take advantage of that fact? WARNING, I am doing two additional things down in the bottom so please do read this lecture thoroughly to see the changes made. We are going to do some “useful work”, changing the backcolor of the control as it gets the focus, then change it back as it loses the focus. • From the database window, click Insert / Class. • Immediately save the new class as clsCtlTxt • Place the following code in the header of the class Private WithEvents mctlTxt As TextBox Private Const cstrEvProc As String = "[Event Procedure]" This should be starting to look familiar. The first line dimensions a variable for a text box control, and dimensions it WithEvents, which means that this class will sink events for the control passed in. cstrEvProc is already familiar and is the text which when placed in an event property “hooks” that event and causes the control to Raise that event. • In the left text box box select the class. The editor will insert an Initialize event stub. • In the right text box box, select the Terminate event. The editor will insert a Terminate event stub. • In the Terminate event stub insert the following code: Private Sub Class_Initialize() Set mctlTxt = Nothing End Sub • Again, this code should be looking familiar. We are telling the class that when it terminates, to clean up the pointer to the text box box. • Create a mInit() function as follows: Function mInit(lctlTxt As TextBox) Set mctlTxt = lctlTxt mctlTxt.BeforeUpdate = cstrEvProc mctlTxt.AfterUpdate = cstrEvProc mctlTxt.OnGotFocus = cstrEvProc mctlTxt.OnLostFocus = cstrEvProc End Function This mInit passes in a pointer to a control in lctlTxt. It then saves that pointer to mctlTxt. Finally it “hooks” four events of the text box, the BeforeUpdate, AfterUpdate, GotFocus and LostFocus. • In the left text box box in the editor, select mctlTxt. The editor will create the BeforeUpdate event stub. In the right text box select the AfterUpdate event and the editor will create an event stub for that event. Repeat for the GotFocus and LostFocus. • In this case we are going to lose the message boxes and modify the events to write to the debug window. We are also going to change the back color of the control as it gets focus and loses focus. • In order to do the back color we need to add a variable and a constant in the header. In the header of the class add the following code: Private mlngBackColor As Long Private Const clngBackColor As Long = vbCyan mlngBackColor will give us a place to store the original back color of the control when the GotFocus event fires. The constant clngBackColor is the color that we will set the control’s back color to • In these events place the following code: Private Sub mctlTxt_AfterUpdate() Debug.print "AfterUpdate: " & mctlTxt.Name End Sub Private Sub mctlTxt_BeforeUpdate(Cancel As Integer) Debug.print "BeforeUpdate: " & mctlTxt.Name End Sub Private Sub mctlTxt_GotFocus() Debug.Print "GotFocus: " & mctlTxt.Name 'Store the back color as we get the focus mlngBackColor = mctlTxt.BackColor 'Set the back color to an ugly light blue color mctlTxt.BackColor = clngBackColor End Sub Private Sub mctlTxt_LostFocus() Debug.Print "LostFocus: " & mctlTxt.Name 'Change the back color back to the original color mctlTxt.BackColor = mlngBackColor End Sub • Save and close clsCtlTxt. • Having done that we need to modify the CtlScanner in clsFrm to automatically load this new clsCtlTxt. Open clsFrm. Move down to the ctlScanner function and modify the Case acTextBox code as follows: Case acTextBox 'Find all text boxes and load class to change backcolor Dim lclsCtlTxt As clsCtlTxt Set lclsCtlTxt = New clsCtlTxt lclsCtlTxt.mInit ctl colCtls.Add lclsCtlTxt, ctl.Name Case acToggleButton • Compile and close clsFrm. • While we are at it let’s clean up the clsCtlCbo to lose the message boxes in the events. We will also add the same “back color change” logic to the combo classes. Open clsCtlCbo. Add the following code in the class header: Private mlngBackColor As Long Private Const clngBackColor As Long = vbCyan • Replace the event code with the following: Private Sub mctlCbo_GotFocus() Debug.Print "GotFocus: " & mctlCbo.Name mlngBackColor = mctlCbo.BackColor mctlCbo.BackColor = clngBackColor End Sub Private Sub mctlCbo_LostFocus() Debug.Print "LostFocus: " & mctlCbo.Name mctlCbo.BackColor = mlngBackColor End Sub • Open the main frmDemoCtls • Click into the text box and observe that it turns Cyan. • Click out of the text box and observe that it resumes its original color. • Click into each of the combo boxes (you should have three now). Observe that each one changes the back color as it gains the focus and changes the color back to the original as it loses the focus. This lecture has created a new clsCtlTxt. We are starting to see a pattern emerge, where we have a private variable in the top of the class dimmed WithEvents to hold a pointer to an object, in this case a text control. We have a Terminate event of the class that cleans up the pointer when the class closes. We have an mInit() event that passes in a pointer to the object, sets the local variable equal to the passed in pointer, and then “hooks” events of the object passed in by setting the properties to a specific string "[Event Procedure]" by using a constant declared in the class header. We then have event sink subs which will execute when the given event fires. We also added a little real functionality to change the back color as the controls got the focus and set it back to the original as the controls lost the focus. Congratulations on sticking with us. You are now beginning to see that just like the other objects you know and love, classes are easy to use and modify. Practice makes perfect and you have now created four different classes, clsFrm, clsCtlCbo, clsCtlTxt and clsTimer. Each has a header and an area to write code. Each has events that fire to initialize and cleanup code, and each has code that performs whatever behaviors you want done. Easy stuff. -- John W. Colby www.ColbyConsulting.com