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 problèmes connexes.
Pour placer des données dans le Presse-papiers ou les récupérer, 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 est ouverte 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 fonctionCloseClipboard.
Les rubriques suivantes sont abordées dans cette section.
- opérations couper et copier
- les opérations de collage
- Propriété du Presse-papiers
- de rendu différé
- mémoire et le Presse-papiers
Opérations couper et copier
Pour placer des informations dans le Presse-papiers, une fenêtre efface 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 affecte la propriété du Presse-papiers à la fenêtre sur laquelle le Presse-papiers est ouvert. 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ées du format 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 globale. 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 de 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’il 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 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 globale 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 ou 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é de la fenêtre d’un ou plusieurs formats de Presse-papiers. 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 de 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 CF_OWNERDISPLAY Presse-papiers. 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 presse-papiers dans le Presse-papiers, une fenêtre peut retarder le rendu des données dans ce format jusqu’à ce 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 passant un handle de NULL, une fenêtre affiche des formats de Presse-papiers complexes uniquement quand et s’ils sont nécessaires.
Si une fenêtre retarde le rendu d’un format 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é rendu. 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 retardé 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 poignées 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 poignées de mémoire globales dans le Presse-papiers.
Tous les formats du 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 de rendu différés
Le rendu différé est une fonctionnalité de performances, ce qui permet à une application d’éviter de faire du travail pour restituer des données du Presse-papiers dans un format qui ne peut jamais être demandé. Toutefois, l’utilisation d’un rendu retardé implique les compromis suivants qui doivent être pris en compte :
- L’utilisation du rendu retardé ajoute une certaine complexité à l’application, ce qui lui 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 l’interface utilisateur réactive si le rendu des données prend suffisamment de temps pour que l’utilisateur soit remarqué. Avec le rendu différé, si les données sont éventuellement nécessaires, la fenêtre doit afficher les données 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 devenir visiblement non réponse (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 petite quantité de surcharge si les données sont éventuellement nécessaires. 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 fonction une deuxième fois avec un handle pour les données rendues, comme décrit ci-dessus. Par conséquent, si les données sont éventuellement nécessaires, l’utilisation du rendu retardé ajoute le coût de traitement d’un message de fenêtre et l’appel de la fonction SetClipboardData une seconde fois. Ce coût est petit, mais pas égal à zéro. Si une application prend uniquement en charge un format de Presse-papiers unique et si les données sont toujours demandées, l’utilisation du rendu différé ajoute simplement cette petite quantité de surcharge (le coût varie selon le matériel ; une estimation est comprise 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 d’affichage des données, ce qui peut vaincre 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à dans sa forme finale, la surcharge liée à l’utilisation du rendu retardé 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, simplement pour la copier une fois qu’elles sont rendues.)
- Le rendu différé est un avantage net en matière de performances s’il gagne plus de temps qu’il n’ajoute de surcharge. Pour déterminer la surcharge du rendu retardé, la mesure est optimale, mais 10 à 100 microsecondes est une estimation. Pour calculer les économies d’utilisation du rendu différé pour chaque format presse-papiers, mesurez le coût d’affichage des données dans ce format et déterminez la fréquence à laquelle ce format est finalement 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 finalement demandées (avant que le Presse-papiers soit vidé ou que son contenu change) pour déterminer les économies de rendu retardé 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 uniquement en charge un format de Presse-papiers unique, tel que du texte, où les données ne sont pas considérablement coûteuses à afficher, envisagez de placer les données 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 de 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 vers le 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 du 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 |
aucun |
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. |