CCmdTarget

Microsoft 基础类库消息映射体系结构中的基类。

语法

class CCmdTarget : public CObject

成员

公共构造函数

名称 描述
CCmdTarget::CCmdTarget 构造 CCmdTarget 对象。

公共方法

名称 描述
CCmdTarget::BeginWaitCursor 将光标显示为沙漏光标。
CCmdTarget::DoOleVerb 导致执行由 OLE 谓词指定的操作。
CCmdTarget::EnableAutomation 允许 CCmdTarget 对象的 OLE 自动化。
CCmdTarget::EnableConnections 可通过连接点触发事件。
CCmdTarget::EnableTypeLib 实现对象的类型库。
CCmdTarget::EndWaitCursor 返回上一个光标。
CCmdTarget::EnumOleVerbs 枚举对象的 OLE 谓词。
CCmdTarget::FromIDispatch 返回指向与 IDispatch 指针关联的 CCmdTarget 对象的指针。
CCmdTarget::GetDispatchIID 获取主调度接口 ID。
CCmdTarget::GetIDispatch 返回指向与 CCmdTarget 对象关联的 IDispatch 对象的指针。
CCmdTarget::GetTypeInfoCount 检索对象提供的类型信息接口的数量。
CCmdTarget::GetTypeInfoOfGuid 检索与指定的 GUID 相对应的类型说明。
CCmdTarget::GetTypeLib 获取指向类型库的指针。
CCmdTarget::GetTypeLibCache 获取类型库缓存。
CCmdTarget::IsInvokeAllowed 启用自动化方法调用。
CCmdTarget::IsResultExpected 如果自动化函数应返回值,则返回非零值。
CCmdTarget::OnCmdMsg 路由和调度命令消息。
CCmdTarget::OnFinalRelease 在释放最后一个 OLE 引用后进行清理。
CCmdTarget::RestoreWaitCursor 还原沙漏光标。

注解

消息映射将命令或消息路由到写入的成员函数以进行处理。 (命令是菜单项、命令按钮或快捷键中的消息。)

CCmdTarget 派生的关键框架类包括 CViewCWinAppCDocumentCWndCFrameWnd。 如果希望新类处理消息,请从其中一个 CCmdTarget 派生类派生类。 很少会从 CCmdTarget 直接派生类。

有关命令目标和 OnCmdMsg 路由的概述,请参阅命令目标命令路由映射消息

CCmdTarget 包含处理显示沙漏光标的成员函数。 预计命令需要明显的时间间隔才能执行时,显示沙漏光标。

调度映射(类似于消息映射)用于公开 OLE 自动化 IDispatch 功能。 通过公开此接口,其他应用程序(例如 Visual Basic)可对你的应用程序发出调用。

继承层次结构

CObject

CCmdTarget

要求

标头afxwin.h

CCmdTarget::BeginWaitCursor

预计命令需要明显的时间间隔才能执行时,调用此函数,将光标显示为沙漏光标。

void BeginWaitCursor();

备注

框架调用此函数向用户显示它处于繁忙状态,例如 CDocument 对象加载或保存到文件时。

BeginWaitCursor 的操作在单个消息处理程序之外并非总是有效,因为其他操作(例如 OnSetCursor 处理)可能会更改光标。

调用 EndWaitCursor 以还原上一个光标。

示例

// The following example illustrates the most common case
// of displaying the hourglass cursor during some lengthy
// processing of a command handler implemented in some
// CCmdTarget-derived class, such as a document or view.
void CMyView::OnBeginSleepEnd()
{
   BeginWaitCursor(); // display the hourglass cursor
   // do some lengthy processing
   Sleep(3000);
   EndWaitCursor(); // remove the hourglass cursor
}

// The next example illustrates RestoreWaitCursor.
void CMyView::OnBeginDlgRestore()
{
   BeginWaitCursor(); // display the hourglass cursor
   // do some lengthy processing
   // The dialog box will normally change the cursor to
   // the standard arrow cursor, and leave the cursor in
   // as the standard arrow cursor when the dialog box is
   // closed.
   CFileDialog dlg(TRUE);
   dlg.DoModal();

   // It is necessary to call RestoreWaitCursor here in order
   // to change the cursor back to the hourglass cursor.
   RestoreWaitCursor();
   // do some more lengthy processing
   Sleep(3000);
   EndWaitCursor(); // remove the hourglass cursor
}

