Opérations du Presse-papiers

Une fenêtre doit utiliser le Presse-papiers lors de la coupe, de la copie ou du collage de données. Une fenêtre place les données dans le Presse-papiers pour les opérations couper et copier, et récupère les données du Presse-papiers pour les opérations de collage. Les sections suivantes décrivent ces opérations et les problèmes connexes.

Pour placer des données dans le Presse-papiers ou récupérer des données à partir de celui-ci, une fenêtre doit d’abord ouvrir le Presse-papiers à l’aide de la fonction OpenClipboard. Une seule fenêtre peut ouvrir le Presse-papiers à la fois. Pour savoir quelle fenêtre a ouvert le Presse-papiers, appelez la fonction GetOpenClipboardWindow. Une fois l’opération terminée, la fenêtre doit fermer le Presse-papiers en appelant la fonction CloseClipboard.

Les rubriques suivantes sont présentées dans cette section.

Opérations couper et copier

Pour placer des informations dans le Presse-papiers, une fenêtre efface tout d’abord tout contenu précédent du Presse-papiers à l’aide de la fonction EmptyClipboard. Cette fonction envoie le message WM_DESTROYCLIPBOARD au propriétaire du Presse-papiers précédent, libère les ressources associées aux données du Presse-papiers et attribue la propriété du Presse-papiers à la fenêtre qui a ouvert le Presse-papiers. Pour savoir quelle fenêtre possède le Presse-papiers, appelez la fonction GetClipboardOwner.

Après avoir vidé le Presse-papiers, la fenêtre place les données dans le Presse-papiers dans autant de formats de Presse-papiers que possible, classés du format de Presse-papiers le plus descriptif au moins descriptif. Pour chaque format, la fenêtre appelle la fonction SetClipboardData, en spécifiant l’identificateur de format et un handle de mémoire global. Le handle de mémoire peut être NULL, ce qui indique que la fenêtre restitue les données à la demande. Pour plus d’informations, consultez Rendu différé.

Opérations de collage

Pour récupérer des informations de collage à partir du Presse-papiers, une fenêtre détermine d’abord le format du Presse-papiers à récupérer. En règle générale, une fenêtre énumère les formats de Presse-papiers disponibles à l’aide de la fonction EnumClipboardFormats et utilise le premier format qu’elle reconnaît. Cette méthode sélectionne le meilleur format disponible en fonction du jeu de priorités lorsque les données ont été placées dans le Presse-papiers.

Vous pouvez également utiliser la fonction GetPriorityClipboardFormat. Cette fonction identifie le meilleur format de Presse-papiers disponible en fonction d’une priorité spécifiée. Une fenêtre qui reconnaît un seul format de Presse-papiers peut simplement déterminer si ce format est disponible à l’aide de la fonction IsClipboardFormatAvailable.

Après avoir déterminé le format du Presse-papiers à utiliser, une fenêtre appelle la fonction GetClipboardData. Cette fonction retourne le handle à un objet mémoire global contenant des données au format spécifié. Une fenêtre peut verrouiller brièvement l’objet mémoire afin d’examiner ou de copier les données. Toutefois, une fenêtre ne doit pas libérer l’objet ni le laisser verrouillé pendant une longue période.

Propriété du Presse-papiers

Le propriétaire du Presse-papiers est la fenêtre associée aux informations du Presse-papiers. Une fenêtre devient le propriétaire du Presse-papiers lorsqu’elle place des données dans le Presse-papiers, en particulier lorsqu’elle appelle la fonction EmptyClipboard. La fenêtre reste le propriétaire du Presse-papiers jusqu’à ce qu’elle soit fermée ou qu’une autre fenêtre vide le Presse-papiers.

