Delen via


Klembordbewerkingen

Een venster moet het Klembord gebruiken bij het knippen, kopiëren of plakken van gegevens. In een venster worden gegevens op het klembord geplaatst voor knip- en kopieerbewerkingen en worden gegevens opgehaald van het klembord voor plakbewerkingen. In de volgende secties worden deze bewerkingen en gerelateerde problemen beschreven.

Als u gegevens op het klembord wilt plaatsen of ophalen, moet een venster eerst het klembord openen met behulp van de functie OpenClipboard. Slechts één venster kan het Klembord tegelijk openen. Als u wilt zien welk venster het klembord heeft geopend, roept u de functie GetOpenClipboardWindow aan. Wanneer het venster is voltooid, moet het klembord worden gesloten door de functie CloseClipboard aan te roepen.

De volgende onderwerpen worden in deze sectie besproken.

Knip- en kopieerbewerkingen

Als u informatie op het klembord wilt plaatsen, wist een venster eerst eventuele vorige klembordinhoud met behulp van de functie EmptyClipboard. Met deze functie wordt het WM_DESTROYCLIPBOARD bericht verzonden naar de vorige eigenaar van het klembord, worden bronnen vrijgemaakt die zijn gekoppeld aan gegevens op het klembord en wordt het eigendom van het klembord toegewezen aan het venster waarop het klembord is geopend. Als u wilt achterhalen welk venster eigenaar is van het klembord, roept u de functie GetClipboardOwner aan.

Na het leegmaken van het klembord worden in het venster gegevens op het klembord in zoveel mogelijk klembordindelingen geplaatst, geordend van de meest beschrijvende klembordindeling tot het minst beschrijvende. Voor elke indeling roept het venster de SetClipboardData functie aan, waarbij de indelings-id en een globale geheugengreep worden opgegeven. De geheugengreep kan NULL zijn, wat aangeeft dat het venster de gegevens op aanvraag weergeeft. Zie Vertraagde renderingvoor meer informatie.

Plakbewerkingen

Als u plakgegevens van het klembord wilt ophalen, bepaalt een venster eerst de opmaak van het klembord die moet worden opgehaald. Normaal gesproken bevat een venster de beschikbare klembordindelingen met behulp van de enumClipboardFormats functie en wordt de eerste indeling gebruikt die wordt herkend. Met deze methode wordt de beste beschikbare indeling geselecteerd op basis van de prioriteitsset wanneer de gegevens op het klembord zijn geplaatst.

U kunt ook een venster gebruiken met de functie GetPriorityClipboardFormat. Deze functie identificeert de beste beschikbare klembordindeling op basis van een opgegeven prioriteit. Een venster dat slechts één klembordindeling herkent, kan eenvoudig bepalen of deze indeling beschikbaar is met behulp van de functie IsClipboardFormatAvailable.

Nadat u hebt bepaald welke klembordindeling moet worden gebruikt, roept een venster de functie GetClipboardData aan. Deze functie retourneert de ingang naar een globaal geheugenobject met gegevens in de opgegeven indeling. Een venster kan het geheugenobject kort vergrendelen om de gegevens te onderzoeken of te kopiëren. Een venster mag het object echter niet vrijlaten of het gedurende een lange periode vergrendeld laten.

Eigendom van Klembord

De eigenaar van het klembord is het venster dat is gekoppeld aan de informatie op het klembord. Een venster wordt de eigenaar van het Klembord wanneer er gegevens op het klembord worden geplaatst, met name wanneer het de functie EmptyClipboard aanroept. Het venster blijft de eigenaar van het Klembord totdat het wordt gesloten of een ander venster het klembord leeg maakt.

