Dnes pokračujeme v našem pravidelném popisu jednotlivých zajímavých oblastí programování v Delphi. O práci se schránkou (clipboard) jsme se již zmínili v několika předchozích kapitolách, dnes toto téma rozšíříme a shrneme.
Využití schránky v aplikacích
Dnešní díl seriálu bude trochu oddychovější, neboť po vyčerpávajícím popisu souborů a knihoven DLL potřebujeme všichni trochu odpočinku:-). Podíváme se tedy na nepříliš komplikované, přesto však poměrně rozsáhlé téma, které si zmínku rozhodně zasluhuje. Dnes si opět prozradíme několik obecných informací ke schránce, shrneme formáty dat, které se ve schránce mohou vyskytovat a zopakujeme si základní úkony se schránkou v Delphi. Pak lehce „načneme“ téma obtížnějších operací se schránkou v Delphi. Toto téma následně dokončíme za týden a opět si uvedeme několik praktických ukázek aplikací.
Co je to vlastně schránka ve Windows? K čemu se používá? Je to asi každému jasné, nicméně pro úplnost to zopakujeme. Schránka je nejčastěji používaný mechanismus ke komunikaci mezi aplikacemi. Při práci ve Windows máme zpravidla otevřených více aplikací, např. textový editor, tabulkový procesor, prohlížeč obrázků, internetový prohlížeč. Potřebujeme-li nejsnáze přenést data (typicky text nebo obrázek) z jedné aplikace do druhé, provedeme to pomocí schránky.
Určitě znáte klávesové zkratky Ctrl-C, Ctrl-V, pravděpodobně znáte také Ctrl-X. První slouží ke zkopírování označeného textu (nebo jiného objektu) do schránky, druhá k vložení obsahu schránky na místo kurzoru. Zkratka Ctrl-X funguje stejně jako Ctrl-V, ale navíc označená data vyjme ze zdrojového dokumentu.
Ve vašich programech doporučuji neměnit tyto zaběhnuté zkratky, dokonce je nedoporučuji ani počešťovat, neboť jsou většině uživatelů notoricky známé a případná změna (překlad) způsobí pouze nesmírné zmatení.
Potřebujeme-li se podívat, co je momentálně ve schránce, nabízí se použití standardně dodávaného Windows programu: Prohlížeč schránky.
Poznámka: ve Windows 2000 byl tento program přejmenován, jmenuje se Prohlížeč síťové schránky a spustíte jej např. pomocí nabídky Start – Spustit – clipbrd.
Možná jste přemýšleli, jak je zařízeno, že ve schránce nemusí být uložen jen čistý text, ale mohou se v ní nacházet data nejrůznějších typů, např. bitmapy, tabulky, HTML kód, apod. Důvody si vysvětlíme v nadcházející podkapitole. Jen podotýkám, že Delphi práci se schránkou nesmírně zjednodušuje. Pokud byste hodlali implementovat práci se schránkou např. při vyvíjení aplikací v Microsoft Visual C++, byla by práce trochu obtížnější (bylo by zapotřebí nejprve alokovat blok paměti, pak získat jeho handle – tj. jednoznačný číselný identifikátor –, následně otevřít schránku, pak předat alokovaný paměťový blok – prostřednictvím zmíněného handle – schránce a nakonec schránku zase uzavřít). V Delphi prakticky nic z toho dělat nemusíte. Hádejte, kdo to udělá za vás…:-)
Obecně platí, že ve schránce mohou být umístěna data některého z mnoha typů. Ty nejdůležitější z nich popisuje následující tabulka. Ovšem v Delphi zpravidla používáme pouze 5 předdefinovaných formátů. Ty se v následující tabulce nevyskytují, protože si je popíšeme v další podkapitole.
Označení formátu |
Popis |
CF_TEXT |
Obyčejný text. Přesněji řečeno – řetězec ANSI znaků, který na konci každého řádku obsahuje znak CR (Carriage Return, návrat vozíku) a LF (Line Feed, přechod na novou řádku). Konec textu je indikován znakem NULL (nulovým znakem). |
CF_OEMTEXT |
Text používající znakovou sadu OEM. Platí o něm totéž jako o formátu CF_TEXT (znaky CR, LF). Tato znaková sada se zpravidla ve Windowských aplikacích nepoužívá, ke slovu přichází v případě, že používáme ve Windows DOSovské aplikace pracující se schránkou. |
CF_UNICODETEXT |
Text ve znakové sadě Unicode. Opět obsahuje na koncích řádků znaky CR a LF. Tento typ je podporován pouze ve Windows od verze NT. |
CF_DIF |
Data ve formátu DIF (Data Interchange Format). Tento formát je používaný prakticky pouze pro přenos dat do tabulkového procesoru VisiCalc. Jde v podstatě o určitou odnož textového formátu s řádky ukončenými znaky CR a LF. |
CF_SYLK |
Data ve formátu Microsoftu „Symbolický Link“. Používá se pro výměnu dat mezi programy Microsoftu Multiplan, Chart a Excel. Opět jde o určitý druh ASCII formátu s řádky ukončenými znaky CR a LF. |
CF_BITMAP |
Obrázek ve formátu bitmapy. Tato bitmapa není závislá na zařízení. |
CF_DIB |
Také obrázek ve formátu bitmapy, nicméně bitmapa je závislá na zařízení. Data začínají informační strukturou, následuje tabulka možných barev a pak vlastní bitmapa. |
CF_PALETTE |
Data obsahující palety barev. |
CF_PICTURE |
Objekt typu TPicture |
CF_TIFF |
Data ve formátu TIFF (Tag Image File Format). Tento formát vyvinuly firmy Hewlett-Packard, Aldus a Microsoft. |
CF_METAFILEPICT |
Metasouborový formát vycházející z původního metasouboru ve Windows |
CF_ENHMETAFILE |
Rozšířený metasoubor |
CF_WAVE |
Data ve formátu zvuku *.wav |
CF_RIFF |
Data ve formátu multimediálního souboru RIFF (Resource Intercharge File Format) |
CF_COMPONENT |
Objekt typu TPersistent. |
Poznámky pro pokročilé uživatele:
Metasoubor je binární soubor popisující posloupnost kreslicích kroků.
Je možné používat i jiný datový typ (tzv. uživatelský formát), nicméně je nutné jej registrovat pomocí funkce TPicture.RegisterClipboardFormat.
Využití schránky při programování v Delphi
Nejjednodušší (přesto však v drtivé většině případů postačující) úkony se schránkou provádíme pomocí tří klíčových metod:
- CopyToClipboard: zkopíruje označený objekt do schránky.
- CutToClipboard: přesune označený objekt do schránky.
- PasteFromClipboard: vloží objekt ze schránky na aktuální pozici kurzoru
Tyto metody jsou k dispozici u celé řady komponent pracujících s textem, např. editačního pole (Edit), poznámky (Memo), rozšířené poznámky (RichEdit). Kromě toho je ale můžeme využívat u některých databázových komponent pracujících s obrázky (např. DBImage).
V některém z předchozích dílů seriálu jsme se již zmínili o tom, jak se tyto metody používají: nemají žádný parametr, pouze se zavolají u komponenty, jejíž obsah chceme vložit do schránky (případně do níž chceme text ze schránky umístit). Tyto metody jsou totiž natolik „inteligentní“, že je-li nějaká část objektu (např. textu) označena, umístí do schránky tuto označenou část, v opačném případě neumístí do schránky nic. Byl-li před zavoláním některé této metody ve schránce nějaký údaj, je samozřejmě přepsán údajem novým, nicméně zavolá-li se některá z těchto metod, aniž byl označen text, nedojde k vymazání schránky.
Nyní si ukážeme aplikaci pracující se schránkou pomocí těchto velmi jednoduchých metod.
Na hlavním formuláři (frmHlavni) je komponenta Memo (memoHlavni) a čtyři tlačítka: btnKopiruj, btnVystrihni, btnVloz, btnKonec). Každé z tlačítek demonstruje jednu metodu, poslední slouží k ukončení aplikace.
Zdrojové kódy aplikace:
unit Hlavni;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
StdCtrls;
type
TfrmHlavni = class(TForm)
memoHlavni: TMemo;
btnKopiruj: TButton;
btnVystrihni: TButton;
btnVloz: TButton;
btnKonec: TButton;
procedure FormCreate(Sender: TObject);
procedure btnKopirujClick(Sender: TObject);
procedure btnVystrihniClick(Sender: TObject);
procedure btnVlozClick(Sender: TObject);
procedure btnKonecClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
frmHlavni: TfrmHlavni;
implementation
{$R *.DFM}
procedure TfrmHlavni.FormCreate(Sender: TObject);
begin
frmHlavni.Caption := `Aplikace demonstrující práci se schránkou`;
memoHlavni.Lines.Clear;
btnKopiruj.Caption := `K&opíruj`;
btnVystrihni.Caption := `&Vystřihni`;
btnVloz.Caption := `V&lož`;
btnKonec.Caption := `&Konec`;
end;
procedure TfrmHlavni.btnKopirujClick(Sender: TObject);
begin
memoHlavni.CopyToClipboard;
memoHlavni.SetFocus;
end;
procedure TfrmHlavni.btnVystrihniClick(Sender: TObject);
begin
memoHlavni.CutToClipboard;
memoHlavni.SetFocus;
end;
procedure TfrmHlavni.btnVlozClick(Sender: TObject);
begin
memoHlavni.PasteFromClipboard;
memoHlavni.SetFocus;
end;
procedure TfrmHlavni.btnKonecClick(Sender: TObject);
begin
Application.Terminate;
end;
end.
Poznámka: divíte-li se, k čemu v obsluze každé události voláme metodu SetFocus, pak vězte, že je to proto, aby komponenta Memo dostala hned po stisku některého tlačítka zaměření (tedy aby se do ní přesunul kurzor).
Obtížnější operace se schránkou v Delphi
Ovšem nejen těmito triviálními akcemi musí se zabývati programátor. Občas je třeba umístit do schránky třeba obyčejný obrázek nebo jiný typ dat (viz tabulka v jedné z předchozích podkapitol). V takovém případě je nutné přistupovat ke schránce pomocí třídy TClipboard.
Třída TClipboard zapouzdřuje schránku Windows. Není doporučeno vytvářet vlastní objekty (instance) této třídy (voláním konstruktoru Create). Je vhodné použít globální instanci, kterou vrací funkce Clipboard. Funkce Clipboard sama vrátí objekt třídy TClipboard, takže nemusíme nijak explicitně schránku vytvářet. Za týden uvidíte, že práce s touto funkcí je velmi intuitivní, např. pokud chcete vložit do schránky obrázek uložený v komponentě Image, napíšete
Clipboard.Assign(Image.Picture);
Použitím funkce Clipboard (a tím třídy TClipboard) umožníme aplikacím sdílet jednu instanci (jeden jediný výskyt) objektu Clipboard. Důležité je, že v tomto případě je schránka „zabezpečena“ proti náhodnému (nechtěnému) vymazání dat, ke kterému by mohlo dojít, kdyby se v systému zároveň vyskytovalo „více schránek“.
Důležité upozornění: Předtím, než můžeme zavolat funkci Clipboard, je nutné do sekce uses v modulu přidat jednotku Clipbrd.
Za týden budeme pokračovat v popisu práce s třídou TClipboard. Popíšeme si vlastnosti a metody této třídy (události žádné nemá). Ukážeme si také konkrétní problémy a způsob jejich řešení.