Compartir a través de


TN071: Implementación de IOleCommandTarget en MFC

Nota:

La nota técnica siguiente no se ha actualizado desde que se incluyó por primera vez en la documentación en línea. Como resultado, algunos procedimientos y temas podrían estar obsoletos o ser incorrectos. Para obtener información más reciente, se recomienda buscar el tema de interés en el índice de la documentación en línea.

La interfaz IOleCommandTarget permite que los objetos y sus contenedores envíen comandos entre sí. Por ejemplo, las barras de herramientas de un objeto pueden contener botones para comandos como Print, Print Preview, Save, New y Zoom. Si este objeto se incrustaba en un contenedor que admite IOleCommandTarget, el objeto podría habilitar sus botones y reenviar los comandos al contenedor para su procesamiento cuando el usuario haga clic en ellos. Si un contenedor quería que el objeto incrustado se imprimiera, se podía realizar esta solicitud enviando un comando a través de la interfaz IOleCommandTarget del objeto incrustado.

IOleCommandTarget es una interfaz similar a Automation que un cliente usa para invocar métodos en un servidor. Sin embargo, el uso de IOleCommandTarget guarda la sobrecarga al realizar llamadas a través de las interfaces de Automation porque los programadores no tienen que usar el método normalmente costoso Invoke de IDispatch.

En MFC, los servidores de los documentos activos usan la interfaz IOleCommandTarget para permitir que los contenedores de los documentos activos envíen comandos al servidor. La clase del servidor del documento activo CDocObjectServerItem, usa asignaciones de interfaz MFC (consulte TN038: Implementación MFC/OLE IUnknown) para implementar la interfaz IOleCommandTarget.

IOleCommandTarget se implementa en la clase COleFrameHook. COleFrameHook es una clase MFC no documentada que implementa la funcionalidad de la ventana del marco de los contenedores de edición en el lugar. COleFrameHook también usa la asignación de interfaz MFC para implementar la interfaz IOleCommandTarget. La implementación COleFrameHook de IOleCommandTarget reenvía comandos OLE a los contenedores de documentos activos derivados COleDocObjectItem. Esto permite que cualquier contenedor de documentos activos de MFC reciba mensajes de los servidores de documentos activos contenidos.

Asignaciones de comandos OLE de MFC

Los desarrolladores de MFC pueden aprovechar las ventajas de IOleCommandTarget mediante las asignaciones de comandos OLE de MFC. Las asignaciones de comandos OLE son similares a las asignaciones de mensajes porque se pueden usar para asignar comandos OLE a las funciones miembro de la clase que contiene la asignación de comandos. Para que esto funcione, hay que colocar macros en la asignación de comandos para especificar el grupo de comandos OLE del comando que se desean controlar, el comando OLE y el identificador de comando del mensaje WM_COMMAND que se enviará cuando se reciba el comando OLE. MFC también proporciona una serie de macros predefinidas para los comandos OLE estándar. Para obtener una lista de los comandos OLE estándar diseñados originalmente para su uso con aplicaciones de Microsoft Office, consulte la enumeración OLECMDID, que se define en docobj.h.

Cuando una aplicación MFC recibe un comando OLE que contiene una asignación de comandos OLE, MFC intenta encontrar el identificador de comando y el grupo de comandos para ese comando solicitado en la asignación de comandos OLE de la aplicación. Si se encuentra una coincidencia, se envía un mensaje WM_COMMAND a la aplicación que contiene la asignación de comandos con el identificador del comando solicitado. (Consulte la descripción de ON_OLECMD a continuación). De este modo, MFC convierte los comandos OLE enviados a una aplicación en mensajes WM_COMMAND. Los mensajes de WM_COMMAND se enrutan a través de las asignaciones de mensajes de la aplicación mediante la arquitectura de enrutamiento de comandos estándar de MFC.

A diferencia de las asignaciones de mensajes, classWizard no admite asignaciones de comandos OLE de MFC. Los desarrolladores de MFC deben agregar la compatibilidad con la asignación de comandos OLE y las entradas de asignación de comandos OLE a mano. Las asignaciones de comandos OLE se pueden agregar a los servidores de documentos activos de MFC en cualquier clase que esté en la cadena de enrutamiento de mensajes WM_COMMAND en el momento en que el documento activo esté operativo en un contenedor. Estas clases incluyen aquellas de la aplicación derivada de CWinApp, CView, CDocument y COleIPFrameWnd. En los contenedores de documentos activos, las asignaciones de comandos OLE solo se pueden agregar a la clase derivada de COleDocObjectItem. Además, en contenedores de documentos activos, los mensajes de WM_COMMAND solo se enviarán a la asignación de mensajes en la clase derivada COleDocObjectItem.

