3.2//EN"> HTML Doc made using TxtToHTML v1.7 Copyright (c) 2001-2003 ssnakesoft Nazdar všichni!

Tak po delší odmlce, kterou způsobyl nákup mého Pegasose jsem opět zde, a píšu v pořadí již pátý tutoriál. Už ne na Amize, nýbrž na Pegasosovy, ale nemyslim, že byste to poznali :) Po shlédnutí konce minulého tutoriálu jsem zjistil, že jsem na sebe ušil pěknou boudu, protože musím popsat soubory a requestery. No co, hurá do toho, a půl je hotovo ;)
Soubory:

Jak začít. Soubory jistě každý z vás zná, takže jen pro úplnost doplním, že v podstatě jsou dva typy souborů, binární, a textový. Textový je obvikle dělaný tak, aby si v něm mohl člověk číst, a binární tak, aby si v něm mohl číst zase počítač. Záleží jen na vás, co vám bude víc vyhovovat ve vašich programech. Binární soubory se obvikle zpracovávají mnohem rychleji, a snáze, než soubory textové, ale to si všechno vysvětlíme později. Nejdřív si nejaký ten soubor musíme vytvořit. V PowerD k tomu není žádna funkce, protože se na to krásně hodí systémová funkce "Open" z dos.library. Ta má dva parametry, prvním je název souboru, a tím druhým je zpusob, jakým budeme k souboru přistupovat:
  DEF soubor
  soubor:=Open('ram:soubor',NEWFILE)

Z tohoto výpisu je zřejmé, že než si nejaký ten soubor vytvoříme, nebo otevřeme, musíme pro něj mít nějakou tu proměnnou, v tomto případě je to proměnná "soubor". Hned potom můžeme soubor otevřít, či vytvořit. V příkladě se otevírá soubor jménem 'ram:soubor', a přistupujeme do něj jako do nového souboru (NEWFILE), což znamená, že se ten soubor vytvoří! Pokud již soubor stejného jména existuje, bude nemilosrdně přepsán. Pokud chcete otevřít již existující soubor, stačí místo konstanty NEWFILE použít konstantu OLDFILE, která se pokusí soubor s daným názvem otevřít pro čtení. Takže NEWFILE se používá pro zápis souboru na disk, a OLDFILE se používá pro čtení souboru z disku. Po pokusu o otevření/vytvoření souboru je nutné otestovat, jestli se soubor opravdu povedlo otevřít/vytvořit. Protože takový soubor nemusí být na disku, nebo se můžete pokoušet zapsat soubor na disk, který je chráněn proti zápisu atd. Takže:
  IF soubor<>NIL

to za nás udělá. Dojde-li totiž k chybě, vrací funkce Open nulu, neboli konstantu NIL. Takže pokud se soubor nerovná nule, můžeme s ním pracovat. K tomu nám slouží tři základní funkce, Read, Write a Seek. Přičemž funkce Read lze použít pouze při otevření souboru pomocí OLDFILE, a Write pouze při vytvoření souboru pomocí NEWFILE. Jedině funkce Seek se dá použít v obou případech. Funkce Write zapisuje data do souboru. Tato funkce má tři argumenty, první je vždy soubor, do kterého se zapisuje, druhý argument obsahuje data, která se musí zapsat, a třetí argument je počet bajtů, který se má z daných dat uložit. Pokud ukládáme text, je to počet znaků, které se uloží do souboru:
  Write(soubor,'Nazdar lidi!\n',STRLEN)

Tento příkaz zapíše do souboru daný text, ale pozor, musíte zadat správnou délku tohoto textu. To za vás částečně reší PowerD svou speciální konstantou STRLEN, která vždy obsahuje délku posledního použitého stringu, pokud použijete místo přímého zadávání textu proměnnou, tato konstanta již nefunguje, a musí se použít:
  Write(soubor,string,StrLen(string))

Kde string může obsahovat libovolný text, a takto bude uložen o celé své délce. Funkci Write můžeme používat úplně pro všechny způsoby zápisu, jak text, tak binární data. Protože ale tato funkce potřebuje "pole", ze kterého má zapsat určitý počet počet bajtů, nemůžeme použít proměnnou s číslem přímo, ale musíme použít jeho adresu:
  DEF cislo=1234
  Write(soubor,&cislo,4)

Tato funkce uloží do souboru binárně číslo 1234, které bude mít 4 bajty, neboli long. Funkci Write lze používat opakovaně dle potřeby. Jsou-li všechny zápisy do souboru hotové, musíme soubor zavřít. To uděláme následovně:
  Close(soubor)

Pokud soubor není správně uzavřen, nebude soubor přístupný ke čtení přinejmenším do resetu počítače, v horším případě (FFS) dojde po restartu k validaci disku, v lepším případě (SFS/PFS...) bude po resetu všechno v pořádku a v souboru bude zapsáno to, co jsme do něj zapsali, takže nezapomínejte za sebou soubor vždy zavírat. Toto všechno byly funkce, které lze provádět pouze v případě, že se nám povedlo soubor vytvořit, což nám zajišťuje řádek s "IF soubor<>NIL". Nyní, když jsme soubor zavřeli, musíme ještě ukončit tuto podmínku:
  ENDIF

