Živě.cz o počítačích a internetu

Tipy a triky v Delphi, díl 40. - Průhlednost oken v Delphi 6; Práce s INI soubory

Jan Šindelář - 15.5.2002

Průhlednost oken v Delphi 6

Moderní operační systémy se snaží nejen dobře fungovat, což se předpokládá jako samozřejmost (škoda, že tomu tak ne vždy je), ale snaží se též zaujmout svým vzhledem. Proto se i v nejnovější verzi Windows, tedy Windows XP, objevily vizuální styly. Kromě tohoto na první pohled viditelného rozdílu však Windows (a to dokonce už ve verzi 2000) obsahují ještě jeden zajímavý vizuální prvek, který se však v programech přesto příliš neobjevuje. Tímto prvkem je průhlednost oken. Od nové verze Delphi 6 se tato vlastnost oken již objevila v seznamu parametrů v Object Inspectoru, takže použití bude hračka.

O průhlednost okna, či přesněji řečeno průsvitnost, se starají 4 základní vlastnosti okna. Jsou to vlastnosti AlphaBlend, AlphaBlendValue, TransparentColor a TransparentColorValue. Hned si objasníme, co která vlastnost znamená, i když z názvů je to docela patrné.

AlphaBlend může nabývat hodnot True nebo False a určuje, zda chceme či nechceme průhlednost oken používat. Až tedy budete experimentovat, musíte nastavit hodnotu True, jinak se pochopitelně nedostanete dál. Když tímto způsobem průhlednost povolíme, druhý parametr AlphaBlendValue určuje číselnou hodnotu průhlednosti. Může nabývat hodnot od 0 do 255, přičemž 0 znamená zcela průhledné okno, zatímco 255 je přesný opak, tedy okno zcela neprůhledné (standardní).

Až si budete s těmito parametry hrát, jistě brzy zjistíte, že tento efekt sice může vypadat velmi zajímavě a hezky, ale někdy je problém s čitelností textu na takto poloprůhledném okně, neboť prosvítající podklad může vytvářet menší chaos, pokud obsahuje například text se stejným fontem a stejnou barvou podkladu. Je proto nutné šikovně zvolit úroveň průhlednosti a také barvy jednotlivých prvků na takovémto okně s ohledem na podklad. Rozhodně by nebylo příliš moudré využít této vlastnosti například pro okno textového editoru, protože prosvítající podklad by mohl dost značně zkomplikovat čitelnost textu. Naproti tomu je tato vlastnost ideální k vytvoření různých "About..." boxů a přímo dokonale se hodí k vytvoření "Spash screen". Možná znáte oblíbený grafický benchmark 3D Mark, který po svém spuštění zobrazí obvyklý splashscreen, navíc s efektem postupného objevování. Přesně tento efekt si můžete vytvořit ve svých aplikacích také, právě s využitím průhlednosti okna. Jak vytvořit splashscreen jsme si již v našem seriálu říkali a efekt postupného objevování či mizení vytvoříte snadno tím, že budete postupně měnit hodnotu vlastnosti AlphaBlendValue, protože je to vlastnost, která se dá pochopitelně měnit přímo za běhu aplikace. Tohoto efektu se dá využít prakticky u všech oken aplikace, jenom je třeba si dát pozor, aby ono objevování či mizení netrvalo příliš dlouho a nezdržovalo.

A dostáváme se k vlastnostem TransparentColor a TransparentColorValue. První z nich je opět logická proměnná nabývající hodnot True nebo False. Zapíná nebo vypíná průhlednost barvy, kterou definuje vlastnost TransparentColorValue. Budete-li tedy chtít, aby nějaká konkrétní barva nebyla vůbec vidět, tedy přesněji řečeno byla průhledná a místo ní se zobrazovalo pozadí okna (to, co je pod oknem), tímto parametrem toho dosáhnete. Snadno tak můžete vytvořit na formuláři "díry", i když v tomto případě mě nenapadá nějaké rozumné využití.