Macros de asignación de comandos OLE

Use las macros siguientes para agregar la funcionalidad de asignación de comandos a la clase:

DECLARE_OLECMD_MAP ()

Esta macro se incluye en la declaración de clase (normalmente en el archivo de encabezado) de la clase que contiene la asignación de comandos.

BEGIN_OLECMD_MAP(theClass, baseClass)

theClass
Nombre de la clase que contiene la asignación de comando.

baseClass
Nombre de la clase raíz de la clase que contiene la asignación de comando.

Esta macro marca el principio del mapa de comandos. Use esta macro en el archivo de implementación de la clase que contiene la asignación de comandos.

END_OLECMD_MAP()

Esta macro marca el final de la asignación de comandos. Use esta macro en el archivo de implementación de la clase que contiene la asignación de comandos. Esta macro siempre debe seguir la macro BEGIN_OLECMD_MAP.

ON_OLECMD(pguid, olecmdid, id)

pguid
Puntero a la GUID del grupo de comandos OLE. Este parámetro es NULL para el grupo de comandos OLE estándar.

olecmdid
Id. de comando OLE del comando que se va a invocar.

id
Id. del mensaje de WM_COMMAND que se va a enviar a la aplicación que contiene la asignación de comandos cuando se invoca este comando OLE.

Use la macro ON_OLECMD en la asignación de comandos para agregar las entradas para los comandos OLE que se desean controlar. Cuando se reciben los comandos OLE, se convierten en el mensaje de WM_COMMAND especificado y se enrutan a través de la asignación de mensajes de la aplicación mediante la arquitectura de enrutamiento de comandos MFC estándar.

Ejemplo

En siguiente ejemplo se muestra cómo agregar la funcionalidad de control de comandos OLE a un servidor de documentos activo de MFC para controlar el comando OLE de OLECMDID_PRINT. En este ejemplo se supone que se usó AppWizard para generar una aplicación MFC que es un servidor de documentos activo.

  1. En el archivo de encabezado de la clase derivada CView, agregue la macro DECLARE_OLECMD_MAP a la declaración de clase.

    Nota:

    Use la clase derivada CView porque es una de las clases del servidor de documentos activo que se encuentra en la cadena de enrutamiento de mensajes WM_COMMAND.

    class CMyServerView : public CView
    {
    protected: // create from serialization only
        CMyServerView();
        DECLARE_DYNCREATE(CMyServerView)
        DECLARE_OLECMD_MAP()
        // . . .
    };
    
  2. En el archivo de implementación de la clase derivada CView, agregue las macros BEGIN_OLECMD_MAP y END_OLECMD_MAP:

    BEGIN_OLECMD_MAP(CMyServerView, CView)
    
    END_OLECMD_MAP()
    
  3. Para controlar el comando de impresión OLE estándar, agregue una macro ON_OLECMD a la asignación de comandos que especifica el id. de comando OLE para el comando de impresión estándar y ID_FILE_PRINT para el identificador de WM_COMMAND. ID_FILE_PRINT es el id. de comando de impresión estándar que usan las aplicaciones MFC generadas por AppWizard:

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

Tenga en cuenta que una de las macros de comandos OLE estándar, definidas en afxdocob.h, se podría usar en lugar de la macro de ON_OLECMD porque OLECMDID_PRINT es un identificador de comando OLE estándar. La macro ON_OLECMD_PRINT realizará la misma tarea que la macro ON_OLECMD mostrada anteriormente.

Cuando una aplicación contenedora envía a este servidor un comando OLECMDID_PRINT a través de la interfaz del servidor IOleCommandTarget, el controlador de comandos de impresión MFC se invocará en el servidor, lo que hará que el servidor imprima la aplicación. El código del contenedor de documentos activo para invocar el comando print agregado en los pasos anteriores tendría un aspecto similar al que se muestra a continuación:

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();
}

Consulte también

Notas técnicas por número
Notas técnicas por categoría