// In the above example, the dialog was clearly invoked between
// the pair of calls to BeginWaitCursor and EndWaitCursor.
// Sometimes it may not be clear whether the dialog is invoked
// in between a pair of calls to BeginWaitCursor and EndWaitCursor.
// It is permissible to call RestoreWaitCursor, even if
// BeginWaitCursor was not previously called.  This case is
// illustrated below, where CMyView::AnotherFunction does not
// need to know whether it was called in the context of an
// hourglass cursor.
void CMyView::OnDlgRestore()
{
   // some processing ...
   CFileDialog dlg(TRUE);
   dlg.DoModal();
   RestoreWaitCursor();

   // some more processing ...
}

// If the dialog is invoked from a member function of
// some non-CCmdTarget, then you can call CWinApp::DoWaitCursor
// with a 0 parameter value to restore the hourglass cursor.
void CMyObject::OnDlgDoWait()
{
   CFileDialog dlg(TRUE);
   dlg.DoModal();
   AfxGetApp()->DoWaitCursor(0); // same as CCmdTarget::RestoreWaitCursor
}

CCmdTarget::CCmdTarget

构造 CCmdTarget 对象。

CCmdTarget();

CCmdTarget::DoOleVerb

导致执行由 OLE 谓词指定的操作。

BOOL DoOleVerb(
    LONG iVerb,
    LPMSG lpMsg,
    HWND hWndParent,
    LPCRECT lpRect);

参数

iVerb
谓词的数字标识符。

lpMsg
指向 MSG 结构的指针,描述调用此谓词的事件(例如双击)。

hWndParent
包含该对象的文档窗口的句柄。

lpRect
指向 RECT 结构的指针,包含用来定义 hWndParent 中对象的边框的坐标(以像素为单位)。

返回值

如果成功,则为 TRUE;否则为 FALSE

备注

此成员函数基本上实现 IOleObject::DoVerb。 可能的操作由 CCmdTarget::EnumOleVerbs 枚举。

CCmdTarget::EnableAutomation

调用此函数以启用对象的 OLE 自动化。

void EnableAutomation();

备注

此函数通常从对象的构造函数中调用,并且仅应在已为该类声明调度映射时调用。 有关自动化的详细信息,请参阅文章自动化客户端自动化服务器

CCmdTarget::EnableConnections

可通过连接点触发事件。

void EnableConnections();

注解

若要启用连接点,请在派生类的构造函数中调用此成员函数。

CCmdTarget::EnableTypeLib

实现对象的类型库。

void EnableTypeLib();

注解

如果 CCmdTarget 派生对象提供了类型信息,请在该派生对象的构造函数中调用此成员函数。

CCmdTarget::EndWaitCursor

在调用 BeginWaitCursor 成员函数后调用此函数以从沙漏光标返回到前一个光标。

void EndWaitCursor();

备注

框架在调用沙漏光标后也会调用此成员函数。

示例

// The following example illustrates the most common case
// of displaying the hourglass cursor during some lengthy
// processing of a command handler implemented in some
// CCmdTarget-derived class, such as a document or view.
void CMyView::OnBeginSleepEnd()
{
   BeginWaitCursor(); // display the hourglass cursor
   // do some lengthy processing
   Sleep(3000);
   EndWaitCursor(); // remove the hourglass cursor
}

// The next example illustrates RestoreWaitCursor.
void CMyView::OnBeginDlgRestore()
{
   BeginWaitCursor(); // display the hourglass cursor
   // do some lengthy processing
   // The dialog box will normally change the cursor to
   // the standard arrow cursor, and leave the cursor in
   // as the standard arrow cursor when the dialog box is
   // closed.
   CFileDialog dlg(TRUE);
   dlg.DoModal();

   // It is necessary to call RestoreWaitCursor here in order
   // to change the cursor back to the hourglass cursor.
   RestoreWaitCursor();
   // do some more lengthy processing
   Sleep(3000);
   EndWaitCursor(); // remove the hourglass cursor
}