Co říci na závěr? Že každá legrace něco stojí. V tomto případě je to výkon počítače. Pokud totiž máte zastaralejší hardware, nemusí být překreslování těchto poloprůhledných oken právě nejrychlejší, obzvlášť pokud máte zapnutou vlastnost "Zobrazovat obsah okna během přetahování". Další nevýhodou je to, že tento efekt bude viditelný pouze ve Windows 2000 a XP, ale na druhou stranu si nemusíte dělat starosti s nefunkčností aplikace pod staršími Windows 9x, protože zde bude váš program bez problémů také pracovat. Pouze bude ignorována vlastnost průhlednosti oken a ta budou zobrazena standardním způsobem. A poslední problém? Nutnost mít Delphi 6 (tedy šlo by to i bez nich, ale složitějším způsobem než pouhým nastavováním vlastností v Object Inspectoru), verzi Personal si však můžete zdarma stáhnout přímo od Borlandu.

Práce s INI soubory

Jistě mi dáte za pravdu, že každá i jen malinko rozsáhlejší aplikace tu a tam potřebuje uložit nějaká data na disk. Typicky to mohou být různá uživatelská nastavení, stavové informace o programu (jako je poloha okna, naposledy otevřený adresář atd..) a řada dalších informací nutných pro běh aplikace. S příchodem Windows 95 se zpočátku s nadšením upustilo od INI souborů, ve kterých byly podobné informace uloženy, a všichni se vrhli na registry. Logickým argumentem bylo kromě jiného i to, že v dobách starých Windows se v jejich adresáři často hromadilo velké množství nepotřebných INI souborů od již dávno odinstalovaných aplikací. Bohužel se brzy zjistilo, že se tento problém se zapomenutými či špatně odinstalovanými daty přechodem na registry moc neodstranil, pouze se přesunul na jiné místo a přeplněné a nepřehledné registry máme v našich systémech zřejmě všichni.

Proto si myslím, že není třeba INI soubory ještě zcela zatracovat. Ukážeme si, co nám mohou pro pohodlnou práci s nimi nabídnout Delphi. Všechny důležité funkce se skrývají v knihovně IniFiles, takže ji přidejte do projektu. Nevím, jestli to není zbytečné, ale možná bychom se měli nejprve přece jen alespoň krátce zmínit, jak takový INI soubor vlastně vypadá. Jedná se o obyčejný textový soubor, a když si nějaký prohlédnete, zjistíte, že je rozdělen na určité sekce. Každá je označena svým názvem uvedeným v hranatých závorkách. Těsně za tímto názvem sekce následují jednotlivé řádky, kde je vždy uveden název parametru a za rovnítkem jeho hodnota. Formát je to tedy velmi jednoduchý, přehledný a snadno (i ručně) editovatelný.

Čistě teoreticky bychom mohli se souborem zacházet jako s každým jiným textovým souborem a se znalostí jeho formátu s ním pracovat. Bylo by to však poněkud nepohodlné, takže proč nevyužít standardní funkce Delphi. Jaké funkce tedy budeme potřebovat ? Předně budeme chtít soubor vytvořit a zapisovat do něj hodnoty. Takto zapsané hodnoty budeme poté chtít celkem logicky také číst, případně mazat a editovat. Ukažme si tedy postupně jednotlivé funkce.

Vytvoření nového INI souboru a zároveň zapsání položky obstará funkce WriteString. Její použití si hned ukážeme na příkladu:

procedure TForm1.Button1Click(Sender: TObject);
var
INISoubor: TIniFile;
begin
INISoubor := TIniFile.Create(`c:\pokus.ini`);
INISoubor.WriteString(`První sekce`, `Jméno položky`, `hodnota`);
INISoubor.WriteString(`Další sekce`, `Jméno položky`, `hodnota`);
INISoubor.Free;
end;

