Transfert des objets Shell avec glisser-déposer et le presse-papiers

De nombreuses applications permettent aux utilisateurs de transférer des données vers une autre application par glisser-déposer avec la souris ou en utilisant le Presse-papiers. Parmi les nombreux types de données qui peuvent être transférées figurent des objets Shell tels que des fichiers ou des dossiers. Le transfert de données shell peut se produire entre deux applications, mais les utilisateurs peuvent également transférer des données Shell vers ou depuis le bureau ou Windows Explorer.

Bien que les fichiers soient l’objet Shell le plus couramment transféré, le transfert de données Shell peut impliquer n’importe lequel des différents objets trouvés dans l’espace de noms Shell. Par exemple, votre application peut avoir besoin de transférer un fichier vers un dossier virtuel tel que la Corbeille, ou d’accepter un objet à partir d’une extension d’espace de noms non Microsoft. Si vous implémentez une extension d’espace de noms, elle doit être en mesure de se comporter correctement en tant que source et cible de glisser-déposer.

Ce document explique comment les applications peuvent implémenter des transferts de données glisser-déplacer et Presse-papiers avec des objets Shell.

Fonctionnement du glisser-déplacer avec des objets Shell

Les applications doivent souvent fournir aux utilisateurs un moyen de transférer des données Shell. Voici quelques exemples :

  • Faites glisser un fichier à partir de Windows Explorer ou du bureau et déposez-le sur une application.
  • Copier un fichier dans le Presse-papiers dans Windows Explorer et le coller dans une application.
  • Faire glisser un fichier d’une application vers la Corbeille.

Pour une discussion détaillée sur la façon de gérer ces scénarios et d’autres scénarios, consultez Gestion des scénarios de transfert de données Shell. Ce document se concentre sur les principes généraux du transfert de données Shell.

Windows fournit deux façons standard pour les applications de transférer des données Shell :

  • Un utilisateur coupe ou copie des données Shell, telles qu’un ou plusieurs fichiers, dans le Presse-papiers. L’autre application récupère les données du Presse-papiers.
  • Un utilisateur fait glisser une icône qui représente les données de l’application source et dépose l’icône sur une fenêtre appartenant à la cible.

Dans les deux cas, les données transférées sont contenues dans un objet de données. Les objets de données sont des objets COM (Component Object Model) qui exposent l’interface IDataObject . Schématiquement, il existe trois étapes essentielles que tous les transferts de données Shell doivent suivre :

  1. La source crée un objet de données qui représente les données à transférer.
  2. La cible reçoit un pointeur vers l’interface IDataObject de l’objet de données.
  3. L’élément cible appelle l’interface IDataObject pour en extraire les données.

La différence entre le Presse-papiers et les transferts de données glisser-déplacer réside principalement dans la façon dont le pointeur IDataObject est transféré de la source à la cible.

Transferts de données du presse-papiers

Le Presse-papiers est le moyen le plus simple de transférer des données Shell. La procédure de base est similaire aux transferts de données standard du Presse-papiers. Toutefois, étant donné que vous transférez un pointeur vers un objet de données, et non les données elles-mêmes, vous devez utiliser l’API presse-papiers OLE au lieu de l’API de Presse-papiers standard. La procédure suivante explique comment utiliser l’API presse-papiers OLE pour transférer des données Shell avec le Presse-papiers :

  1. La source de données crée un objet de données pour contenir les données.
  2. La source de données appelle OleSetClipboard, qui place un pointeur vers l’interface IDataObject de l’objet de données dans le Presse-papiers.
  3. L’application cible appelle OleGetClipboard pour récupérer le pointeur vers l’interface IDataObject de l’objet de données.
  4. La cible extrait les données en appelant la méthode IDataObject ::GetData .
  5. Avec certains transferts de données Shell, la cible peut également avoir besoin d’appeler la méthode IDataObject ::SetData de l’objet de données pour fournir des commentaires à l’objet de données sur le résultat du transfert de données. Consultez Gestion des opérations de déplacement optimisées pour obtenir un exemple de ce type d’opération.

Transferts de données par glisser-déposer

Bien qu’un peu plus complexe à implémenter, le transfert de données glisser-déplacer présente des avantages significatifs sur le Presse-papiers :

  • Les transferts glisser-déplacer peuvent être effectués avec un mouvement simple de la souris, ce qui rend l’opération plus flexible et intuitive à utiliser que le Presse-papiers.
  • Le glisser-déplacer fournit à l’utilisateur une représentation visuelle de l’opération. L’utilisateur peut suivre l’icône à mesure qu’elle se déplace de la source à la cible.
  • Le glisser-déplacer avertit la cible lorsque les données sont disponibles.