// In the above example, the dialog was clearly invoked between
// the pair of calls to BeginWaitCursor and EndWaitCursor.
// Sometimes it may not be clear whether the dialog is invoked
// in between a pair of calls to BeginWaitCursor and EndWaitCursor.
// It is permissible to call RestoreWaitCursor, even if
// BeginWaitCursor was not previously called.  This case is
// illustrated below, where CMyView::AnotherFunction does not
// need to know whether it was called in the context of an
// hourglass cursor.
void CMyView::OnDlgRestore()
{
   // some processing ...
   CFileDialog dlg(TRUE);
   dlg.DoModal();
   RestoreWaitCursor();

   // some more processing ...
}

// If the dialog is invoked from a member function of
// some non-CCmdTarget, then you can call CWinApp::DoWaitCursor
// with a 0 parameter value to restore the hourglass cursor.
void CMyObject::OnDlgDoWait()
{
   CFileDialog dlg(TRUE);
   dlg.DoModal();
   AfxGetApp()->DoWaitCursor(0); // same as CCmdTarget::RestoreWaitCursor
}

CCmdTarget::EnumOleVerbs

枚举对象的 OLE 谓词。

BOOL EnumOleVerbs(LPENUMOLEVERB* ppenumOleVerb);

参数

ppenumOleVerb
指向 IEnumOLEVERB 接口的指针的指针。

返回值

如果对象支持至少一个 OLE 谓词(在这种情况下,*ppenumOleVerb 指向 IEnumOLEVERB 枚举器接口),则为 TRUE;否则为 FALSE

备注

此成员函数基本上实现 IOleObject::EnumVerbs

CCmdTarget::FromIDispatch

调用此函数,将从类的自动化成员函数接收到的 IDispatch 指针映射到实现 IDispatch 对象接口的 CCmdTarget 对象。

static CCmdTarget* PASCAL FromIDispatch(LPDISPATCH lpDispatch);

参数

lpDispatch
指向 IDispatch 对象的指针。

返回值

指向与 lpDispatch 关联的 CCmdTarget 对象的指针。 如果 IDispatch 对象未被识别为 Microsoft 基础类库 IDispatch 对象,此函数返回 NULL

注解

此函数的结果是对成员函数 GetIDispatch 的调用的反函数。

CCmdTarget::GetDispatchIID

获取主调度接口 ID。

virtual BOOL GetDispatchIID(IID* pIID);

参数

pIID
指向接口 ID (GUID) 的指针。

返回值

如果成功,则为 TRUE;否则为 FALSE。 如果成功,*pIID 设置为主调度接口 ID。

备注

派生类应重写此成员函数(如果未重写,则 GetDispatchIID 返回 FALSE)。 请参阅 COleControl

CCmdTarget::GetIDispatch

调用此成员函数,从自动化方法中检索 IDispatch 指针,该方法返回 IDispatch 指针或通过引用获取 IDispatch 指针。

LPDISPATCH GetIDispatch(BOOL bAddRef);

参数

bAddRef
指定是否递增对象的引用计数。

返回值

与对象关联的 IDispatch 指针。

备注

对于在其构造函数中调用 EnableAutomation 的对象,启用其自动化,该函数返回一个指向 IDispatch 的基础类实现的指针,该实现由通过 IDispatch 接口进行通信的客户端使用。 调用此函数会自动添加对指针的引用,因此不需要调用 IUnknown::AddRef

CCmdTarget::GetTypeInfoCount

检索对象提供的类型信息接口的数量。

virtual UINT GetTypeInfoCount();

返回值

检索类型信息接口的数量。

备注

此成员函数基本上实现 IDispatch::GetTypeInfoCount

派生类应重写此函数,以返回提供的类型信息接口数(0 或 1)。 如果未重写,则 GetTypeInfoCount 返回 0。 若要重写,请使用 IMPLEMENT_OLETYPELIB 宏,这也会实现 GetTypeLibGetTypeLibCache

CCmdTarget::GetTypeInfoOfGuid

检索与指定的 GUID 相对应的类型说明。

HRESULT GetTypeInfoOfGuid(
    LCID lcid,
    const GUID& guid,
    LPTYPEINFO* ppTypeInfo);

参数

lcid
区域设置标识符 (LCID)。

guid
类型说明的 GUID

ppTypeInfo
指向 ITypeInfo 接口的指针的指针。

返回值

一个 HRESULT,指示调用成功还是失败。 如果成功,*ppTypeInfo 指向类型信息接口。

