XDropStack Calling
Now let’s take a closer look at the XEditor search properties and methods used by the XDropStack control. The FindWhat property and its cousin ReplaceWith are the keys.
The FindWhat property represents the top of the stack (or front of the list) and is normally used without an index. You read from it to find the current find string:
sFind = edit.FindWhat
You write to it to add an item to the list:
edit.FindWhat = sFind
But it is also possible to index the FindWhat property to read all the items out of the list. Let’s look at the FindWhat property and its relatives to see how this works:
Property Get FindWhat(Optional iIndex As Long = 1) As String
With nFindWhat
If .Count = 0 Or iIndex > .Count Then Exit Property
FindWhat = .Item(iIndex)
End With
End Property
Property Let FindWhat(Optional iIndex As Long = 1, sWhatA As String)
With nFindWhat
' Don't use optional parameter on Let
BugAssert iIndex = 1
Dim v As Variant, i As Long
For i = 1 To .Count
' If item is in list, move to start of list
If .Item(i) = sWhatA Then
.Add sWhatA, , 1
.Remove i + 1
NotifySearchChange eseFindWhat
Exit Property
End If
Next
' If item isn't in list, add it
If .Count Then
.Add sWhatA, , 1
Else
.Add sWhatA
End If
NotifySearchChange eseFindWhat
End With
End Property
Property Get FindWhatCount() As Long
FindWhatCount = nFindWhat.Count
End Property
Property Get FindWhatMax() As Long
FindWhatMax = cFindWhatMax
End Property
Property Let FindWhatMax(cFindWhatMaxA As Long)
cFindWhatMax = cFindWhatMaxA
Dim v As Variant, i As Integer
For i = nFindWhat.Count To cFindWhatMax + 1 Step -1
' If item is in list beyond maximum, remove it
nFindWhat.Remove i
Next
NotifySearchChange eseFindWhat
End Property
The most important point about the FindWhat property is that it hides an internal Collection of strings. The default argument makes FindWhat look like a simple string property, and some simple clients might prefer to use the current string as if there were no others. But clients (such as the FSearch form) who wish to initialize a list can do so. What they can’t do is modify any item other than the top item because that would contradict the definition of a drop stack. The definitions of Property Get, Set, and Let procedures with the same name must all match—if one has an optional parameter, all must have the same optional parameter. You can’t prevent clients from writing code that uses the index, but you can assert that what they are doing is illegal, and if they do it anyway, ignore their foolish request.
The Property Let is what really makes the list work. It adds each new string to the list and ensures that the list isn’t too long and that the list doesn’t have duplicates. Finally, it calls NotifySearchChange, which raises a SearchChange event so that if the FSearch form modifies the search list through its drop stack, any other client using the list can recognize the change and update its list. The remaining search option properties also call NotifySearchChange in case a client represents them in some other way. Edwina monitors only FindWhat property changes, but your clients might want to monitor other options such as case sensitivity or direction. The FSearch form also monitors the SearchChange event so that any changes from the client made while the modal search form is active will be recognized as they happen.
The XDropStack implementation looks a lot like the implementation of the FindWhat list. Of course, combo boxes work a little differently than collections, so there are some differences in design. Figure 9-6 shows a picture of how
the data is organized in both formats. You can check out the code details in DROPSTACK.CTL.
Figure 9-6. A find list in XEditor and XDropStack.
CHALLENGE Your next assignment is to save the Find and Replace lists with the SaveSetting function when Edwina terminates and to restore them with GetSetting at startup. You might notice that the XEditor control doesn’t allow you to enter items in the FindWhat list at design time. It would certainly be possible to do this in much
the same way that you can enter list or combo box items in the List property at design time, but this isn’t the way search lists are normally maintained. My copy of Edwina has a different search list than your copy. While it’s saving the search list, Edwina should probably save the user’s favorite font and colors. And, of course, any respectable editor should provide a list of the most recently edited files and reopen the last one with the cursor position restored.