Wanneer het klembord wordt geleegd, ontvangt de eigenaar van het klembord een WM_DESTROYCLIPBOARD bericht. Hier volgen enkele redenen waarom een venster dit bericht kan verwerken:

  • Het venster vertraagde weergave van een of meer klembordindelingen. Als reactie op het WM_DESTROYCLIPBOARD bericht, kunnen in het venster mogelijk resources worden vrijgemaakt die het had toegewezen om gegevens op aanvraag weer te geven. Zie Vertraagde renderingvoor meer informatie over het weergeven van gegevens.
  • Het venster plaatst gegevens op het klembord in een persoonlijke klembordindeling. De gegevens voor persoonlijke klembordindelingen worden niet door het systeem vrijgemaakt wanneer het klembord wordt geleegd. Daarom moet de eigenaar van het klembord de gegevens vrijmaken bij het ontvangen van het WM_DESTROYCLIPBOARD bericht. Zie Klembordindelingenvoor meer informatie over persoonlijke klembordindelingen.
  • Het venster plaatst gegevens op het klembord met behulp van de CF_OWNERDISPLAY klembordindeling. Als reactie op het WM_DESTROYCLIPBOARD bericht, kan het venster resources vrijmaken die het had gebruikt om informatie weer te geven in het klembordviewervenster. Zie Display Formatvoor meer informatie over deze alternatieve indeling.

Vertraagde rendering

Wanneer u een klembordindeling op het klembord plaatst, kan een venster het weergeven van de gegevens in die indeling vertragen totdat de gegevens nodig zijn. Hiervoor kan een toepassing NULL- opgeven voor de parameter hData van de functie SetClipboardData. Dit is handig als de toepassing ondersteuning biedt voor verschillende klembordindelingen, waarvan sommige of allemaal tijdrovend zijn om weer te geven. Door een NULL- greep door te geven, worden in een venster alleen complexe klembordindelingen weergegeven wanneer en indien nodig.

Als een venster de weergave van een klembordindeling vertraagt, moet deze worden voorbereid om de indeling op verzoek weer te geven zolang het de eigenaar van het klembord is. Het systeem verzendt de eigenaar van het Klembord een WM_RENDERFORMAT bericht wanneer een aanvraag wordt ontvangen voor een specifieke indeling die niet is weergegeven. Wanneer u dit bericht ontvangt, moet het venster de functie SetClipboardData aanroepen om een algemene geheugengreep op het klembord in de aangevraagde indeling te plaatsen.

Een toepassing mag het Klembord niet openen voordat SetClipboardData- wordt aangeroepen als reactie op het WM_RENDERFORMAT bericht. Het openen van het klembord is niet nodig en een poging om dit te doen mislukt omdat het klembord momenteel wordt geopend door de toepassing waarvoor de indeling is aangevraagd die moet worden weergegeven.

Als de eigenaar van het klembord op het punt staat te worden vernietigd en bepaalde of alle klembordindelingen heeft vertraagd, ontvangt het WM_RENDERALLFORMATS bericht. Wanneer u dit bericht ontvangt, moet het venster het klembord openen, controleren of het nog steeds de eigenaar van het klembord is met de functie GetClipboardOwner en vervolgens geldige geheugengrepen op het klembord plaatsen voor alle indelingen van het klembord die het biedt. Dit zorgt ervoor dat deze indelingen beschikbaar blijven nadat de eigenaar van het klembord is vernietigd.

In tegenstelling tot WM_RENDERFORMAT, moet een toepassing die reageert op WM_RENDERALLFORMATS het klembord openen voordat SetClipboardData- wordt aangeroepen om globale geheugengrepen op het klembord te plaatsen.

Eventuele klembordindelingen die niet worden weergegeven als reactie op het WM_RENDERALLFORMATS bericht niet meer beschikbaar zijn voor andere toepassingen en die niet meer worden geïnventariseerd door de klembordfuncties.

Richtlijnen voor vertraagde rendering

