Creating Robust Controls

See Also

For your user, the three most important things about an ActiveX control are robustness, robustness, and robustness. Because a control component runs in the process space of an application that uses it, fatal errors in your controls are also fatal errors for the application.

The following lists of DOs and DON'Ts are by no means inclusive. They only provide a starting point for producing robust controls.

Error Handling

DO DON'T
Provide thorough error handling in every event procedure you put code in, whether the event belongs to the UserControl or to a constituent control. Raise errors in any event procedures.
In particular, provide thorough error handling in the UserControl's Paint, Resize, and Terminate events.

Unhandled errors in event procedures will be fatal to your control component, and the application using it, because there will never be a procedure on the call stack that can handle the errors.

It's perfectly safe to raise errors in property procedures and methods, because properties and methods are always invoked by other procedures, and errors you raise can be handled by the user in those procedures.

Object Models

If your control component includes dependent objects, such as a collection of ToolbarButton objects for a Toolbar control:

DO DON'T
Create wrapper classes for collections of such objects, as described in "General Principles of Component Design" and "Standards and Guidelines." Use the Collection object without a wrapper class. The Collection object accepts any variant, meaning your users could accidentally insert objects that might cause errors in your control's code.
Use property procedures for collection properties. Implement such properties as simple data members.

For example, if you create a ToolbarButtons class as the wrapper class for a collection of ToolbarButton objects, add the property to your UserControl object as a read-only property procedure:

Private mToolbarButtons As ToolbarButtons

Property Get ToolbarButtons() As ToolbarButtons
   Set ToolbarButtons = mToolbarButtons
End Property

Private Sub UserControl_Initialize()
   Set mToolbarButtons = New ToolbarButtons
End Sub

By contrast, the following implementation allows your user to accidentally set ToolbarButtons to Nothing, destroying the collection:

Public ToolbarButtons As New ToolbarButtons

Implementing Properties

DO implement properties using property procedures, instead of public data members.

You can use Property Let to validate property values. If you use public data members, you'll have to check the data every time you use it; and if that happens in an event procedure, you won't be able to raise an error without bringing down the application that's using your control component.

In addition, your properties will not work correctly in the Properties window and Property Pages dialog box, as discussed in "Adding Properties to Your Control," earlier in this chapter.