Takže prográmek, který nám zapíše text do souboru vypadá asi takto:
PROC main()
  DEF soubor
  soubor:=Open('ram:soubor',NEWFILE)
  IF soubor<>NIL
    Write(soubor,'Nazdar lidi!',STRLEN)
    Close(soubor)
  ENDIF
ENDPROC

Pokud jde o čtení souboru, je použití velice podobné, jenom namísto konstanty NEWFILE použijeme konstantu OLDFILE. Hned po otevření souboru musí opět následovat test, jestli se opravdu povedlo soubor otevřít, pokud ne, nesmíme se pokoušet z něj číst, pokud ano, můžeme pokračovat, se čtením ze souboru je to krapet složitější, než se zápisem, protože je potřeba si hlídat mnohem víc věcí. Tak předem musíte vedět, kolik toho budete ze souboru vlastně načítat. Nejjednodušší cesta je, si do paměti načíst kompletní soubor, k tomu ale potřebujeme paměť, do které se nám celý soubor vejde. To se dá udělat v PowerD snadno použitím funkce FileLength, která vrací délku souboru v bajtech:
DEF len
len:=FileLength('ram:soubor')

Tato funkce bude zapíše do proměnné len délku souboru 'ram:soubor'. Pokud se soubor nepodaří otevřít, vrací zápornou hodnotu. Teď je na řadě si alokovat dostatek paměti, aby jsme do ní mohli soubor pěkně načíst k tomu slouží v PowerD funkce New:
DEF pamet:PTR TO BYTE
pamet:=New(len+1)

Tato funkce alokuje blok počítačové paměti o velikosti len+1. Pokud se alokace nezdaří (třeba kvůli nedostatku paměti), vrací funkce New nulu, naboli NIL, takže s alokovanou pamětí můžeme pracovat pouze v případě, že se alokace podařila:
IF pamet<>NIL

Takže nyní máme alokovanou paměť o správné délce, do které nyní můžeme načíst data ze souboru:
DEF nacteno
nacteno:=Read(soubor,pamet,len)
pamet[nacteno]:="\0"

Funkce Read přečte ze souboru "soubor" "len" bajtů, a uloží je do paměti, jejíž ukazatel jsme uložili do proměnné "pamet". Jistě jste si všimli, že to ještě není všechno, že je tam ještě jedna věc, a to je použití proměnné "nacteno", do které funkce Read uloží počet bajtů, které načetla ze souboru do paměti. Pokud je všechno v pořádku, musí se hodnoty "len" a "nacteno" rovnat, jestli ne, pravděpodobně je soubor kratší, než je udávaná délka pro načítání, nebo došlo k chybě při načítání z disku, zkrátka nebylo možné načíst všechny bajty, jak bylo zadáno. Pak ještě následuje ukončení stringu, protože funkce Read načte přesně ten počet bajtů, který jsme zadali, a tudíž není tento string korektně ukončen nulovým bajtem. To je také důvod, proč jsme alokovali len+1 bajtů, a ne jen len bajtů. Prostě jsme si udělali místo na tento nulový bajt. Takže poslední znak vynulujeme. Takže zadáme ještě jednu podmínku:
IF len=nacteno

A pokud je tato podmínka splněna, máme jistotu, že všechno klaplo, a v proměnné "pamet" máme kompletní obsah souboru "ram:soubor". A vzhledem k tomu, ze tento soubor obsahuje pouze text, který jsme tam zapsali minulým příkladem, můžeme si vz pekně vypsat:
PrintF('Soubor obsahuje text: "\s"\n',pamet)

Teď už zbývá jen korektně uzavřít všechny podmínky, a uvolnit pameť, kterou jsme si alokovali, to provedeme pomocí funkce Dispose, která je opakem funkce New, tedy že uvolní paměť, kterou jsme alokovaly. Ukazatel na tuto paměť musí být argumentem této funkce, a protože ukazatelem je právě proměnná "pamet", zadáme jako argument právě ji:
Dispose(pamet)

A nakonec ještě zavřít za sebou soubor, pomocí funkce Close, stejně, jako u zápisu do souboru a prográmek je hotov:
PROC main()
  DEF soubor
  soubor:=Open('ram:soubor',OLDFILE)
  IF soubor<>NIL
    DEF len
    len:=FileLength('ram:soubor')
    IF len>0
      DEF pamet:PTR TO BYTE
      pamet:=New(len+1)
      IF pamet<>NIL
        DEF nacteno
        nacteno:=Read(soubor,pamet,len)
        pamet[nacteno]:="\0"
        IF len=nacteno
          PrintF('Soubor obsahuje text: "\s"\n',pamet)
        ELSE PrintF('chyba pri nacitani souboru!\n')
        Dispose(pamet)
      ELSE PrintF('nedostatek pameti!\n')
    ENDIF
    Close(soubor)
  ELSE PrintF('soubor se nepovedlo otevrit!\n')
