|
Winning the Little
Battles
NOTE: I found some software that makes development a lot faster and improves windows in general:
As you start a project such as this there must be a glimmer of an idea
somewhere in your consciousness. From there on it is all problem solving.
In this instance, the only idea I had was that I wanted to show a number
of colored bars being sorted. I had no idea what the shape control was, no
idea about partitioning, stepping, or speed variation; and I only knew
about four sorting methods.
Problems by the numbers for me were:
1. How do you make bars?
Answer: Discover the Shape control!
Of particular interest to me was the fillcolor property of the shape
control. Displaying the RED, ORANGE, GREEN, and BLUE while sorting is
really the most striking visual effect of the viewer. After discovering
the shape control, considerable time was spent developing the Form_Load
sub with attention paid to generating the interface using constants (like
UNIT) to allow for easy editing later if the interface didn't have the
look and feel I desired. Also if the project was to be of general
interest, it was necessary for subsequent users to be able to create the
interface in a very simple way (i.e. without having to accurately place
and size the controls). After programmatically loading all 16 bars on the
form, I knew I was on my way - I knew I could do something like my vision.
Next I started writing the first sort sub - bubble_sort, of course.
While I was doing this I was careful to try to make some general
subroutines like compar, swap, and pause that would be used by all my
future sorting methods. As it turned out the simple pause sub became the
heart of the program.
2. How to pause and stop execution
Answer: A simple loop of DoEvents!
Private Sub pause()
Dim i As Long
For i = 1 To Spd
If stepping Or Not sorting Then Exit For
DoEvents
Next
End Sub
|
I needed a way to pause the execution of the sorts long enough for the
viewer to see the bars being swapped, and I needed to give the user the
opportunity to stop the process by clicking a stop button. The Spd (speed)
variable eventually would allow the user to vary the pause, and the
DoEvents call within the procedure allows the click of another button to
be recognized.
Stopping a method was accomplished by setting a Boolean named sorting to
true before calling the sorting procedure. Then with strategically placed
Exit Sub commands in the sort procedures, I could effectively stop the
sorts whenever sorting is false. The pause command came to the rescue
again by allowing me to click the stop button which had as its principle
statement sorting = False.
In line with making this project a learning tool, one feature I thought
would be interesting would be to stop and switch methods right in the
middle of a sort. This naturally progressed to just clicking on another
sort button without clicking stop. Since all the command buttons are
members of the same array, clicking one is like clicking another with the
only difference being the Index integer that is the parameter in the
Command_Click event sub. This is fine for centralized processing but has
one drawback. The first sort will exit out this very sub after the new
sort you pick is finished executing. A very messy thread.
3. How to switch sorting methods?
Answer: Use a temp variable for Index
Let me explain further. When a sort method is clicked, the event is
passed to the Command1_Click sub and is then directed to the proper sort
procedure with the Select Case block. After that sort is done, the code
thread returns to the spot in the Select Case block and continues on down
to exit out of Command1_Click (returning control to windows).
If sorting Then
sorting = False
idx = Index + 1
Exit Sub
End If
cm1: sorting = True
Select Case Index
Case 5: bubble_sort 0, BARSM1
Case 6: bibub_sort 0, BARSM1
Case 7: count_sort 0, BARSM1
End Select
If idx Then
Index = idx - 1: idx = 0
GoTo cm1
End If
|
I needed a way to completely exit one sort method before starting
another through this same event sub, or risk unexpected results. To
accomplish a sort switch in the Command1_Click sub, I set the boolean
sorting to False to get the first sort routine to stop. But before doing
this I had to enble the thread of that code as it exited Command_Click to
redirect itself to the new sort method. I did this by setting another temp
variable equal to the Index of the sort method that I was going to run and
then just Exit Sub!
What would happen then is that the first sort would end, and while its
thread was exiting Command1_Click, it would encounter the temp Index that
would redirect execution back through the Select Case block to do the new
sort. If you examine the above code, you will find the name of my temp
index is idx.
4. How to accomplish sorting in either direction?
Answer: Use a global variable indicating direction.
In order to be a versatile sort method, I felt it should be able to
arrange the elements in descending as well as ascending order. Granted
each sort method must be programmed to know what to do, but there must be
a flag telling these routines which direction to go.
In many generic sort routines you will find this information passed to
the sort routine as a boolean parameter to the subroutine. This would be
in keeping with the encapsulation virtue of OOP. I decided to implement a
global integer variable ascend since I prefer to limit the number of
parameters that have to be piled onto the stack of recursively called
routines.
Note that ascend can be either 1 or -1. This makes it directly useful
in the math statements of the sort routines which is something a boolean
could not do.
5. How to single step through the sorting?
Answer: Develop a wait subroutine.
Private Sub wait()
stepit = False
Do Until stepit
DoEvents
Loop
End Sub
|
Note that stepit is a global boolean. The wait sub calls are
judiciously set in routines common to all the sort routines. When the step
button is clicked (or when a key is pressed) all that needs to be done is
to set stepit = true and the loop will be exited, moving the execution on
to the next wait call.
5. How to vary the speed of the sorting?
Answer: Use a scrollbar control.
Private Sub HScroll1_Change()
If Not stepping Then Spd = IHI - HScroll1.Value
End Sub
|
Note that IHI is a constant for the intrinsic integer high of 32767 which
conveniently happens to be the maximum value a scrollbar will accept. IHI
- HScroll1.Value simply inverts the value that the scrollbar has been set
to since I need a lower number for Spd when I want to go faster. (Fewer
loops means faster execution.) Refer to the code for pause above to see
how the change in the Spd variable varies the visual speed of the sorting.
<<Previous | Next >>
|