TN071:MFC IOleCommandTarget 实现

注释

自联机文档中首次包含此说明以来,尚未更新以下技术说明。 因此,某些过程和主题可能过期或不正确。 有关最新信息,建议在在线文档索引中搜索您感兴趣的主题。

IOleCommandTarget 接口使对象及其容器能够相互调度命令。 例如,对象的工具栏可能包含命令的按钮,例如PrintPrint PreviewSaveNewZoom。 如果此类对象嵌入在支持的 IOleCommandTarget容器中,该对象可以启用其按钮,并在用户单击命令时将命令转发到容器进行处理。 如果容器希望嵌入对象打印自身,则它可以通过通过 IOleCommandTarget 嵌入对象的接口发送命令来发出此请求。

IOleCommandTarget 是一个类似自动化的接口,客户端使用该接口在服务器上调用方法。 但是,使用 IOleCommandTarget 可节省通过自动化接口进行调用的开销,因为程序员不必使用通常昂贵的 Invoke 方法 IDispatch

在 MFC 中 IOleCommandTarget ,活动文档服务器使用该接口允许活动文档容器将命令调度到服务器。 活动文档服务器类CDocObjectServerItem使用 MFC 接口映射(请参阅 TN038:MFC/OLE IUnknown 实现)来实现IOleCommandTarget接口。

IOleCommandTarget 也在类中 COleFrameHook 实现。 COleFrameHook 是一个未记录的 MFC 类,用于实现就地编辑容器的框架窗口功能。 COleFrameHook 还使用 MFC 接口映射来实现 IOleCommandTarget 接口。 COleFrameHook's implementations IOleCommandTarget OLE commands to COleDocObjectItem-derived Active document containers. 这样,任何 MFC Active 文档容器就可以从包含的活动文档服务器接收消息。

MFC OLE 命令映射

MFC 开发人员可以使用 MFC OLE 命令映射来利用 IOleCommandTarget 。 OLE 命令映射类似于消息映射,因为它们可用于将 OLE 命令映射到包含命令映射的类的成员函数。 若要执行此作,请在命令映射中放置宏,以指定要处理的命令的 OLE 命令组、OLE 命令以及接收 OLE 命令时将发送 的WM_COMMAND 消息的命令 ID。 MFC 还为标准 OLE 命令提供了许多预定义的宏。 有关最初设计用于 Microsoft Office 应用程序的标准 OLE 命令的列表,请参阅 docobj.h 中定义的 OLECMDID 枚举。

