MFC ActiveX 控件:添加自定义事件

自定义事件与常用事件的不同之处在于它们不会由类 COleControl 自动触发。 自定义事件将控件开发人员确定的特定操作识别为事件。 自定义事件的事件映射条目由 EVENT_CUSTOM 宏表示。 以下部分为使用 ActiveX 控件向导创建的 ActiveX 控件项目实现自定义事件。

使用添加事件向导添加自定义事件

以下过程将添加特定的自定义事件 ClickIn。 可以使用此过程添加其他自定义事件。 将自定义事件名称及其参数替换为 ClickIn 事件名称和参数。

使用添加事件向导添加 ClickIn 自定义事件

  1. 加载控件的项目。

  2. 在“类视图”中,右键单击 ActiveX 控件类打开快捷菜单

  3. 在快捷菜单中,依次单击“添加”和“添加事件”。

    这会打开添加事件向导。

  4. 在“事件名称”框中,首先选择任意现有事件,单击“自定义”单选按钮,然后键入“ClickIn”

  5. 在“内部名称”框中,键入事件触发函数的名称。 对于此示例,请使用添加事件向导 (FireClickIn) 提供的默认值。

  6. 使用“参数名称”和“参数类型”控件,添加名为 xCoord 的参数(类型为 OLE_XPOS_PIXELS)

  7. 添加名为 yCoord 的第二个参数(类型为 OLE_YPOS_PIXELS)

  8. 单击“完成”以创建事件

针对自定义事件的添加事件向导变更

添加自定义事件时,“添加事件向导”会对控件类 .H、.CPP 和 .IDL 文件进行更改。 以下代码示例特定于 ClickIn 事件。

将以下行添加到控件类的标头 (.H) 文件中:

void FireClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord)
{
   FireEvent(eventidClickIn, EVENT_PARAM(VTS_XPOS_PIXELS VTS_YPOS_PIXELS), xCoord, yCoord);
}

此代码声明一个名为 FireClickIn 的内联函数,该函数使用你通过“添加事件向导”定义的 ClickIn 事件和参数调用 COleControl::FireEvent

此外,位于控件类的实现 (.CPP) 文件中的以下行会添加到控件的事件映射中:

EVENT_CUSTOM_ID("ClickIn", eventidClickIn, FireClickIn, VTS_XPOS_PIXELS VTS_YPOS_PIXELS)
EVENT_CUSTOM_ID("ClickIn", eventidClickIn, FireClickIn, VTS_XPOS_PIXELS VTS_YPOS_PIXELS)

此代码将事件 ClickIn 映射到内联函数 FireClickIn,传递使用“添加事件向导”定义的参数。

最后,以下行会添加到控件的 .IDL 文件中:

[id(1)] void ClickIn(OLE_XPOS_PIXELS xCoord, OLE_YPOS_PIXELS yCoord);

此行会为 ClickIn 事件分配一个特定的 ID 号,该 ID 号取自“添加事件向导”事件列表中的事件位置。 通过事件列表中的条目,容器可以预测事件。 例如,它可以提供在触发事件时要执行的处理程序代码。

调用 FireClickIn

现在,你已使用“添加事件向导”添加了 ClickIn 自定义事件,必须决定何时触发此事件。 可以通过在发生相应操作时调用 FireClickIn 来实现此目的。 对于此讨论,控件使用 InCircle 消息处理程序内的 WM_LBUTTONDOWN 函数在用户单击圆形或椭圆区域时触发 ClickIn 事件。 以下过程添加 WM_LBUTTONDOWN 处理程序。

使用“添加事件向导”添加消息处理程序

  1. 加载控件的项目。

  2. 在“类视图”中,选择 ActiveX 控件类

  3. 在“属性”窗口中,可以看到 ActiveX 控件可以处理的消息列表。 任何以粗体显示的消息都已分配有处理程序函数。

  4. 请选择要处理的消息。 对于此示例,选择 WM_LBUTTONDOWN

  5. 从右侧的下拉列表框中,选择“<添加> OnLButtonDown”

  6. 双击“类视图”中的新处理程序函数以跳转到 ActiveX 控件的实现 (.CPP) 文件中的消息处理程序代码

每次在控件窗口中单击鼠标左键时,以下代码示例都会调用 InCircle 函数。 可以在 Circ 示例摘要中的 WM_LBUTTONDOWN 处理函数 OnLButtonDown 中找到此示例。

void CMyAxUICtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
   if (InCircle(point))
      FireClickIn(point.x, point.y);

   COleControl::OnLButtonDown(nFlags, point);
}

注意

当“添加事件向导”为鼠标按钮操作创建消息处理程序时,会自动添加对基类的同一消息处理程序的调用。 请勿删除此调用。 如果控件使用任何常用鼠标消息,则必须调用基类中的消息处理程序,以确保正确处理鼠标捕获。

在以下示例中,仅当在控件内的圆形或椭圆形区域内进行单击时,才会触发该事件。 若要实现此行为,可以将 InCircle 函数置于控件的实现 (.CPP) 文件:

VARIANT_BOOL CMyAxUICtrl::InCircle(CPoint& point)
{
   CRect rc;
   GetClientRect(rc);
   // Determine radii
   double a = (rc.right - rc.left) / 2;
   double b = (rc.bottom - rc.top) / 2;

   // Determine x, y
   double x = point.x - (rc.left + rc.right) / 2;
   double y = point.y - (rc.top + rc.bottom) / 2;

   // Apply ellipse formula
   return ((x * x) / (a * a) + (y * y) / (b * b) <= 1);
}

还需要将 InCircle 函数的以下声明添加到控件的标头 (.H) 文件中:

VARIANT_BOOL InCircle(CPoint& point);

具有常用名称的自定义事件

可以创建与常用事件同名的自定义事件,但是无法在同一个控件中实现这两个事件。 例如,你可能想要创建一个名为 Click 的自定义事件,该事件不会触发,而常用事件 Click 可以正常触发。 之后可以通过调用其触发函数随时触发 Click 事件。

以下过程添加自定义 Click 事件。

添加使用常用事件名称的自定义事件

  1. 加载控件的项目。

  2. 在“类视图”中,右键单击 ActiveX 控件类打开快捷菜单

  3. 在快捷菜单中,依次单击“添加”和“添加事件”。

    这会打开添加事件向导。

  4. 在“事件名称”下拉列表中,选择常用事件名称。 对于此示例,选择“点击”

  5. 对于“事件类型”,请选择“自定义”

  6. 单击“完成”以创建事件

  7. 在代码中的相应位置调用 FireClick

另请参阅

MFC ActiveX 控件
MFC ActiveX 控件:方法
COleControl 类