创建健壮的控件

对用户来说,关于 ActiveX 控件最重要的三件事是健壮、健壮、再健壮。因为控件部件在使用它的应用程序的进程空间中运行,控件中的致命错误也将是应用程序的致命错误。

下面列出的“需要做”和“不要做”决不是包罗万象的。它们仅仅提供了制作健壮控件的基本要求。

错误处理

需要做 不要做
在放入代码的每个事件过程中提供完全的错误处理,不管该事件是属于 UserControl 还是某个子控件。 在任何事件过程中产生错误。
特别地,在 UserControl 的 Paint、Resize 和 Terminate 事件中提供完全的错误处理。  

事件过程中未被处理的错误对于控件部件和使用它的应用程序将是致命的,因为调用栈上永远不会有处理这些错误的过程。

在属性过程和方法中产生错误是相当安全的,因为属性和方法一般是由其它过程调用的,产生的错误会由那些过程中的用户处理。

对象模型

如果控件部件中含有了独立的对象,例如 Toolbar 控件的 ToolbarButton 对象集合:

需要做 不要做
为这种对象的集合创建包装类, 请参阅“部件设计的一般准则”和“ActiveX 部件的标准及指南”。 使用 Collection 对象,但没有包装类。Collection 对象可以接受任何 variant 类型的值,因此用户可能会错误地输入能引起控件代码错误的对象。
为集合属性使用属性过程。 以简单数据成员的形式来实现这样的属性。

例如,如果创建 ToolbarButtons 类作为 ToolbarButton 对象集合的包装类,则将此属性以只读属性过程的形式添加 UserControl 对象:

Private mToolbarButtons As ToolbarButtons

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

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

与此相反,以下实现的方法允许错误地把 ToolbarButtons 设置为 Nothing,这将毁坏了集合:

Public ToolbarButtons As New ToolbarButtons

属性的实现

必须用属性过程实现属性,而不是公有数据成员。

可以使用 Property Let 来验证属性值。如果使用公有数据成员,那么将不得不在每次使用数据时都对它进行检查;而且,如果在某个事件过程中发生了验证失效,则不可能发出错误,除非关闭使用控件部件的应用程序。

另外,属性在“属性”窗口和“属性页”对话框中不会正确地工作,请参阅本章前面的“在控件中添加属性”。