ENDPROC

Je vidět, že je to už krapet složitější, ale není v tom nic, co by se člověk nedočetl v dokumentaci k dos.library. Jestě jsem dodělal maličké vylepšení, které v případě, že nastane chyba vypíše chybové hlášení, to jsem udělal záměnou "ENDIF" za "ELSE", které je následováno funkcí, která se provede, není-li splněna podmínka "IF", k němuž "ENDIF" patřilo.


Requestery:

Další na řadě jsou requestery. To je jednoduché, ale nejdřív něco teorie pro ty, kteří nevědí o co jde. Requestery jsou informační okna, která obsahuji nejaký text, a obyčejně i volbu, kterou nám počítač dává na výber. V systému se s nimi setkáváte pořád, ale jak si takový requester vytvořit? To si pravě teď vysvětlíme. Ke všemu nám stačí jediná funkce EasyRequestArgs. Je to funkce intuitionu, takže se o nic nemusíte starat, protože PowerD si knihovnu intuition.library otevírá automaticky. Detailní informace o této knihovně se dozvíme v autodokumentaci k intuitionu.
  EasyRequestArgs(NIL,[20,0,'uff','bla bla','bezva'],NIL,NIL)

Tohle je v podstatě nejjednodušší requester, jaký si můžeme vytvořit. Při spuštění této funkce se otevře okno, které bude mít název 'uff', uvnitř bude zpráva 'bla bla', a dole bude tlačítko s nápisem 'bezva'. Docela jednoduché, že? Ale teď detailněji. První NIL, je argument okna, pokud totiž udete chtít otevřít requester na vlastní obrazovce, budete muset místo tohoto prvního NIL použít ukazatel, na okno dané obrazovky, jinak se otevře na Workbenchi. Pak následuje pole, které musí obsahovat pět položek. První dvě musí být pořád stejné, a to 20 a 0. Pokud vás tyto hodnoty zajímají blíže, podívejte se na autodokumentaci k této funkci. Další položkou v tomto poli je titul requesteru, dalším je text, který bude obsažen v těle okna, a poslední je seznam tlačítek, které v okně budou. Pak je tam další NIL, které vás také zatím nemusí zajímat, a poslední NIL, které by mělo obsahovat seznam arguemntů, které chceme použít v těle okna a v tlačítkách. Použití je stejné, jako u funkce PrintF. Co se týče textu, který bude obsažen v okně, lze používat znaky pro odřádkování, abyste se dostali na další řádek jako pomocí PrintF('\n'), takže:
  EasyRequestArgs(NIL,[20,0,'uff','ahoj\n\s','bezva'],NIL,['vole'])

Otevře requester s názvem "Uff", a okno bude obsahovat text o dvou řádcích, kde na prvním bude "ahoj", a na druhém bude "vole". Určitě si ale budete chtít vytvořit třeba requester s několika tlačítky. To se udělá velice snadno, místo textu 'bezva' použijete třeba 'bezva|nikdy', a hnedle bude mít okno dvě tlačítka, kde levé bude osahovat text "bezva", a pravé "nikdy":
  EasyRequestArgs(NIL,[20,0,'hlaska','chces pokracovat?','ano|ne'],NIL,NIL)

Tento příkaz otevře okno s názvem "hlaska", s textem "chces pokracovat?", a dá vám na výběr dvě možnosti, buď "ano", nebo "ne". Teď už zbývá jen rozlišit, jaké tlačítko jsme si zvolili, a podle toho pokračovat v programu:
  DEF volba
  volba:=EasyRequestArgs(NIL,[20,0,'hlaska','chces pokracovat?','ano|ne'],NIL,NIL)

Ano správně. Funkce EasyRequestArgs vrací hodnotu, a touto hodnotou je právě tlačítko, které jsme si zvolili. Ale pozor, první tlačítko vrací číslo 1, druhé tlačítko vrací číslo 2, atd, ale poslední tlačítko vrací číslo 0, takže pokud zvolíme "ano", bude proměnná "volba" obsahovat číslo 1, ale pokud zvolíme tlačítko "ne", bude proměnná "volba" obsahovat číslo 0.
PROC main()
  DEF volba
  volba:=EasyRequestArgs(NIL,[20,0,'hlaska','co chces?','pomerance|rajcata|svestky|nic'],NIL,NIL)
  SELECT volba
  CASE 1  PrintF('pomerance???\n')
  CASE 2  PrintF('proc rajcata?\n')
  CASE 3  PrintF('svestky jsou dobra volba ;)\n')
  CASE 0  PrintF('taky dobry...\n')
  ENDSELECT
ENDPROC

Tak. To by pro dnešek stačilo. Příště si konečně řekneme něco o polích, a uvítal bych, kdybyste se mi ozvali, a řekli mi, co by vás zajímalo, abych o tom něco mohl napsat. Můj email je mark@tbs-software.com.

Baj, MarK.