Lorsque le Presse-papiers est vidé, le propriétaire du Presse-papiers reçoit un message WM_DESTROYCLIPBOARD. Voici quelques raisons pour lesquelles une fenêtre peut traiter ce message :

  • Rendu différé d’un ou plusieurs formats de Presse-papiers par la fenêtre. En réponse au message WM_DESTROYCLIPBOARD, la fenêtre peut libérer des ressources qu’elle avait allouées pour afficher les données à la demande. Pour plus d’informations sur le rendu des données, consultez Rendu différé.
  • La fenêtre a placé des données dans le Presse-papiers dans un format de Presse-papiers privé. Les données des formats de Presse-papiers privés ne sont pas libérées par le système lorsque le Presse-papiers est vidé. Par conséquent, le propriétaire du Presse-papiers doit libérer les données lors de la réception du message WM_DESTROYCLIPBOARD. Pour plus d’informations sur les formats de Presse-papiers privés, consultez Formats du Presse-papiers.
  • La fenêtre a placé des données dans le Presse-papiers à l’aide du format de Presse-papiers CF_OWNERDISPLAY. En réponse au message WM_DESTROYCLIPBOARD, la fenêtre peut libérer des ressources qu’elle avait utilisées pour afficher des informations dans la fenêtre de visionneuse du Presse-papiers. Pour plus d’informations sur ce format alternatif, consultez Format d’affichage du propriétaire.

Rendu différé

Lorsque vous placez un format de Presse-papiers dans le Presse-papiers, une fenêtre peut différer le rendu des données dans ce format tant que les données ne sont pas nécessaires. Pour ce faire, une application peut spécifier NULL pour le paramètre hData de la fonction SetClipboardData. Cela est utile si l’application prend en charge plusieurs formats de Presse-papiers, dont certains ou tous sont longs à afficher. En transmettant un handle NULL, une fenêtre affiche des formats de Presse-papiers complexes uniquement quand ils sont nécessaires.

Si une fenêtre diffère le rendu d’un format de Presse-papiers, elle doit être prête à afficher le format à la demande tant qu’elle est le propriétaire du Presse-papiers. Le système envoie au propriétaire du Presse-papiers un message WM_RENDERFORMAT lorsqu’une demande est reçue pour un format spécifique qui n’a pas été affiché. Lors de la réception de ce message, la fenêtre doit appeler la fonction SetClipboardData pour placer un handle de mémoire global dans le Presse-papiers au format demandé.

Une application ne doit pas ouvrir le Presse-papiers avant d’appeler SetClipboardData en réponse au message WM_RENDERFORMAT. L’ouverture du Presse-papiers n’est pas nécessaire et toute tentative de ce type échoue, car le Presse-papiers est actuellement ouvert par l’application qui a demandé le rendu du format.

Si le propriétaire du Presse-papiers est sur le point d’être détruit et a différé le rendu de certains ou de tous les formats du Presse-papiers, il reçoit le message WM_RENDERALLFORMATS. Lors de la réception de ce message, la fenêtre doit ouvrir le Presse-papiers, vérifier qu’elle est toujours le propriétaire du Presse-papiers avec la fonction GetClipboardOwner, puis placer des handles de mémoire valides dans le Presse-papiers pour tous les formats de Presse-papiers qu’il fournit. Cela garantit que ces formats restent disponibles une fois le propriétaire du Presse-papiers détruit.

Contrairement à WM_RENDERFORMAT, une application répondant à WM_RENDERALLFORMATS doit ouvrir le Presse-papiers avant d’appeler SetClipboardData pour placer les handles de mémoire globales dans le Presse-papiers.

Tous les formats de Presse-papiers qui ne sont pas affichés en réponse au message WM_RENDERALLFORMATS cesse d’être disponibles pour d’autres applications et ne sont plus énumérés par les fonctions du Presse-papiers.

Conseils relatifs au rendu différé

