Transferencia de objetos shell con arrastrar y colocar y el Portapapeles

Muchas aplicaciones permiten a los usuarios transferir datos a otra aplicación arrastrando y quitando los datos con el mouse, o mediante el Portapapeles. Entre los muchos tipos de datos que se pueden transferir, se encuentran objetos shell, como archivos o carpetas. La transferencia de datos de Shell puede realizarse entre dos aplicaciones, pero los usuarios también pueden transferir datos de Shell a o desde el escritorio o el Explorador de Windows.

Aunque los archivos son el objeto shell transferido más frecuentemente, la transferencia de datos de Shell puede implicar cualquiera de los diversos objetos que se encuentran en el espacio de nombres de Shell. Por ejemplo, es posible que la aplicación tenga que transferir un archivo a una carpeta virtual, como la Papelera de reciclaje, o aceptar un objeto de una extensión de espacio de nombres que no sea de Microsoft. Si va a implementar una extensión de espacio de nombres, debe ser capaz de comportarse correctamente como origen y destino de eliminación.

En este documento se describe cómo las aplicaciones pueden implementar transferencias de datos de arrastrar y colocar y portapapeles con objetos shell.

Funcionamiento de arrastrar y colocar con objetos shell

A menudo, las aplicaciones necesitan proporcionar a los usuarios una manera de transferir datos de Shell. Ejemplos:

  • Arrastrar un archivo desde el Explorador de Windows o el escritorio y colocarlo en una aplicación.
  • Copiar un archivo en el Portapapeles en el Explorador de Windows y pegarlo en una aplicación.
  • Arrastrar un archivo desde una aplicación a la Papelera de reciclaje.

Para obtener una explicación detallada de cómo controlar estos y otros escenarios, consulte Control de escenarios de transferencia de datos de Shell. Este documento se centra en los principios generales que subyacen a la transferencia de datos de Shell.

Windows proporciona dos formas estándar para que las aplicaciones transfieran datos de Shell:

  • Un usuario corta o copia datos de Shell, como uno o varios archivos, en el Portapapeles. La otra aplicación recupera los datos del Portapapeles.
  • Un usuario arrastra un icono que representa los datos de la aplicación de origen y coloca el icono en una ventana propiedad del destino.

En ambos casos, los datos transferidos están contenidos en un objeto de datos. Los objetos de datos son objetos Component Object Model (COM) que exponen la interfaz IDataObject . De forma esquemática, hay tres pasos esenciales que deben seguir todas las transferencias de datos de Shell:

  1. El origen crea un objeto de datos que representa los datos que se van a transferir.
  2. El destino recibe un puntero a la interfaz IDataObject del objeto de datos.
  3. El destino llama a la interfaz IDataObject para extraer los datos de él.

La diferencia entre el Portapapeles y las transferencias de datos de arrastrar y colocar se basa principalmente en cómo se transfiere el puntero IDataObject desde el origen al destino.

Transferencias de datos del Portapapeles

El Portapapeles es la manera más sencilla de transferir datos de Shell. El procedimiento básico es similar a las transferencias de datos estándar del Portapapeles. Sin embargo, dado que va a transferir un puntero a un objeto de datos, no a los datos, debe usar la API del Portapapeles OLE en lugar de la API estándar del Portapapeles. En el procedimiento siguiente se describe cómo usar la API del Portapapeles OLE para transferir datos de Shell con el Portapapeles:

  1. El origen de datos crea un objeto de datos para contener los datos.
  2. El origen de datos llama a OleSetClipboard, que coloca un puntero a la interfaz IDataObject del objeto de datos en el Portapapeles.
  3. El destino llama a OleGetClipboard para recuperar el puntero a la interfaz IDataObject del objeto de datos.
  4. El destino extrae los datos llamando al método IDataObject::GetData .
  5. Con algunas transferencias de datos de Shell, el destino también podría necesitar llamar al método IDataObject::SetData del objeto de datos para proporcionar comentarios al objeto de datos sobre el resultado de la transferencia de datos. Consulte Control de operaciones de movimiento optimizadas para obtener un ejemplo de este tipo de operación.

Transferencias de datos de arrastrar y colocar

Aunque algo más complejo de implementar, la transferencia de datos de arrastrar y colocar tiene algunas ventajas significativas sobre el Portapapeles:

  • Las transferencias de arrastrar y colocar se pueden realizar con un movimiento simple del mouse, lo que hace que la operación sea más flexible e intuitiva de usar que el Portapapeles.
  • Arrastrar y colocar proporciona al usuario una representación visual de la operación. El usuario puede seguir el icono a medida que pasa de origen a destino.
  • Arrastrar y colocar notifica al destino cuando los datos están disponibles.