Les opérations de glisser-déplacer utilisent également des objets de données pour transférer des données. Toutefois, la source de déplacement doit fournir des fonctionnalités au-delà de celles requises pour les transferts par le presse-papiers.

  • La source drop doit également créer un objet qui expose une interface IDropSource . Le système utilise IDropSource pour communiquer avec la source pendant que l’opération est en cours.
  • L'objet de données glisser-déplacer est chargé de suivre les mouvements du curseur et d'afficher une icône représentant l'objet de données.

Les cibles de dépôt doivent également offrir plus de fonctionnalités que celles nécessaires pour gérer les transferts par presse-papiers :

  • La cible de suppression doit exposer une interface IDropTarget . Lorsque le curseur se trouve sur une fenêtre cible, le système utilise IDropTarget pour fournir à la cible des informations telles que la position du curseur et l’avertir lorsque les données sont déposées.
  • La cible de déplacement doit s’enregistrer auprès du système en appelant RegisterDragDrop. Cette fonction fournit au système le handle vers une fenêtre cible et un pointeur vers l’interface IDropTarget de l’application cible.

Remarque

Pour les opérations de glisser-déplacer, votre application doit initialiser COM avec OleInitialize, et non CoInitialize.

 

La procédure suivante décrit les étapes essentielles qui sont généralement utilisées pour transférer des données Shell avec glisser-déplacer :

  1. La cible appelle RegisterDragDrop pour fournir au système un pointeur vers son interface IDropTarget et inscrire une fenêtre en tant que cible de dépôt.
  2. Lorsque l’utilisateur démarre une opération de glisser-déplacer, la source crée un objet de données et lance une boucle de glisser-déplacer en appelant DoDragDrop.
  3. Lorsque le curseur se trouve sur la fenêtre cible, le système avertit la cible en appelant l’une des méthodes IDropTarget de la cible. Le système appelle IDropTarget::DragEnter lorsque le curseur entre dans la fenêtre cible et IDropTarget::DragOver lorsque le curseur passe sur la fenêtre cible. Les deux méthodes fournissent à la cible de dépôt la position actuelle du curseur et l'état des touches de modification du clavier, telles que CTRL ou ALT. Lorsque le curseur quitte la fenêtre cible, le système avertit la cible en appelant IDropTarget::DragLeave. Quand l’une de ces méthodes retourne, le système appelle l’interface IDropSource pour transmettre la valeur de retour à la source.
  4. Lorsque l’utilisateur libère le bouton de la souris pour déposer les données, le système appelle la méthode IDropTarget::Drop de la cible. Parmi les paramètres de la méthode figure un pointeur vers l’interface IDataObject de l’objet de données.
  5. La cible appelle la méthode IDataObject::GetData de l'objet de données pour extraire les données.
  6. Avec certains transferts de données Shell, la cible peut également avoir besoin d’appeler la méthode IDataObject ::SetData de l’objet de données pour fournir des commentaires à la source sur le résultat du transfert de données.
  7. Lorsque la cible a terminé avec l’objet de données, elle retourne à IDropTarget::Drop. Le système retourne de l'appel DoDragDrop de la source pour informer celle-ci que le transfert de données est terminé.
  8. Selon le scénario de transfert de données particulier, la source peut avoir besoin d’effectuer des actions supplémentaires en fonction de la valeur retournée par DoDragDrop et des valeurs transmises à l’objet de données par la cible. Par exemple, lorsqu’un fichier est déplacé, la source doit vérifier ces valeurs pour déterminer si elle doit supprimer le fichier d’origine.
  9. La source libère l’objet de données.

Bien que les procédures décrites ci-dessus fournissent un bon modèle général pour le transfert de données Shell, il existe de nombreux types de données différents qui peuvent être contenus dans un objet de données Shell. Il existe également plusieurs scénarios de transfert de données différents que votre application peut avoir besoin de gérer. Chaque type de données et chaque scénario nécessitent une approche légèrement différente pour trois étapes clés de la procédure :

  • Comment une source construit un objet de données pour contenir les données Shell.
  • Comment une cible extrait les données Shell de l’objet de données.
  • Comment la source termine l’opération de transfert de données.

L’objet de données Shell fournit une discussion générale sur la façon dont une source construit un objet de données Shell et la façon dont cet objet de données peut être géré par la cible. La gestion des scénarios de transfert de données Shell décrit en détail comment gérer un certain nombre de scénarios courants de transfert de données Shell.