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

若要重写 PreCreateWindowIsSubclassedControl,请将以下代码行添加到控件类声明的 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.stylecs.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 和两个参数的返回类型,该类型 WPARAMLPARAM,分别。例如:

    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 成员函数处理反射消息。wParamlParam 参数相同的与原始窗口消息。

有关示例的反射如何处理消息,请参见 MFC Activex 控件示例 按钮。它演示检测 BN_CLICKED 通知代码并通过激发的一 OnOcmCommand 处理程序 () 发送响应单击事件。

请参见

概念

MFC ActiveX 控件