Las operaciones de arrastrar y colocar también usan objetos de datos para transferir datos. Sin embargo, el origen de eliminación debe proporcionar funcionalidad más allá de lo necesario para las transferencias del Portapapeles:

  • El origen de colocación también debe crear un objeto que exponga una interfaz IDropSource . El sistema usa IDropSource para comunicarse con el origen mientras la operación está en curso.
  • El objeto de datos de arrastrar y colocar es responsable de realizar un seguimiento del movimiento del cursor y mostrar un icono para representar el objeto de datos.

Los destinos de colocación también deben proporcionar más funcionalidad de la necesaria para controlar las transferencias del Portapapeles:

  • El destino de colocación debe exponer una interfaz IDropTarget . Cuando el cursor se encuentra sobre una ventana de destino, el sistema usa IDropTarget para proporcionar al destino información como la posición del cursor y notificarlo cuando se quitan los datos.
  • El destino de colocación debe registrarse en el sistema llamando a RegisterDragDrop. Esta función proporciona al sistema el identificador de una ventana de destino y un puntero a la interfaz IDropTarget de la aplicación de destino.

Nota

Para las operaciones de arrastrar y colocar, la aplicación debe inicializar COM con OleInitialize, no CoInitialize.

 

En el procedimiento siguiente se describen los pasos esenciales que se usan normalmente para transferir datos de Shell con arrastrar y colocar:

  1. El destino llama a RegisterDragDrop para proporcionar al sistema un puntero a su interfaz IDropTarget y registrar una ventana como destino de colocación.
  2. Cuando el usuario inicia una operación de arrastrar y colocar, el origen crea un objeto de datos e inicia un bucle de arrastre llamando a DoDragDrop.
  3. Cuando el cursor se encuentra sobre la ventana de destino, el sistema notifica al destino mediante una llamada a uno de los métodos IDropTarget del destino. El sistema llama a IDropTarget::D ragEnter cuando el cursor entra en la ventana de destino y IDropTarget::D ragOver a medida que el cursor pasa sobre la ventana de destino. Ambos métodos proporcionan el destino de colocación con la posición actual del cursor y el estado de las teclas modificadoras de teclado, como CTRL o ALT. Cuando el cursor sale de la ventana de destino, el sistema notifica al destino mediante una llamada a IDropTarget::D ragLeave. Cuando se devuelve cualquiera de estos métodos, el sistema llama a la interfaz IDropSource para pasar el valor devuelto al origen.
  4. Cuando el usuario suelta el botón del mouse para quitar los datos, el sistema llama al método IDropTarget::D rop del destino. Entre los parámetros del método se encuentra un puntero a la interfaz IDataObject del objeto de datos.
  5. El destino llama al método IDataObject::GetData del objeto de datos para extraer los datos.
  6. Con algunas transferencias de datos de Shell, es posible que el destino también necesite llamar al método IDataObject::SetData del objeto de datos para proporcionar comentarios al origen sobre el resultado de la transferencia de datos.
  7. Cuando el destino finaliza con el objeto de datos, devuelve de IDropTarget::D rop. El sistema devuelve la llamada DoDragDrop del origen para notificar al origen que se ha completado la transferencia de datos.
  8. Según el escenario de transferencia de datos concreto, es posible que el origen tenga que realizar acciones adicionales en función del valor devuelto por DoDragDrop y los valores que el destino pasa al objeto de datos. Por ejemplo, cuando se mueve un archivo, el origen debe comprobar estos valores para determinar si debe eliminar el archivo original.
  9. El origen libera el objeto de datos.

Aunque los procedimientos descritos anteriormente proporcionan un buen modelo general para la transferencia de datos de Shell, hay muchos tipos diferentes de datos que se pueden contener en un objeto de datos de Shell. También hay una serie de escenarios de transferencia de datos diferentes que es posible que la aplicación necesite controlar. Cada tipo de datos y escenario requiere un enfoque algo diferente para tres pasos clave en el procedimiento:

  • Cómo un origen construye un objeto de datos para que contenga los datos de Shell.
  • Cómo un destino extrae datos de Shell del objeto de datos.
  • Cómo el origen completa la operación de transferencia de datos.

El objeto de datos de Shell proporciona una explicación general de cómo un origen construye un objeto de datos de Shell y cómo el destino puede controlar ese objeto de datos. El control de escenarios de transferencia de datos de Shell describe con detalle cómo controlar varios escenarios comunes de transferencia de datos de Shell.