当 MFC 应用程序收到包含 OLE 命令映射的 OLE 命令时,MFC 会尝试在应用程序的 OLE 命令映射中找到所请求命令的命令 ID 和命令组。 如果找到匹配项,则会将WM_COMMAND消息调度到包含具有请求命令 ID 的命令映射的应用程序。 (请参阅下面的说明 ON_OLECMD 。通过这种方式,调度到应用程序的 OLE 命令由 MFC 转换为WM_COMMAND消息。 然后,使用 MFC 标准 命令路由 体系结构通过应用程序的消息映射路由WM_COMMAND消息。

与消息映射不同,ClassWizard 不支持 MFC OLE 命令映射。 MFC 开发人员必须手动添加 OLE 命令映射支持和 OLE 命令映射条目。 当活动文档在容器中就地处于活动状态时,可以在WM_COMMAND消息路由链中的任何类中将 OLE 命令映射添加到 MFC Active 文档服务器。 这些类包括从 CWinApp、CViewCDocumentCOleIPFrameWnd 派生的应用程序类。 在活动文档容器中,只能将 OLE 命令映射添加到 COleDocObjectItem 派生类。 此外,在活动文档容器中,WM_COMMAND消息将仅调度到 -derived 类中的 COleDocObjectItem消息映射。

OLE 命令映射宏

使用以下宏将命令映射功能添加到类:

DECLARE_OLECMD_MAP ()

此宏位于包含命令映射的类的类声明(通常位于头文件中)。

BEGIN_OLECMD_MAP(theClass, baseClass)

theClass
包含命令映射的类的名称。

baseClass
包含命令映射的类的基类的名称。

此宏标记命令映射的开头。 在包含命令映射的类的实现文件中使用此宏。

END_OLECMD_MAP()

此宏标记命令映射的末尾。 在包含命令映射的类的实现文件中使用此宏。 此宏必须始终遵循BEGIN_OLECMD_MAP宏。

ON_OLECMD(pguid, olecmdid, id)

pguid
指向 OLE 命令命令组的 GUID 的指针。 此参数为标准 OLE 命令组的 NULL

olecmdid
要调用的命令的 OLE 命令 ID。

id
调用此 OLE 命令时要发送到包含命令映射的应用程序的WM_COMMAND消息的 ID。

使用命令映射中的ON_OLECMD宏为要处理的 OLE 命令添加条目。 收到 OLE 命令后,它们将转换为指定的WM_COMMAND消息,并使用标准 MFC 命令路由体系结构通过应用程序的消息映射进行路由。

示例:

以下示例演示如何将 OLE 命令处理功能添加到 MFC Active 文档服务器以处理 OLECMDID_PRINT OLE 命令。 此示例假定你使用 AppWizard 生成作为活动文档服务器的 MFC 应用程序。

  1. CView在 -derived 类的头文件中,将DECLARE_OLECMD_MAP宏添加到类声明中。

    注释

    CView使用 -derived 类,因为它是活动文档服务器中位于WM_COMMAND消息路由链中的类之一。

    class CMyServerView : public CView
    {
    protected: // create from serialization only
        CMyServerView();
        DECLARE_DYNCREATE(CMyServerView)
        DECLARE_OLECMD_MAP()
        // . . .
    };
    
  2. 在 -derived 类的 CView实现文件中,添加BEGIN_OLECMD_MAP和END_OLECMD_MAP宏:

    BEGIN_OLECMD_MAP(CMyServerView, CView)
    
    END_OLECMD_MAP()
    
  3. 若要处理标准 OLE 打印命令,请将 ON_OLECMD 宏添加到命令映射中,指定标准打印命令的 OLE 命令 ID,并为WM_COMMAND ID ID_FILE_PRINTID_FILE_PRINT 是 AppWizard 生成的 MFC 应用程序使用的标准打印命令 ID:

    BEGIN_OLECMD_MAP(CMyServerView, CView)
        ON_OLECMD(NULL, OLECMDID_PRINT, ID_FILE_PRINT)
    END_OLECMD_MAP()
    

请注意,在 afxdocob.h 中定义的标准 OLE 命令宏之一可用于代替ON_OLECMD宏,因为 OLECMDID_PRINT 是标准 OLE 命令 ID。 ON_OLECMD_PRINT宏将完成与上面所示ON_OLECMD宏相同的任务。

当容器应用程序通过服务器的IOleCommandTarget接口向此服务器发送OLECMDID_PRINT命令时,将在服务器中调用 MFC 打印命令处理程序,从而导致服务器打印应用程序。 用于调用在上述步骤中添加的打印命令的活动文档容器的代码如下所示:

void CContainerCntrItem::DoOleCmd()
{
    IOleCommandTarget *pCmd = NULL;
    HRESULT hr = E_FAIL;
    OLECMD ocm={OLECMDID_PRINT, 0};

    hr = m_lpObject->QueryInterface(
        IID_IOleCommandTarget,reinterpret_cast<void**>(&pCmd));

    if (FAILED(hr))
        return;

    hr = pCmd->QueryStatus(NULL, 1, &ocm, NULL);

    if (SUCCEEDED(hr) && (ocm.cmdf& OLECMDF_ENABLED))
    {
        //Command is available and enabled so call it
        COleVariant vIn;
        COleVariant vOut;
        hr = pCmd->Exec(NULL, OLECMDID_PRINT,
            OLECMDEXECOPT_DODEFAULT, &vIn, &vOut);
        ASSERT(SUCCEEDED(hr));
    }
    pCmd->Release();
}

另请参阅

按编号列出的技术说明
按类别列出的技术说明