Code changes |
This third version attempts to
fix one problem in the second version. When you click on a button to start the loop
running, you now get separate text boxes to display the results. This makes it easier
to separate out the timing results for each variable type.
The program allows you to have up to seven columns shown on the form. This
avoids the problem with information being printed directly on the form, where your
vertical space to display the information is limited.
|
Tracking multiple Click events |
For how many Click events do we want to show
separate results? I arbitrarily chose seven, since they barely fit on the form in 800 by
600 resolution. I declared a constant at the top of the form for this limit, which is
named fiMAX_COLS. In each Click Event routine, I declared a static variable siNdex to
keep track of how many times that button has been clicked. Since static variables retain
their value for the life of the program, they can be used to identify how many times the
Click event has occurred:
'Identify maximum number of columns we can show
Const fiMAX_COLS As Integer = 7
Private Sub cmdLong_Click()
Static siNdex As Integer
Dim liNdex As Integer
Dim llCounter1 As Long
Dim llCounter2 As Long
Dim llAccum As Long
Dim ldtStart As Date
Dim ldtStop As Date
Dim lsMsg As String
'Don't allow too many of these to run!
If siNdex > fiMAX_COLS - 1 Then Exit Sub
'Identify current loop number
liNdex = siNdex
siNdex = siNdex + 1
All the variables declared inside the cmdLong_Click event above (except for siNdex)
will be re-initialized to zero each time the Click event is called. The reason is that the
variables other than siNdex have local scope, and they are allocated dynamically on the
stack each time the Click event occurs.
At the beginning of each Click event, the local variables are initialized to have
values of zero. At the end of each Click event, the local variables vanish as their memory
space is de-allocated.
|
Displaying the timing results |
One approach to showing the information for
multiple click events is to create a large number of text boxes laid out on the form in
rows and columns. I have done this before, and I don't like the appearance much. I set
up the program to do something slicker, which is to create the necessary text boxes at run
time. When necessary, the form is resized to accommodate the next column of text boxes
that are created.
|
Creating controls in Visual Basic 5 |
Visual Basic 6 has some new ways to create
controls at run time. Since some people may still be working with Visual Basic 5, I'll use
the "old fashioned" method. This requires that you have a control array defined
at design time. For those controls that you want to create at run time, you use the Load
function, which adds another element to the control array. If you look in the properties
window for the form object frmIntSpeed3, you'll see that each of the text boxes is defined
as a control array. The item which makes them control arrays is having the Index property
set to any value.
If the Index property is set to nothing, then you have a single control which is not an
element in a control array. If the Index property is set to zero, then you have a control
array with a single element whose index is zero.
|
Creating controls
at run time |
The program assigns the value of the static
variable siNdex to a local variable liNdex. This local variable liNdex will be used as the
subscript for the new control array elements that we create. The Load function creates the
new element in the control array. We then set the Left property to make it appear in the
next column to the right of the prior text box. The final test in this If/Endif block is
whether the new column of Text boxes extends beyond the right edge of the form.If so, we
need to increase the Width property of the form. I used Me.Width, which refers to the
current instance of the Form. This is the preferred method, instead of using
frmIntSpeed3.Width.
'Identify current loop number
liNdex = siNdex
siNdex = siNdex + 1
'Need to load new set of controls?
If liNdex > 0 Then
Load txtLngStart(liNdex)
txtLngStart(liNdex).Left = 1560 * liNdex _
+
txtLngStart(liNdex).Left
Load txtLngStop(liNdex)
txtLngStop(liNdex).Left = 1560 * liNdex _
+
txtLngStop(liNdex).Left
Load txtLngElapse(liNdex)
txtLngElapse(liNdex).Left = 1560 * liNdex _
+
txtLngElapse(liNdex).Left
'May need to widen the form
If Me.Width < txtLngStart(liNdex).Left + 1560 Then
Me.Width = Me.Width +
1560
End If
End If
|
Displaying controls
at run time |
One last detail is to show the controls that we
just created. By default, they are not visible. This allows us to position them using the
prior code first. Now we set the Visible property to true, and they will appear on the
form: ldtStart = Time
txtLngStart(liNdex).Text = ldtStart
txtLngStart(liNdex).Visible = True
txtLngElapse(liNdex).Visible = True
|
Accuracy problem |
Now that you can see all the timing results
clearly for the different variable types, you may notice something. The results are NOT
very accurate. This is caused by use of the Time function, which is only accurate to the
nearest second. Version 4 of the program shows more accurate
timings via use of the Windows API function timeGetSystemTime.
|