CCmdTarget::GetTypeLib

获取指向类型库的指针。

virtual HRESULT GetTypeLib(
    LCID lcid,
    LPTYPELIB* ppTypeLib);

参数

lcid
区域设置标识符 (LCID)。

ppTypeLib
指向 ITypeLib 接口的指针的指针。

返回值

一个 HRESULT,指示调用成功还是失败。 如果成功,*ppTypeLib 指向类型库接口。

备注

派生类应重写此成员函数(如果未重写,则 GetTypeLib 返回 TYPE_E_CANTLOADLIBRARY)。 请使用 IMPLEMENT_OLETYPELIB 宏,这也会实现 GetTypeInfoCountGetTypeLibCache

CCmdTarget::GetTypeLibCache

获取类型库缓存。

virtual CTypeLibCache* GetTypeLibCache();

返回值

一个指向 CTypeLibCache 对象的指针。

备注

派生类应重写此成员函数(如果未重写,则 GetTypeLibCache 返回 NULL)。 请使用 IMPLEMENT_OLETYPELIB 宏,这也会实现 GetTypeInfoCountGetTypeLib

CCmdTarget::IsInvokeAllowed

该函数由 MFC 的 IDispatch::Invoke 实现调用,以确定是否可以调用给定的自动化方法(由 dispid 标识)。

virtual BOOL IsInvokeAllowed(DISPID dispid);

参数

dispid
调度 ID。

返回值

如果可以调用此方法,则为 TRUE;否则为 FALSE

备注

如果 IsInvokeAllowed 返回 TRUEInvoke 继续调用该方法;否则,Invoke 将失败,返回 E_UNEXPECTED

派生类可重写此函数以返回适当的值(如果未重写,则 IsInvokeAllowed 返回 TRUE)。 尤其请参阅 COleControl::IsInvokeAllowed

CCmdTarget::IsResultExpected

使用 IsResultExpected 来确定客户端是否需要从其对自动化函数的调用中获得返回值。

BOOL IsResultExpected();

返回值

如果自动化函数应返回值,则为非零值;否则为 0。

备注

OLE 接口向 MFC 提供有关客户端是使用还是忽略函数调用结果的信息,然后 MFC 使用此信息来确定调用 IsResultExpected 的结果。 如果生成返回值需要消耗大量时间或消耗大量资源,则可以在计算返回值之前调用此函数来提高效率。

此函数仅返回一次 0,这样,如果你从客户端调用的自动化函数中调用其他自动化函数,你就会得到有效的返回值。

如果在未进行自动化函数调用时调用 IsResultExpected,则返回非零值。

CCmdTarget::OnCmdMsg

由框架调用以路由和调度命令消息并处理命令用户界面对象的更新。

virtual BOOL OnCmdMsg(
    UINT nID,
    int nCode,
    void* pExtra,
    AFX_CMDHANDLERINFO* pHandlerInfo);

参数

nID
包含命令 ID。

nCode
标识命令通知代码。 请参阅注解来详细了解 nCode 的值

pExtra
根据 nCode 的值使用。 请参阅注解来详细了解 pExtra

pHandlerInfo
如果不为 NULL,则 OnCmdMsg 填充 pHandlerInfo 结构的 pTargetpmf 成员,而不是调度命令。 通常此参数应为 NULL

返回值

如果消息已处理,则为非零值;否则为 0。

备注

这是框架命令体系结构的主要实现例程。

在运行时,OnCmdMsg 将命令调度给其他对象或通过调用根类 CCmdTarget::OnCmdMsg 来处理命令本身,此根类执行实际的消息映射查找。 有关默认命令路由的完整说明,请参阅消息处理和映射主题

在极少数情况下,你可能需要重写此成员函数以扩展框架的标准命令路由。 若要进一步详细了解命令路由体系结构,请参阅技术说明 21

如果重写 OnCmdMsg,你必须为 nCode(命令通知代码)和 pExtra(取决于 nCode 的值)提供相应的值。 下表列出了这些项的相应值:

nCode pExtra
CN_COMMAND CCmdUI*
CN_EVENT AFX_EVENT*
CN_UPDATE_COMMAND_UI CCmdUI*
CN_OLECOMMAND COleCmdUI*
CN_OLE_UNREGISTER NULL

示例