Tento jednoduchý příklad vytvoří INI soubor s názvem pokus.ini a vytvoří v něm dvě sekce. Každá z těchto sekcí bude obsahovat pouze jednu položku s hodnotou hodnota. Budete-li chtít již do existujícího INI souboru přidat další sekce a hodnoty, použijete přesně stejný postup. Existující soubor (ani položky v něm) nebude přepsán, ale nová data se přidají k ostatním. Pochopitelně nemůže dojít k duplicitě záznamů, neboť každý je jednoznačně identifikovatelný svým názvem a sekcí, ve které se nachází, a funkce si to sama pohlídá. Budete-li přidávat záznam do již existující sekce, automaticky se přidá na správné místo v souboru na konec dané sekce.

Dalším krokem je čtení záznamů z již vytvořeného INI souboru. Je to opět velmi snadné, jak ukazuje následující příklad:

procedure TForm1.Button2Click(Sender: TObject);
var
INISoubor: TIniFile;
st:string;
begin
INISoubor := TIniFile.Create(`c:\pokus.ini`);
st := INISoubor.ReadString(`První sekce`, `Jméno položky`, `Default`);
INISoubor.Free;
ShowMessage(st);
end;

Funkce ReadString se pokusí v daném souboru najít příslušnou sekci a zjistit hodnotu požadované položky. V případě problémů (například nelze najít požadovanou sekci, položku či hodnotu) se vrací hodnota, kterou nastavíte jako implicitní (v našem případě hodnota Default).

Protože by načítání dat po jednotlivých položkách mohlo v případě delších "seznamů" poněkud zdržovat, dá se využít funkce ReadSectionValues, která najednou načte všechny položky dané sekce a výsledek uloží do nějakého seznamu řetězců (např. do ListBoxu, Memo atd..).

procedure TForm1.Button3Click(Sender: TObject);
var
INISoubor: TIniFile;
begin
INISoubor := TIniFile.Create(`c:\pokus.ini`);
INISoubor.ReadSectionValues(`První sekce`, ListBox1.Items);
INISoubor.Free;
end;

Podobným způsobem se dají též získat najednou samotné názvy všech sekcí. To zařídí funkce ReadSections. Příklad je velmi podobný tomu předchozímu:

procedure TForm1.Button4Click(Sender: TObject);
var
INISoubor: TIniFile;
begin
INISoubor := TIniFile.Create(`c:\pokus.ini`);
INISoubor.ReadSections(ListBox1.Items);
INISoubor.Free;
end;

Zbývá nám naučit se, jak jednotlivé sekce či položky z INI souboru vymazat. Potřebujete-li hromadně smazat celou jednu sekci včetně všech jejích položek a hodnot, slouží k tomuto účelu funkce EraseSection. Ta danou sekci se souboru vymaže a soubor hezky upraví tak, aby mezi jednotlivými sekcemi byl opět vždy jeden prázdný řádek a nevznikaly nějaké mezery navíc. Pokud se pokusíte smazat neexistující sekci, nic se nestane. Nic se pochopitelně nesmaže, ale tento pokus nevyvolá ani chybu v programu. Obdobně "čistě" se chovají i ostatní již zmíněné funkce. Zde je tedy příklad:

procedure TForm1.Button5Click(Sender: TObject);
var
INISoubor: TIniFile;
begin
INISoubor := TIniFile.Create(`c:\pokus.ini`);
INISoubor.EraseSection(`První sekce`);
INISoubor.Free;
end;

A na závěr nám zůstává mazání jednotlivých položek, což bude asi mnohem častější činnost než mazání celých sekcí. Dá se celkem snadno předpokládat, že funkce bude mít dva parametry – sekci a položku, kterou chceme mazat. Jedná se o funkci DeleteKey a příklad máte zde:

procedure TForm1.Button6Click(Sender: TObject);
var
INISoubor: TIniFile;
begin
INISoubor := TIniFile.Create(`c:\pokus.ini`);
INISoubor.DeleteKey(`První sekce`,`Polozka5`);
INISoubor.Free;
end;

Jak vidíte, práce s INI soubory je velmi jednoduchá, připravené funkce v Delphi zvládají všechny hlavní činnosti a jejich použití je bezproblémové. Neváhejte tedy a zkuste někdy místo registrů ukládat aplikační data do INI souboru. Uvidíte, že to není zase až tak zastaralá "technologie".