Vertraagde rendering is een prestatiefunctie, waardoor een toepassing geen werk kan doen om klembordgegevens weer te geven in een indeling die nooit kan worden aangevraagd. Het gebruik van vertraagde rendering omvat echter de volgende afwegingen die in aanmerking moeten worden genomen:

  • Het gebruik van vertraagde rendering voegt enige complexiteit toe aan de toepassing, waardoor deze twee renderingvensterberichten moet verwerken, zoals hierboven is beschreven.
  • Als u vertraagde rendering gebruikt, verliest de toepassing de optie om de gebruikersinterface responsief te houden als het genereren van de gegevens voldoende tijd kost dat deze zichtbaar is voor de gebruiker. Bij vertraagde rendering, als de gegevens uiteindelijk nodig zijn, moet het venster de gegevens weergeven tijdens het verwerken van een renderingvensterbericht, zoals hierboven beschreven. Als de gegevens zeer tijdrovend zijn om weer te geven, kan de toepassing zichtbaar niet reageren (vastgelopen) tijdens het weergeven, omdat er geen andere vensterberichten kunnen worden verwerkt terwijl het renderingvensterbericht wordt verwerkt. Een toepassing die geen vertraagde rendering gebruikt, kan er in plaats daarvan voor kiezen om gegevens op een achtergrondthread weer te geven om het ui-antwoord te behouden terwijl de weergave plaatsvindt, mogelijk voortgangs- of annuleringsopties, die niet beschikbaar zijn bij het gebruik van vertraagde rendering.
  • Als u vertraagde rendering gebruikt, voegt u een kleine hoeveelheid overhead toe als de gegevens uiteindelijk nodig zijn. Wanneer u vertragingsweergave gebruikt, roept een venster in eerste instantie de functie SetClipboardData aan met een NULL--ingang. Als de gegevens later nodig zijn, moet het venster reageren op een vensterbericht en de functie SetClipboardData een tweede keer aanroepen met een ingang voor de gerenderde gegevens, zoals hierboven beschreven. Als de gegevens uiteindelijk nodig zijn, worden met behulp van vertraagde rendering de kosten voor het verwerken van een vensterbericht opgebeld en worden de SetClipboardData- functie een tweede keer aangeroepen. Deze kosten zijn klein, maar niet nul. Als een toepassing slechts één Klembord-indeling ondersteunt en de gegevens altijd uiteindelijk worden aangevraagd, wordt met vertraagde rendering alleen deze kleine hoeveelheid overhead toegevoegd (de kosten variëren per hardware; een schatting is tussen 10 en 100 microseconden). Als de gegevens echter klein zijn, kan de overhead van het gebruik van vertraagde rendering de kosten overschrijden om de gegevens weer te geven, wat het doel van het gebruik van vertraagde rendering kan verslaan om de prestaties te verbeteren. (Bij het testen overschreden de kosten voor het kopiëren van de gegevens naar het klembord als de gegevens 100 KiB of minder waren bij het testen van gegevens die al in de uiteindelijke vorm staan, de overhead van het gebruik van vertraagde rendering de kosten voor het kopiëren van de gegevens naar het klembord consistent overschreden. Deze test omvat niet de kosten voor het weergeven van gegevens, alleen om deze te kopiëren zodra deze is gerenderd.)
  • Vertraagde rendering is een netto prestatievoordeel als het meer tijd bespaart dan extra overhead. Om de overhead van vertraagde rendering te bepalen, is meting het beste, maar 10 tot 100 microseconden is een schatting. Als u de besparingen wilt berekenen van het gebruik van vertraagde rendering voor elke klembordindeling, meet u de kosten voor het weergeven van de gegevens in die indeling en bepaalt u hoe vaak die indeling uiteindelijk wordt aangevraagd (op basis van de hierboven beschreven vensterberichten). Vermenigvuldig de kosten voor het weergeven van de gegevens met het percentage tijd dat de gegevens niet uiteindelijk worden aangevraagd (voordat het klembord wordt geleegd of de inhoudswijziging) om de besparingen van vertraagde rendering voor elke klembordindeling te bepalen. Vertraagde rendering is een nettoprestatievoordeel als de besparingen de overheadkosten overschrijden.
  • Als concrete richtlijn kunt u voor toepassingen die slechts één klembordindeling ondersteunen, zoals tekst, waarbij de gegevens niet aanzienlijk duur zijn om weer te geven, overwegen de gegevens rechtstreeks op het klembord te plaatsen als de grootte van de gegevens 4 KiB of minder is.

Geheugen en het Klembord

Een geheugenobject dat op het klembord moet worden geplaatst, moet worden toegewezen met behulp van de functie GlobalAlloc met de vlag GMEM_MOVEABLE.

Nadat een geheugenobject op het klembord is geplaatst, wordt het eigendom van die geheugengreep overgebracht naar het systeem. Wanneer het klembord leeg is en het geheugenobject een van de volgende klembordindelingen heeft, maakt het systeem het geheugenobject vrij door de opgegeven functie aan te roepen:

Functie om een gratis object te maken Klembordindeling
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
geen
CF_OWNERDISPLAY
Wanneer het klembord van een CF_OWNERDISPLAY-object wordt geleegd, moet de toepassing zelf het geheugenobject vrijmaken.