Le rendu différé est une fonctionnalité de performances, ce qui permet à une application d’éviter de faire du travail pour afficher des données du Presse-papiers dans un format qui ne peut jamais être demandé. Toutefois, l’utilisation d’un rendu différé implique les compromis suivants qui doivent être pris en compte :

  • L’utilisation du rendu différé ajoute une certaine complexité à l’application, ce qui l’oblige à gérer deux messages de fenêtre de rendu, comme décrit ci-dessus.
  • L’utilisation du rendu différé signifie que l’application perd la possibilité de maintenir la réactivité de l’interface utilisateur si le rendu des données prend suffisamment de temps pour que l’utilisateur le remarque. Avec le rendu différé, si les données sont éventuellement nécessaires, la fenêtre doit les afficher lors du traitement d’un message de fenêtre de rendu, comme décrit ci-dessus. Par conséquent, si les données sont très longues à afficher, l’application peut ne plus répondre (être bloquée) pendant le rendu, car aucun autre message de fenêtre ne peut être traité pendant le traitement du message de la fenêtre de rendu. Une application qui n’utilise pas le rendu différé peut plutôt choisir d’afficher des données sur un thread d’arrière-plan afin de conserver la réponse de l’interface utilisateur pendant le rendu, en fournissant peut-être des options de progression ou d’annulation, qui ne sont pas disponibles lors de l’utilisation du rendu différé.
  • L’utilisation du rendu différé ajoute une légère surcharge si les données sont nécessaires ultérieurement. Lorsque vous utilisez le rendu différé, une fenêtre appelle initialement la fonction SetClipboardData avec un handle NULL, et si les données sont nécessaires ultérieurement, la fenêtre doit répondre à un message de fenêtre et appeler la fonction SetClipboardData une deuxième fois avec un handle pour les données affichées, comme décrit ci-dessus. Par conséquent, si les données sont nécessaires ultérieurement, l’utilisation du rendu différé ajoute le coût de traitement d’un message de fenêtre et l’appel de la fonction SetClipboardData une deuxième fois. Ce coût est faible, mais pas nul. Si une application prend uniquement en charge un format de Presse-papiers unique et si les données sont demandées ultérieurement, l’utilisation du rendu différé ajoute simplement cette faible surcharge (le coût varie selon le matériel ; il est estimé entre 10 et 100 microsecondes). Toutefois, si les données sont petites, la surcharge liée à l’utilisation du rendu différé peut dépasser le coût de rendu des données, ce qui peut aller à l’encontre de l’objectif de l’utilisation du rendu différé pour améliorer les performances. (En cas de test, pour les données qui se trouvent déjà sous leur forme finale, la surcharge liée à l’utilisation du rendu différé a constamment dépassé le coût de copie des données dans le Presse-papiers si les données étaient de 100 Kib ou moins. Ce test n’inclut pas le coût de rendu des données, pour simplement les copier après leur rendu.)
  • Le rendu différé est un avantage net en matière de performances s’il permet de gagner plus de temps qu’il n’ajoute de surcharge. Pour déterminer la surcharge du rendu différé, il est préférable de la mesurer, mais l’estimation est comprise entre 10 et 100 microsecondes. Pour calculer les économies d’utilisation du rendu différé pour chaque format de Presse-papiers, mesurez le coût de rendu des données dans ce format et déterminez la fréquence à laquelle ce format est demandé (en fonction des messages de fenêtre décrits ci-dessus). Multipliez le coût de rendu des données par le pourcentage de temps que les données ne sont pas demandées (avant que le Presse-papiers soit vidé ou que son contenu change) pour déterminer les économies de rendu différé pour chaque format de Presse-papiers. Le rendu différé est un avantage net en matière de performances si les économies dépassent le coût de surcharge.
  • Pour les applications qui prennent en charge un seul format de Presse-papiers, tel que du texte, où les données ne sont pas considérablement coûteuses à afficher, envisagez de les placer directement dans le Presse-papiers si la taille des données est de 4 Kio ou moins.

Mémoire et Presse-papiers

Un objet mémoire à placer dans le Presse-papiers doit être alloué à l’aide de la fonction GlobalAlloc avec l’indicateur GMEM_MOVEABLE.

Une fois qu’un objet mémoire est placé dans le Presse-papiers, la propriété de ce handle de mémoire est transférée au système. Lorsque le Presse-papiers est vidé et que l’objet mémoire a l’un des formats de Presse-papiers suivants, le système libère l’objet mémoire en appelant la fonction spécifiée :

Fonction pour libérer l’objet Format de Presse-papiers
DeleteMetaFile
CF_DSPENHMETAFILE
CF_DSPMETAFILEPICT
CF_ENHMETAFILE
CF_METAFILEPICT
DeleteObject
CF_BITMAP
CF_DSPBITMAP
CF_PALETTE
GlobalFree
CF_DIB
CF_DIBV5
CF_DSPTEXT
CF_OEMTEXT
CF_TEXT
CF_UNICODETEXT
aucune
CF_OWNERDISPLAY
Lorsque le Presse-papiers est vidé d’un objet CF_OWNERDISPLAY, l’application elle-même doit libérer l’objet mémoire.