Operace se schránkou
Okno by mělo při vyjmutí, kopírování nebo vkládání dat používat schránku. Okno umístí data do schránky pro operace vyjmutí a kopírování a načte data ze schránky pro operace vložení. Následující části popisují tyto operace a související problémy.
Pokud chcete data umístit do schránky nebo je načíst, musí okno nejdřív otevřít schránku pomocí funkce OpenClipboard. V jednom okně může být schránka otevřená jenom v jednom okně. Pokud chcete zjistit, které okno má schránku otevřenou, zavolejte funkci GetOpenClipboardWindow. Po dokončení musí okno zavřít schránku zavoláním funkce CloseClipboard.
V této části jsou popsána následující témata.
- operace vyjmutí a kopírování
- operace vložení
- vlastnictví schránky
- zpožděné vykreslování
- Paměť a schránka
Operace vyjmutí a kopírování
Pokud chcete umístit informace do schránky, okno nejprve vymaže veškerý předchozí obsah schránky pomocí funkce EmptyClipboard. Tato funkce odešle WM_DESTROYCLIPBOARD zprávu předchozímu vlastníkovi schránky, uvolní prostředky přidružené k datům ve schránce a přiřadí vlastnictví schránky k okně, které má otevřenou schránku. Pokud chcete zjistit, které okno vlastní schránku, zavolejte funkci GetClipboardOwner.
Po vyprázdnění schránky okno umístí data do schránky v co největším počtu formátů schránky seřazených od nejvýstižnějšího formátu schránky až po nejméně popisný. Pro každý formát okno volá funkci SetClipboardData, která určuje identifikátor formátu a globální popisovač paměti. Popisovač paměti může mít hodnotu NULL, což znamená, že okno vykreslí data na vyžádání. Další informace naleznete v tématu zpožděné vykreslování.
Operace vložení
Pokud chcete načíst informace o vložení ze schránky, okno nejprve určuje formát schránky, který se má načíst. Obvykle okno vyčísluje dostupné formáty schránky pomocí funkce EnumClipboardFormats a používá první formát, který rozpozná. Tato metoda vybere nejlepší dostupný formát podle nastavené priority při umístění dat do schránky.
Případně může okno použít funkci GetPriorityClipboardFormat. Tato funkce identifikuje nejlepší dostupný formát schránky podle zadané priority. Okno, které rozpozná pouze jeden formát schránky, může jednoduše určit, zda je tento formát k dispozici pomocí funkce IsClipboardFormatAvailable.
Po určení formátu schránky, který se má použít, volá okno funkci GetClipboardData. Tato funkce vrátí popisovač objektu globální paměti obsahující data v zadaném formátu. Okno může krátce uzamknout objekt paměti, aby bylo možné data prozkoumat nebo zkopírovat. Okno by však nemělo uvolnit objekt nebo ho nechat uzamčený po dlouhou dobu.
Vlastnictví schránky
Vlastník schránky je okno přidružené k informacím ve schránce. Okno se stane vlastníkem schránky, když umístí data do schránky, konkrétně při volání funkce EmptyClipboard. Okno zůstane vlastníkem schránky, dokud není zavřené nebo jiné okno vyprázdní schránku.
Po vyprázdnění schránky obdrží vlastník schránky zprávu WM_DESTROYCLIPBOARD. Tady je několik důvodů, proč okno může tuto zprávu zpracovat:
- Zpožděné vykreslování okna jednoho nebo více formátů schránky. V reakci na zprávu WM_DESTROYCLIPBOARD může okno uvolnit prostředky, které přidělil, aby bylo možné vykreslit data na žádost. Další informace o vykreslování dat naleznete v tématu Zpožděné vykreslování.
- Okno umístilo data do schránky v privátním formátu schránky. Data pro soukromé formáty schránky systém neuvolní, když je schránka vyprázdněna. Vlastník schránky by proto měl uvolnit data po přijetí zprávy WM_DESTROYCLIPBOARD. Další informace o soukromých formátech schránky naleznete v tématu Formáty schránky.
- Okno umístilo data do schránky pomocí CF_OWNERDISPLAY formátu schránky. V reakci na zprávu WM_DESTROYCLIPBOARD může okno uvolnit prostředky, které použil k zobrazení informací v okně prohlížeče schránky. Další informace o tomto alternativním formátu naleznete v tématu Formát zobrazení vlastníka.
Zpožděné vykreslování
Při umístění formátu schránky do schránky může okno zpozdit vykreslování dat v daném formátu, dokud nebudou potřebná data. K tomu může aplikace zadat null pro parametr hData funkce SetClipboardData. To je užitečné, pokud aplikace podporuje několik formátů schránky, některé nebo všechny z nich jsou časově náročné na vykreslení. Předáním popisovače NULL okno vykresluje složité formáty schránky pouze v případě, že jsou potřeba.
Pokud okno zpožďuje vykreslování formátu schránky, musí být připraven k vykreslení formátu na vyžádání, dokud se jedná o vlastníka schránky. Systém odešle vlastníkovi schránky zprávu WM_RENDERFORMAT při přijetí požadavku pro určitý formát, který nebyl vykreslen. Po přijetí této zprávy by okno mělo volat funkci SetClipboardData, která do schránky umístí globální popisovač paměti v požadovaném formátu.
Aplikace nesmí otevřít schránku před voláním SetClipboardData v reakci na zprávu WM_RENDERFORMAT. Otevření schránky není nutné a všechny pokusy o to selžou, protože schránka je aktuálně otevřená aplikací, která požadovala vykreslení formátu.
Pokud se vlastník schránky chystá zničit a zpozdil vykreslování některých nebo všech formátů schránky, obdrží zprávu WM_RENDERALLFORMATS. Po přijetí této zprávy by mělo okno otevřít schránku, zkontrolovat, zda je stále vlastníkem schránky s funkcí GetClipboardOwner a potom umístit platné popisovače paměti do schránky pro všechny formáty schránky, které poskytuje. Tím zajistíte, že tyto formáty zůstanou dostupné po zničení vlastníka schránky.
Na rozdíl od WM_RENDERFORMATby měla aplikace reagující na WM_RENDERALLFORMATS otevřít schránku před voláním SetClipboardData umístit všechny globální popisovače paměti do schránky.
Všechny formáty schránky, které nejsou vykresleny v reakci na zprávu WM_RENDERALLFORMATS přestanou být k dispozici pro jiné aplikace a už nejsou uvedené funkcemi schránky.
Zpožděné pokyny k vykreslování
Zpožděné vykreslování je funkce výkonu, která aplikaci umožňuje vyhnout se práci na vykreslení dat schránky ve formátu, který nemusí být nikdy požadován. Použití zpožděného vykreslování ale zahrnuje následující kompromisy, které je třeba vzít v úvahu:
- Použití zpožděného vykreslování zvyšuje určitou složitost aplikace a vyžaduje, aby zpracovával dvě zprávy okna vykreslování, jak je popsáno výše.
- Použití zpožděného vykreslování znamená, že aplikace ztratí možnost zachovat uživatelské rozhraní responzivní, pokud vykreslování dat trvá dostatek času, než je patrné pro uživatele. Pokud jsou data nakonec potřebná, musí okno vykreslit data při zpracování zprávy okna vykreslování, jak je popsáno výše. V důsledku toho, pokud jsou data velmi časově náročná k vykreslení, může se aplikace při vykreslování zobrazit jako nereagující (zablokovaná), protože během zpracování zprávy vykreslovacího okna se nedají zpracovat žádné jiné zprávy okna. Aplikace, která nepoužívá zpožděné vykreslování, se místo toho může rozhodnout vykreslit data ve vlákně na pozadí, aby se při vykreslování zachovala odpověď uživatelského rozhraní, například poskytování možností průběhu nebo zrušení, které nejsou dostupné při použití zpožděného vykreslování.
- Při použití zpožděného vykreslování se přidají malé režijní náklady, pokud jsou data nakonec potřebná. Při použití opožděného vykreslování okno zpočátku volá funkci SetClipboardData s popisovačem NULL a pokud jsou data později potřeba, musí okno reagovat na zprávu okna a volat funkci SetClipboardData podruhé s popisovačem vykreslených dat, jak je popsáno výše. V důsledku toho, pokud jsou data nakonec potřebná, při použití zpožděného vykreslování se přidají náklady na zpracování zprávy okna a volání SetClipboardData funkce podruhé. Tyto náklady jsou malé, ale ne nula. Pokud aplikace podporuje jenom jeden formát schránky a pokud se data vždy vyžádají, při použití zpožděného vykreslování se pouze přidá tato malá režie (náklady se liší podle hardwaru; odhad je mezi 10 a 100 mikrosekundami). Pokud jsou však data malá, režie při použití zpožděného vykreslování může překročit náklady na vykreslení dat, což by mohlo porazit účel použití zpožděného vykreslování ke zlepšení výkonu. (Při testování u dat, která jsou již v konečné podobě, režie použití zpožděného vykreslování konzistentně překročila náklady na kopírování dat do schránky, pokud data byla 100 KiB nebo menší. Toto testování nezahrnuje náklady na vykreslení dat, stačí je zkopírovat po vykreslení.)
- Zpožděné vykreslování je čistá výhoda výkonu, pokud šetří více času, než se zvyšuje režijní náklady. Pro určení režie zpožděného vykreslování je nejlepší měření, ale odhad je 10 až 100 mikrosekund. Pokud chcete vypočítat úspory při použití zpožděného vykreslování pro každý formát schránky, změřte náklady na vykreslení dat v tomto formátu a určete, jak často se tento formát nakonec požaduje (na základě výše popsaných zpráv okna). Vynásobte náklady na vykreslení dat procentem času, po který se data nakonec nepožadují (před vyprázdněním schránky nebo změnou jejího obsahu), aby bylo možné určit úspory zpožděného vykreslování pro každý formát schránky. Zpožděné vykreslování je čistou výhodou výkonu, pokud úspory překračují režijní náklady.
- Jako konkrétní vodítko zvažte umístění dat přímo do schránky, pokud je velikost dat 4 KiB nebo menší, pro aplikace, které podporují pouze jeden formát schránky, například text, kdy nejsou data výrazně náročná na vykreslení.
Paměť a schránka
Objekt paměti, který má být umístěn do schránky, by měl být přidělen pomocí funkce GlobalAlloc s příznakem GMEM_MOVEABLE.
Po umístění objektu paměti do schránky se vlastnictví tohoto popisovače paměti přenese do systému. Když je schránka vyprázdněna a objekt paměti má jeden z následujících formátů schránky, systém uvolní objekt paměti voláním zadané funkce:
Funkce pro volný objekt | Formát schránky |
---|---|
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 |
žádný |
CF_OWNERDISPLAY Když je schránka vyprázdněna objektu CF_OWNERDISPLAY, aplikace sama musí uvolnit objekt paměti. |