Pass It On


Most of the XEditor properties and methods are simply the methods and properties of the internal txt control. It’s a simple (but tedious) matter to initialize and write all these properties. Let’s look at a simple one:

Property Get BackColor() As OLE_COLOR
BackColor = txt.BackColor
End Property

Property Let BackColor(ByVal clrBackColor As OLE_COLOR)
txt.BackColor = clrBackColor
PropertyChanged "BackColor"
End Property

This in itself isn’t enough to make the BackColor property work properly. You have to save the property value in the UserControl_WriteProperties event so that it will be saved as part of its containing form:

PropBag.WriteProperty "BackColor", .BackColor, vbWindowBackground

You also have to read the property from its saved state on the form in the UserControl_ReadProperties event:

.BackColor = PropBag.ReadProperty("BackColor", vbWindowBackground)

That’s easy. Now you just have to pass through all the other standard properties and methods of the RichTextBox control. This isn’t my idea of fun, but fortunately you have a wizard to handle the details. The sidebar “Wizard or Secretary?” on the following page details my philosophy and practice with regard to ­wizards.


Wizard or Secretary?


Wizard. The name raises certain expectations. In fact, you’ll find that most wizards work more like secretaries. They’ll do your repetitive typing for you, but only if you give them very explicit instructions. If you give them bad instructions, they can type a lot of bad code fast and it will take you many hours to undo the damage. Programmers who have used the Wizards in Visual C++ or the Experts in Borland C++ know what I’m talking about. Visual Basic programmers didn’t have to worry about wizards in previous versions because the language made it easy to design forms and dialog boxes that would have been created by wizards in less friendly languages. But Visual Basic version 5 has lots of wizards for creating all sorts of things—including controls.


I don’t want to say that wizards are a bad idea. I’m in the wizard business myself (see Bug Wizard, Global Wizard, and Collection Wizard) and I’m sympathetic to many of the problems that wizard designers encounter. But I prefer language features to wizards. My wizards, for example, work around problems that the language ought to handle, such as assertions, global classes, and collections. I’d like to see a language statement that could simply reuse an existing control.
(I don’t care if it works through inheritance or delegation.) You would write only the code to modify or extend the internal control—no wizard needed. I haven’t seen a language that can do this. Perhaps I’m asking too much.


In the meantime, there’s the ActiveX Control Interface Wizard. All I can say about this wizard is that I don’t trust it (or any other wizard, including the ones I write). It can help you create bad controls very quickly and very easily. It can help you create good controls less quickly and less easily.


In my experience, the most important part of using a wizard is to get all your members in a row before you start. If you don’t know exactly what properties and methods you’re going to delegate, you’ll probably find the wizard’s suggestions incomplete. The Object Browser is a useful way to get the complete list of members that you might want to delegate from the internal control as well as from UserControl.


The second thing about wizards is that you should always check their work. Very few wizards are polite enough to let you choose the coding conventions. That’s because it takes twice as much work to write configurable wizards. It’s much easier to force users to accept your preferences. I plead guilty here for my own wizards, but at least you get the source code to mine. It’s also not unknown for wizards to generate code that is inefficient or just plain wrong. If you’re as picky about your code as I am about mine, you’ll want to have the last word. I had the last word on my control code, and in most cases, you can’t tell whether I used a wizard or not.


Passing properties through appears to be simple, but there are as many exceptions as there are rules. Here are a few of the special cases:
Delegating properties can get messy, but methods are easy. Most are one-liners:

Public Sub Refresh()
txt.Refresh
End Sub

Passing properties through is an annoyance to get past. The interesting part is enhancing and extending properties.