通过菜单-》项目-》添加引用,引用一个COM组件,
当这个COM组件产生了自定义事件时,应当如何响应?

解决方案 »

  1.   

    private withevents obj as youcom
    Private 语句      在模块级别中使用,用于声明私有变量及分配存储空间。语法Private [WithEvents] varname[([subscripts])] [As [New] type] [,[WithEvents] varname[([subscripts])] [As [New] type]] . . .Private 语句的语法包含下面部分:部分 描述 
    WithEvents 可选的。关键字,说明 varname 是用来响应由 ActiveX 对象所触发的事件的对象变量。只有在类模块中才是合法的。使用 WithEvents,可以定义任意个所需的单变量,但不能用 WithEvents 创建数组。New 和 WithEvents 不能一起使用。 
    varname 必需的。变量的名称;遵循标准的变量命名约定。 
    subscripts 可选的。数组变量的维数;最多可以定义 60 维的多维数组。subscripts 参数的使用语法如下: 
      [lower To] upper [,[lower To] upper] . . . 
      如果不显式指定 lower,则数组的下界由 Option Base 语句控制。如果没有 Option Base 语句则下界为 0。 
    New 可选的。使其可以隐式地创建对象的关键字。如果使用 New 声明对象变量,则在第一次引用该变量时创建该对象的新实例,因此不必使用 Set 语句来对该对象引用赋值。New 关键字不能声明任何内部数据类型的变量以及从属对象的实例,也不能与 WithEvents 一起使用。 
    type 可选的。变量的数据类型;可以是 Byte、Boolean、Integer、Long、Currency、Single、Double、Decimal(目前尚不支持)、Date、String(对可变长的字符串)、String * length(对定长的字符串)、Object、Variant、用户定义类型或对象类型。所声明的每个变量都要一个单独的 As type 子句。 
    说明Private 变量只能在包含其声明的模块中使用。可以使用 Private 语句声明变量的数据类型。例如,下面的语句声明了一个 Integer 类型的变量。Private NumberOfEmployees As Integer也可以使用 Private 语句来声明变量的对象类型。下面的语句为工作表的新实例声明了一个变量。Private X As New Worksheet如果在定义对象变量时没有使用 New 关键字,则在使用该变量之前,必须使用 Set 语句将一个已有的对象赋给该引用对象的变量。在赋值之前,所声明的这个对象变量有一个特定值 Nothing,这个值表示该变量没有指向任何对象的实例。如果不指定数据类型或对象类型,且在模块中没有使用 Deftype 语句,则按缺省情况该变量为 Variant 类型。可以用带空圆括号的 Private 语句来声明动态数组,然后可以在过程内用 ReDim 语句来定义该数组的维数和元素。如果试图在 Private,Public 或 Dim 语句中重新定义一个已显式定义了大小的数组的维数,就会发生错误。当初始化变量时,数值变量被初始化为 0,变长的字符串被初始化为一个零长度的字符串 (""),而定长的字符串则用 0 填充。Variant 变量被初始化为 Empty。用户自定义类型的变量的每个元素作为各自独立的变量进行初始化。注意 当在过程中使用 Private 语句时,通常将 Private 语句放在过程的开始。
      

  2.   

    处理对象的事件 
    引发事件的对象叫做事件源。为了处理事件源所引发的事件,可以用 WithEvents 关键字声明对象类的变量。本主题继续讨论上面的“声明和引发事件”中开始的 Widget 对象示例。为了处理 Widget 的 PercentDone 事件,将下面的代码放置到 Form1 的声明部分:Option Explicit
    Private WithEvents mWidget As Widget
    Private mblnCancel As BooleanWithEvents 关键字指定:变量 mWidget 将用于处理对象的事件。可以通过提供类名来指定对象类型,该类是创建这个对象的类。变量 mWidget 是在“Form1”的声明部分所声明的,因为 WithEvents 变量必须是模块级的变量。这是正确的,而不管将它们放置其中的模块类型如何。变量 mblnCancel 将用于取消 LongTask 方法。对 WithEvents 变量的一些限制
    使用 WithEvents 变量时,应该注意下面这些限制条件: WithEvents 变量不能是派生对象变量。也就是说,不能把它声明为 As Object—当声明该变量时必须指定类名。
    不能把 WithEvents 变量声明为 As New。必须明确地创建事件源对象,并将它赋给 WithEvents 变量。
    不能在标准模块中声明 WithEvents 变量。只能在类模块、窗体模块以及其它定义类的模块中声明。
    不能创建 WithEvents 变量数组。 
    编写处理事件的代码
    一旦声明了 WithEvents 变量,变量名就出现在模块“代码”窗口左边的下拉菜单上。当选择了 mWidget 时,Widget 类的事件将出现在右边下拉菜单上,如下图 9.9 中所示。图 9.9   与 WithEvents 变量相关联的事件选定一个事件,将显示相应的事件过程,以 mWidget_ 为前缀。所有跟 WithEvents 变量相关联的事件过程,都将以该变量名为前缀。将下面的代码添加到 mWidget_PercentDone 事件过程中。Private Sub mWidget_PercentDone(ByVal Percent As _
    Single, Cancel As Boolean)
       lblPercentDone.Caption = CInt(100 * Percent) & "%"
       DoEvents
       If mblnCancel Then Cancel = True
    End Sub不论何时,引发 PercentDone 事件时,事件过程就在 Label 控件中显示完成的百分比。DoEvents 语句允许重新画出该标签,同时也给用户单击“取消”按钮的机会。将下面的代码添加到标题为“取消”按钮的 Click 事件中。Private Sub Command2_Click()
       mblnCancel = True
    End Sub当 LongTask 正在运行时,如果单击了“取消”按钮,一旦 DoEvents 语句允许出现对事件的处理,那么将会执行 Command2_Click 事件。模块级的变量 mblnCancel 设置为 True,mWidget_PercentDone 事件将对其进行测试,并将 ByRef Cancel 参数设置为 True。连接 WithEvents 变量与对象
    Form1 已经设置了对 Widget 对象事件的处理。剩余工作就是寻找某个地方的 Widget。在设计时,声明 WithEvents 变量时,并没有任何对象与之相关联。WithEvents 变量与任何其它对象变量相同。必须创建对象,并将对该对象的引用赋给这个 WithEvents 变量。将下面的代码添加到 Form_Load 事件过程中,以创建 Widget。Private Sub Form_Load()
       Set mWidget = New Widget
    End Sub当执行上面的代码时,Visual Basic 将创建一个 Widget,并将它的事件跟 mWidget 相关联的事件过程连接起来。从那时起,一旦 Widget 产生了 PercentDone 事件,都将执行 mWidget_PercentDone 事件过程。为了调用 LongTask 方法,将下面的代码添加到标题为“启动任务”按钮的 Click 事件中。'“启动任务”按钮。
    Private Sub Command1_Click()
       mblnCancel = False
       lblPercentDone.Caption = "0%"
       lblPercentDone.Refresh   Call mWidget.LongTask(14.4, 0.66)   If Not mblnCancel Then lblPercentDone.Caption = 100
    End Sub在调用 LongTask 方法之前,完成百分比的显示标签必须被初始化,而且必须将模块级的 Boolean 标记(其作用是取消方法)设置为 False。用 14.4 秒任务延迟调用 LongTask。每隔三分之二秒引发一次 PercentDone 事件。每次引发该事件时,都将执行 mWidget_PercentDone 事件过程。LongTask 结束以后,都要测试 mblnCancel,以了解 LongTask 是否正常结束,或者是否因为 mblnCancel 设置为 True 而停止。只有在前一种情况下,完成的百分比才会被更新。运行程序
    按 F5 键,就使工程处于运行模式。单击“启动任务”按钮。每次引发 PercentDone 事件,带有完成百分比的标签将会被更新。单击“取消”按钮,可以停止任务。注意:单击“取消”按钮时,该按钮的外观并不会立即改变。直到 DoEvents 语句允许事件处理时,才引发 Click 事件。可能会发现用 F8 键来运行程序是有益的—这样做的话,每次将执行一行代码。可以清楚地看到是怎样执行到 LongTask 的,然后在每次引发 PercentDone 事件时,能直接重新进入 Form1。当执行回到 Form1 中的代码时,如果再次调用 LongTask 方法,将会发生什么样的情况?混乱、混沌,并最终(如果每次产生事件时都发生这种情况)出现堆栈溢出。处理不同的 Widget 事件
    通过将对新 Widget 的引用赋给 mWidget 变量,可以使得 mWidget 变量为不同 Widget 对象处理事件。事实上,每次单击按钮时,通过添加下面两行代码,可以让 Command1 中的代码来做这些:Set mWidget = New Widget      '<- 新行。
    Call mWidget.LongTask(14.4, 0.66)
    Set mWidget = Nothing         '<- 新行。每次按下按钮时,上面的代码都将创建一个新的 Widget。一旦 LongTask 方法结束,对 Widget 的引用就会通过将 mWidget 设置为 Nothing 而释放,而且这个 Widget 也被撤消。WithEvents 变量每次只能包含一个对象引用,因此如果将不同的 Widget 对象赋给 mWidget,先前 Widget 对象的事件将不会再得到处理。如果 mWidget 是唯一包含对旧 Widget 引用的对象变量时,那么该对象将被撤消。注意   需要多少 WithEvents 变量,就可以声明多少,但是不支持 WithEvents 变量数组。终止 WithEvents 变量事件的处理 
    只要有一个赋给变量 mWidget 的 Widget 对象,不论何时,当该 Widget 产生事件时,都将调用跟 mWidget 相关联的事件过程。为了终止事件处理,可以将 mWidget 设置为 Nothing,就象在下面代码块中所示。'终止 mWidget 事件处理。
    Set mWidget = Nothing当把 WithEvents 变量设置为 Nothing 时,Visual Basic 将拆除对象的事件和与该变量相关联的事件过程的连接。重点   WithEvents 变量与任何其它对象变量一样,包含一个对象引用。这个对象引用所起的作用,是保持该对象是活动的。当把对象的所有引用都设置为 Nothing 以撤消它时,不要忘记声明为 WithEvents 的那个变量。详细信息   与 WithEvents 变量相关联的事件过程看起来很象窗体上控件的事件过程。“WithEvents 与窗体上的控件事件的比较”讨论了它们之间的相似和不同之处。
      

  3.   

    Modest(塞北雪貂)·(偶最欣赏楼主的分) 
    楼上的太强了,不过我觉得告诉人家在MSDN那个位置比较好一点。
      

  4.   

    谢谢“偶”的指点,现在我的VB代码如下:
    Option Explicit
    Private WithEvents eeee As ExDcom1
    Dim obj As ObjectPrivate Sub Command1_Click()
    Dim a, b As Long
    a = obj.GetData()
    b = a + CLng(Text1.Text)
    Text3.Text = b
    obj.putData (b)
    End SubPrivate Sub Command2_Click()
    Dim a, b As Long
    a = obj.GetData()
    b = a - CLng(Text2.Text)
    Text3.Text = b
    obj.putData (b)
    End SubPrivate Sub Form_Load()
    Set obj = CreateObject("Atl_ExeCom1.ExDcom1.1")
    Set eeee = New ExDcom1
    End SubPrivate Sub Form_Unload(Cancel As Integer)
    Set obj = Nothing
    End SubPrivate Sub eeee_updatenData(ByVal n As Long)
    Text3.Text = n     //这个事件没有被正常激发!
    End Sub我的组件是用ATL写的进程外组件,我发现好象没有成功连接到组件的连接点上,所以,组件没有向多个VB程序发送事件通知。
    组件这边应当没有问题,我想主要还是VB代码没有建立接收器与组件连接点的正确连接,
    这个问题又要麻烦大家了,不好意思。。
      

  5.   

    Set obj = CreateObject("Atl_ExeCom1.ExDcom1.1")
    Set eeee = New ExDcom1obj和eeee这两个对象好像类型一样啊没有看见Set eeee=obj,就是说这是两个彼此独立的对象实例如果是同一对象实例:
    Set obj = CreateObject("Atl_ExeCom1.ExDcom1.1")
    Set eeee=obj就可以了,为什么Set eeee = New ExDcom1?如果说是两个彼此独立的对象实例:
    两个对象的实例彼此之间如何传递数据,触发事件呢?