MFC ActiveX 控件:Subclassing Windows控件
本文介绍 subclassing 的一个常见的 windows 控件的过程创建 Activex 控件。Subclassing 现有 windows 控件是一种快速开发 Activex 控件。新的控件将具有这样一个 windows 控件的功能,例如绘制并响应鼠标单击。MFC Activex 控件示例 按钮 是 subclassing windows 控件的示例。
对的子类 windows 控件,完成以下任务:
重写 COleControl 的 IsSubclassedControl 和 PreCreateWindow 成员函数
修改 OnDraw 成员函数
处理任何 Activex 控件消息 (OCM) 反映控件
说明 ,如果在 控件设置 页上,选择 control 子类使用的 Select Parent Window Class 下拉列表此行为为您完成由 Activex 控件向导。
请参见知识库文章 Q243454 有关 subclassing 控件的更多信息。
重写的 IsSubclassedControl 和 PreCreateWindow
若要重写 PreCreateWindow 和 IsSubclassedControl,请将以下代码行添加到控件类声明的 protected 部分:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
BOOL IsSubclassedControl();
在控件实现文件 (.CPP),添加以下代码行实现两个重写函数:
// CMyAxSubCtrl::PreCreateWindow - Modify parameters for CreateWindowEx
BOOL CMyAxSubCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
cs.lpszClass = _T("BUTTON");
return COleControl::PreCreateWindow(cs);
}
// CMyAxSubCtrl::IsSubclassedControl - This is a subclassed control
BOOL CMyAxSubCtrl::IsSubclassedControl()
{
return TRUE;
}
注意,在此示例中, windows 按钮控件在 PreCreateWindow指定。但是,所有标准 windows 控件都可以创建子类。有关标准 windows 控件的更多信息,请参见 控制。
当 subclassing windows 控件时,您可能需要指定特定窗口样式 (WS_) 或用于创建控制窗口的扩展窗口样式 (WS_EX_) 标志。可以通过修改 cs.style 和 cs.dwExStyle 结构字段设置这些参数的值。 PreCreateWindow 成员函数。应使用 OR 操作,这些字段的修改,保留由类 COleControl默认设置标志。例如,在中,如果控件 subclassing 按钮控件,并且希望控件显示为复选框,插入以下代码行添加到 CSampleCtrl::PreCreateWindow的实现中,在返回语句之前:
cs.style |= BS_CHECKBOX;
此操作添加 BS_CHECKBOX 样式标志,,同时将默认样式标志 (WS_CHILD) 时类 COleControl 不变。
修改 OnDraw 成员函数
如果希望的子类控件保留与对应的窗口,控件的 OnDraw 成员函数只应包含对 DoSuperclassPaint 成员函数的外观,如下面的示例所示:
void CMyAxSubCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, const CRect& /*rcInvalid*/)
{
if (!pdc)
return;
DoSuperclassPaint(pdc, rcBounds);
}
DoSuperclassPaint 成员函数,实现由 COleControl,在指定的设备上下文使用 windows 控件的窗口过程绘制控件,在边框内。,即使不处于活动状态,这使得控件可见。
说明 |
---|
DoSuperclassPaint 成员函数仅使用允许设备上下文将作为 WM_PAINT 消息的 wParam 的控件类型一起使用。这包括某些标准 windows 控件,如 滚动条 和 按钮和所有公共控件。对于不支持此行为的控件,则必须提供您的代码正确地显示非活动控件。 |
处理反映的窗口消息
windows 控件通常发送某些窗口信息到其父窗口。某些消息,例如 WM_COMMAND,用户提供事件的通知。其他例如, WM_CTLCOLOR,用于从父窗口的信息。Activex 控件与父窗口通常通信是通过其他方式。通知由激发的事件通信 (发送事件通知),并且,有关控件容器的信息通过访问容器的单个属性获取。由于这些通信技术存在, Activex 控件容器不应指示控件发送的任何窗口的信息。
若要防止容器接收一个子类 windows 控件发送的 windows 信息, COleControl 另外创建的窗口充当控件的父级。此额外的窗口,称为 “reflector,”的子类 windows 控件的 Activex 控件仅创建并具有相同大小和位置与控件的窗口。reflector 窗口截获某些 windows 消息并将它们添加到控件中。控件,在其 windows 程序中,可以通过采取措施然后处理这些反射消息适合于 Activex 控件 (例如,激发事件)。为截获的窗口消息及其相应的反射消息列表参见 反映的窗口消息 ID 。
Activex 控件容器能设计执行消息反映,不需要 COleControl 创建 reflector 窗口和减少一个子类 windows 控件的运行时系统开销。COleControl 检测容器是通过检查支持此功能 MessageReflect 环境属性与 TRUE的值。
处理反射的窗口消息,将项添加到控件信息映射和实现处理程序函数。由于反射消息不为标准的部分窗口定义的计时消息,类视图不支持添加这样的消息处理程序。但是,手动添加处理程序不困难。
若要添加反射的 windows 消息的消息处理程序手动执行以下操作:
在控件类。H 文件,声明处理函数。函数应具有 LRESULT 和两个参数的返回类型,该类型 WPARAM 和 LPARAM,分别。例如:
class CMyAxSubCtrl : public COleControl { ... protected: LRESULT OnOcmCommand(WPARAM wParam, LPARAM lParam); };
在控件类 .CPP 文件中,添加 ON_MESSAGE 项到消息映射。此项的参数应为消息标识符和处理程序函数的名称。例如:
BEGIN_MESSAGE_MAP(CMyAxSubCtrl, COleControl) ON_MESSAGE(OCM_COMMAND, &CMyAxSubCtrl::OnOcmCommand) END_MESSAGE_MAP()
在 .CPP 文件,请实现 OnOcmCommand 成员函数处理反射消息。wParam 和 lParam 参数相同的与原始窗口消息。
有关示例的反射如何处理消息,请参见 MFC Activex 控件示例 按钮。它演示检测 BN_CLICKED 通知代码并通过激发的一 OnOcmCommand 处理程序 () 发送响应单击事件。