// This example illustrates extending the framework's standard command
// route from the view to objects managed by the view.  This example
// is from an object-oriented drawing application, similar to the
// DRAWCLI sample application, which draws and edits "shapes".
BOOL CMyView::OnCmdMsg(UINT nID,
                       int nCode,
                       void *pExtra,
                       AFX_CMDHANDLERINFO *pHandlerInfo)
{
   // Extend the framework's command route from the view to
   // the application-specific CMyShape that is currently selected
   // in the view. m_pActiveShape is NULL if no shape object
   // is currently selected in the view.
   if ((m_pActiveShape != NULL) &&
       m_pActiveShape->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
      return TRUE;

   // If the object(s) in the extended command route don't handle
   // the command, then let the base class OnCmdMsg handle it.
   return CView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

 

// The command handler for ID_SHAPE_COLOR (menu command to change
// the color of the currently selected shape) was added to the message
// map of CMyShape (note, not CMyView) using the Properties window.
// The menu item will be automatically enabled or disabled, depending
// on whether a CMyShape is currently selected in the view, that is,
// depending on whether CMyView::m_pActiveView is NULL.  It is not
// necessary to implement an ON_UPDATE_COMMAND_UI handler to enable
// or disable the menu item.
BEGIN_MESSAGE_MAP(CMyShape, CCmdTarget)
ON_COMMAND(ID_SHAPE_COLOR, &CMyShape::OnShapeColor)
END_MESSAGE_MAP()

CCmdTarget::OnFinalRelease

当释放来自对象或到对象的最后一个 OLE 引用时由框架调用。

virtual void OnFinalRelease();

备注

重写此函数以提供针对这种情况的特殊处理。 默认实现将删除对象。

CCmdTarget::RestoreWaitCursor

调用此函数可在系统光标更改后还原相应的沙漏光标(例如,在长时间操作过程中消息框打开后又关闭)。

void RestoreWaitCursor();

示例

// The following example illustrates the most common case
// of displaying the hourglass cursor during some lengthy
// processing of a command handler implemented in some
// CCmdTarget-derived class, such as a document or view.
void CMyView::OnBeginSleepEnd()
{
   BeginWaitCursor(); // display the hourglass cursor
   // do some lengthy processing
   Sleep(3000);
   EndWaitCursor(); // remove the hourglass cursor
}

// The next example illustrates RestoreWaitCursor.
void CMyView::OnBeginDlgRestore()
{
   BeginWaitCursor(); // display the hourglass cursor
   // do some lengthy processing
   // The dialog box will normally change the cursor to
   // the standard arrow cursor, and leave the cursor in
   // as the standard arrow cursor when the dialog box is
   // closed.
   CFileDialog dlg(TRUE);
   dlg.DoModal();

   // It is necessary to call RestoreWaitCursor here in order
   // to change the cursor back to the hourglass cursor.
   RestoreWaitCursor();
   // do some more lengthy processing
   Sleep(3000);
   EndWaitCursor(); // remove the hourglass cursor
}

// In the above example, the dialog was clearly invoked between
// the pair of calls to BeginWaitCursor and EndWaitCursor.
// Sometimes it may not be clear whether the dialog is invoked
// in between a pair of calls to BeginWaitCursor and EndWaitCursor.
// It is permissible to call RestoreWaitCursor, even if
// BeginWaitCursor was not previously called.  This case is
// illustrated below, where CMyView::AnotherFunction does not
// need to know whether it was called in the context of an
// hourglass cursor.
void CMyView::OnDlgRestore()
{
   // some processing ...
   CFileDialog dlg(TRUE);
   dlg.DoModal();
   RestoreWaitCursor();

   // some more processing ...
}

// If the dialog is invoked from a member function of
// some non-CCmdTarget, then you can call CWinApp::DoWaitCursor
// with a 0 parameter value to restore the hourglass cursor.
void CMyObject::OnDlgDoWait()
{
   CFileDialog dlg(TRUE);
   dlg.DoModal();
   AfxGetApp()->DoWaitCursor(0); // same as CCmdTarget::RestoreWaitCursor
}

另请参阅

MFC 示例 ACDUAL
CObject
层次结构图
CCmdUI
CDocument
CDocTemplate
CWinApp
CWnd
CView
CFrameWnd
COleDispatchDriver