MFC ActiveX 控件:添加自定义事件
自定义事件与常用事件的不同之处在于它们不会由类 COleControl
自动触发。 自定义事件将控件开发人员确定的特定操作识别为事件。 自定义事件的事件映射条目由 EVENT_CUSTOM 宏表示。 以下部分为使用 ActiveX 控件向导创建的 ActiveX 控件项目实现自定义事件。
使用添加事件向导添加自定义事件
以下过程将添加特定的自定义事件 ClickIn。 可以使用此过程添加其他自定义事件。 将自定义事件名称及其参数替换为 ClickIn 事件名称和参数。
使用添加事件向导添加 ClickIn 自定义事件
加载控件的项目。
在“类视图”中,右键单击 ActiveX 控件类打开快捷菜单。
在快捷菜单中,依次单击“添加”和“添加事件”。
这会打开添加事件向导。
在“事件名称”框中,首先选择任意现有事件,单击“自定义”单选按钮,然后键入“ClickIn”。
在“内部名称”框中,键入事件触发函数的名称。 对于此示例,请使用添加事件向导 (
FireClickIn
) 提供的默认值。使用“参数名称”和“参数类型”控件,添加名为 xCoord 的参数(类型为 OLE_XPOS_PIXELS)。
添加名为 yCoord 的第二个参数(类型为 OLE_YPOS_PIXELS)。
单击“完成”以创建事件。
针对自定义事件的添加事件向导变更
添加自定义事件时,“添加事件向导”会对控件类 .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
处理程序。
使用“添加事件向导”添加消息处理程序
加载控件的项目。
在“类视图”中,选择 ActiveX 控件类。
在“属性”窗口中,可以看到 ActiveX 控件可以处理的消息列表。 任何以粗体显示的消息都已分配有处理程序函数。
请选择要处理的消息。 对于此示例,选择
WM_LBUTTONDOWN
。从右侧的下拉列表框中,选择“<添加> OnLButtonDown”。
双击“类视图”中的新处理程序函数以跳转到 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 事件。
添加使用常用事件名称的自定义事件
加载控件的项目。
在“类视图”中,右键单击 ActiveX 控件类打开快捷菜单。
在快捷菜单中,依次单击“添加”和“添加事件”。
这会打开添加事件向导。
在“事件名称”下拉列表中,选择常用事件名称。 对于此示例,选择“点击”。
对于“事件类型”,请选择“自定义”。
单击“完成”以创建事件。
在代码中的相应位置调用
FireClick
。