Friday, August 31, 2007

Za jednu z nejvážnějších jsem tehdy označil chybu v komponentě ListView, kdy při použití stylu vsReport a nedefinování hlavičky jednotlivých sloupců (nebo i jednoho sloupce) se při spuštění aplikace pod Windows XP okamžitě zhroutí. Jak z toho tedy ven? Aktualizace vydané Borlandem bohužel věc neřeší, takže si v tomto konkrétním případě pomůžeme sami úpravou knihovny Comctrls, jejíž zdrojový kód (tedy soubor comctrls.pas) byste měli najít ve složce {Delphi}\Source\Vcl.

Labels:

Thursday, August 30, 2007

Úprava knihovny Comctrls pro použití ve Windows XP

Před časem jsme se zabývali použitím vizuálních stylů ve Windows XP. Jistě si vzpomenete na jednoduchý postup, kterým jsme použití stylů do aplikace zakomponovali prostřednictvím souboru manifestu. Možná si také vzpomenete, že tato poměrně jednoduchá akce ale nebyla nakonec úplně bez komplikací, protože VCL knihovna Delphi obsahuje několik chyb, které se za určitých okolností projeví pádem aplikace pod Windows XP.

Labels: ,

Tuesday, August 28, 2007

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".

Labels:

Sunday, August 26, 2007

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;

Labels:

Saturday, August 25, 2007

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;

Labels:

Wednesday, August 22, 2007

načítání

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;

Labels:

čtení záznamů

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).

Labels:

Tuesday, August 21, 2007

INI

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.

Labels:

Sunday, August 19, 2007

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;

Labels:

Č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.

Labels:

Thursday, August 16, 2007

INI

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ý.

Labels:

Tuesday, August 14, 2007

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.

Sunday, August 12, 2007

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.

Labels:

TransparentColor

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í.

Labels:

Friday, August 10, 2007

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.

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í).

Labels:

Wednesday, August 08, 2007

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.

Labels:

Monday, August 06, 2007

procedure

CopyFileWithProgressBar(Source, Destination : string);
var
FromF,
ToF : file of byte;
Buffer : array[0..4096] of char;
NumRead : integer;
FileLength : longint;
begin
AssignFile(FromF,Source);
reset(FromF);
AssignFile(ToF,Destination);
rewrite(ToF);
FileLength:=FileSize(FromF);
with Form1.Progressbar1 do
begin
Min := 0;
Max := FileLength;
while FileLength > 0 do
begin
BlockRead(FromF,Buffer[0],SizeOf(Buffer),NumRead);
FileLength := FileLength - NumRead;
BlockWrite(ToF,Buffer[0],NumRead);
Position := Position + NumRead;
Application.ProcessMessages;
end;
CloseFile(FromF);
CloseFile(ToF);
end;
end;

procedure TForm1.Button16Click(Sender: TObject);
begin
CopyFileWithProgressBar('c:\zdroj.exe','c:\cíl.exe');
end;
Jak vidíte, princip je velmi jednoduchý a snadno pochopitelný. Samozřejmě je nutné, aby byla formuláři umístěna komponenta ProgressBar.

Labels:

Saturday, August 04, 2007

Kopírování souboru se zobrazením průběhu

Chcete si vytvořit vlastní souborový manažer ? Pak se vám možná bude hodit tento tip, ve kterém si ukážeme kopírování souborů s ukazatelem průběhu celé akce. O stupínek výš bychom se s naším příkladem dostali, pokud by kopírování probíhalo v samostatném vlákně na pozadí, ale to poněkud přesahuje prostorové možnosti tohoto dílu seriálu. Takže nám opět pomůže obvyklé Application.ProcessMessages, aby nedošlo k "zamrznutí" aplikace po dobu kopírování.

Thursday, August 02, 2007

Zmizení kurzoru myši

Velice krátký a jednoduchý tip. Zmizení kurzoru myši docílíme takto:
ShowCursor(false);
a jeho opětovné zobrazení celkem logicky takto:
ShowCursor(true);
Je třeba něco dodávat ? Myslím, že určitě ne. Využití tohoto tipu nechám na vás.

Labels:

Wednesday, August 01, 2007

procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.BeginUpdate;
Memo1.Lines.Clear;
ListComponentProperties(Button1, Memo1.Lines);
Memo1.Lines.EndUpdate;
end;
Nejdůležitějším parametrem je pochopitelně komponenta, jejíž vlastnosti chceme zjistit (v naší ukázce je to Button1).

Labels: