26.11.2002
|
čo sa budeme dnes učiť
- ovládanie programu pomocou klávesnice,
napr. klávesov šípok
- otvorenie ďalšieho formulára
Klávesnica
s klávesnicou pracujeme pomocou troch udalostí:
- onKeyDown - práve bol zatlačený
nejaký kláves
- onKeyUp - práve bol pustený nejaký
kláves
- onKeyPress - stlačili sme "obyčajný"
kláves (ktorý má svoj ASCII
kód)
prvé dve udalosti oznámia nie ASCII
kód klávesu ale "virtuálny
kód" (v Helpe si pozrite identifikátory
konštánt) a tiež v parametri Shift zistíme,
či bol pri tom zatlačený napr. Shift alebo Ctrl
(podobne ako pri udalostiach pri práci s myšou)
nasledujúci program ukáže použitie
klávesnice - do formulára umiestnime
komponenty Label1 a Timer1 (nastavíme mu nejaký
krátky Interval) - teraz môžeme na klávesnici
súčasne tlačiť aj viac šípok a tým
riadiť pohyb textu po ploche formulára:
pohyb textu vo formulári:
|
var
dx,dy:integer; // môžeme predpokladať, že sú inicializované na 0
procedure TForm1.Timer1Timer(Sender: TObject);
begin
with Label1 do begin
Left:=Left+dx;
// nedá sa urobiť inc(Left,dx); lebo Left nie je premenná
Top:=Top+dy;
end;
end;
procedure TForm1.FormKeyDown(Sender:TObject; var Key:Word;
Shift:TShiftState);
begin
case Key of
vk_left: dx:=-1;
vk_right: dx:=1;
vk_up: dy:=-1;
vk_down: dy:=1;
vk_escape: Close;
end;
end;
procedure TForm1.FormKeyUp(Sender:TObject; var Key:Word;
Shift:TShiftState);
begin
case Key of
vk_left,
vk_right: dx:=0;
vk_up,
vk_down: dy:=0;
end;
end;
|
- pri práci s klávesnicou si treba dávať
pozor na iné komponenty, ktoré "kradnú"
informácie z klávesnice (napr. Memo, Button,
Edit a pod.) - najjednoduchšie riešenie v prípade,
že chceme pracovať s klávesnicou, je ich nepoužívať,
alebo spracovávať vstup z klávesnice
na týchto komponentoch...
Príklad
- text zadávaný z klávesnice
vypisujeme do grafickej plochy Image1, Enter
posunie kurzor o riadok nižšie -
príklad ilustruje použitie onKeyPress
prvá jednoduchá verzia:
|
var
x,y:integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
x:=20; y:=20;
with Image1.Canvas.Font do begin
Name:='Arial'; Height:=50; Style:=[fsBold];
end;
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if Key>=' ' then begin
Image1.Canvas.TextOut(x,y,Key);
inc(x,20);
end
else if Key=#13 then begin
x:=20; inc(y,50);
end;
end;
|
- druhá verzia ukazuje, ako môžeme
zobrazovať textový kurzor, zároveň
používa metódu TextExtend,
pomocou ktorej zistí šírku a výšku
vypisovaného znaku
druhá verzia - proporčné písmo
a kurzor:
|
var
x,y:integer;
procedure TForm1.FormCreate(Sender: TObject);
begin
DoubleBuffered:=true;
x:=20; y:=20;
with Image1.Canvas, Font do begin
Name:='Arial'; Height:=50; Style:=[fsBold];
MoveTo(x,y); LineTo(x,y+Height);
end;
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
var
s:TSize;
begin
with Image1.Canvas do begin // zmaže kurzor
Pen.Color:=clWhite;
MoveTo(x,y); LineTo(x,y+Font.Height);
end;
if Key>=' ' then with Image1.Canvas do begin
TextOut(x,y,Key);
s:=TextExtent(Key); inc(x,s.cx);
if x>Image1.Width-20 then Key:=#13;
end;
if Key=#13 then begin
s:=Image1.Canvas.TextExtent('M');
x:=20; inc(y,s.cy);
end;
with Image1.Canvas do begin // nakreslí kurzor
Pen.Color:=clBlack;
MoveTo(x,y); LineTo(x,y+Font.Height);
end;
end;
|
NDÚ
- zrealizujte kláves Backspace - treba
si pamätať každý zapísaný
znak (v niečom podobnom ako zásobník)
- aby sme ho mohli zmazať, treba vedieť jeho pozíciu
a buď jeho hodnotu alebo veľkosť
Príklad
- v ďalšom príklade riadime šípkami
viac korytnačiek - len jedna z nich je aktívna,
Enter prepína aktívnosť na nasledujúcu
korytnačku
viac korytnačiek:
|
var
k:TVelaKor;
akt:integer = 0;
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
randomize; zmaz;
k:=TVelaKor.Create;
for i:=1 to 10+random(10) do
k.UrobKor(random(sirka-100)+50,random(vyska-100)+50);
k.HP:=6;
k.k[akt].FP:=clRed;
k.Dopredu(0);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
k.Free;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
case Key of
vk_left: k.k[akt].Vlavo(90);
vk_right: k.k[akt].Vpravo(90);
vk_up: with k.k[akt] do begin
FP:=clBlack; Dopredu(10); FP:=clRed; Dopredu(0);
end;
vk_return: begin
with k.k[akt] do begin FP:=clBlack; Dopredu(0); end;
akt:=(akt+1) mod k.pk;
with k.k[akt] do begin FP:=clRed; Dopredu(0); end;
end;
end;
end;
|
- druhá verzia "vizualizuje"
aktívnu korytnačku a jej momentálny
smer
- využívame tu pomocnú bitmapu na
zapamätanie si stavu plochy tesne pred vykreslením
červenej šípky
- zároveň s ovládaním klávesnice
beží časovač, ktorý hýbe aktívnu
korytnačku po malých krokoch
viac korytnačiek:
|
var
k:TVelaKor;
akt:integer;
bmp:TBitmap;
procedure kresliAktivnu;
begin
bmp.Assign(Form1.Image1.Picture);
with k.k[akt] do begin
FP:=clRed; Dopredu(10);
HP:=7; Dopredu(0);
HP:=4; Dopredu(-10);
FP:=clBlack;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
randomize; zmaz;
k:=TVelaKor.Create;
for i:=1 to 10+random(10) do
k.UrobKor(random(sirka-100)+50,random(vyska-100)+50);
k.HP:=4;
k.Dopredu(0);
bmp:=TBitmap.Create;
kresliAktivnu;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
k.Free; bmp.Free;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Image1.Canvas.Draw(0,0,bmp);
case Key of
vk_left: k.k[akt].Vlavo(90);
vk_right: k.k[akt].Vpravo(90);
vk_up: k.k[akt]. Dopredu(10);
vk_return: akt:=(akt+1) mod k.pk;
vk_escape: Close;
end;
kresliAktivnu;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Image1.Canvas.Draw(0,0,bmp);
with k.k[akt] do begin
Dopredu(1); Vlavo(1);
end;
kresliAktivnu;
end;
|
Príklad
- v príklade zadefinujeme jednoduchý
objekt s bitmapou, ktorý sa potom hýbe
niektorým smerom a odráža sa od okrajov
plochy - smer sa určuje klávesmi šípok
definovanie
jednoduchého objektu s bitmapou:
|
type
TObrazok = class
bmp:TBitmap;
x,y,dx,dy:integer;
constructor Create(meno:string; xx,yy:integer);
destructor Destroy; override;
procedure posun(sir,vys:integer);
procedure kresli(c:TCanvas);
end;
constructor TObrazok.Create(meno:string; xx,yy:integer);
begin
bmp:=TBitmap.Create;
bmp.LoadFromFile(meno);
bmp.TransparentColor:=clWhite;
bmp.Transparent:=true;
x:=xx; y:=yy; dx:=0; dy:=0;
end;
destructor TObrazok.Destroy;
begin
bmp.Free;
end;
procedure TObrazok.posun(sir,vys:integer);
begin
inc(x,dx); inc(y,dy);
if (x<0) or (x>sir) then dx:=-dx;
if (y<0) or (y>vys) then dy:=-dy;
end;
procedure TObrazok.kresli(c:TCanvas);
begin
c.Draw(x-bmp.Width div 2,y-bmp.Height div 2,bmp);
end;
|
práca s obrázkovým objektom
a s klávesnicou:
|
var
a:TObrazok;
procedure TForm1.FormCreate(Sender: TObject);
begin
randomize;
a:=TObrazok.Create('opica.bmp',
random(Image1.Width),random(Image1.Height));
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Image1.Canvas.FillRect(Image1.ClientRect);
a.posun(Image1.Width,Image1.Height);
a.kresli(Image1.Canvas);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
a.Free;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
with a do
case Key of
vk_left: dec(dx);
vk_right: inc(dx);
vk_up: dec(dy);
vk_down: inc(dy);
vk_home:
begin
dx:=0; dy:=0;
end;
end;
end;
|
môžeme experimentovať s odrážaním
objektu na hranici plochy:
|
procedure TObrazok.posun(sir,vys:integer);
begin
inc(x,dx); inc(y,dy);
if x<0 then begin dx:=abs(dx) div 2; x:=0; end;
if x>sir then begin dx:=-abs(dx) div 2; x:=sir-1; end;
if y<0 then begin dy:=abs(dy) div 2; y:=0; end;
if y>vys then begin dy:=-abs(dy) div 2; y:=vys-1; end;
end;
|
Otvorenie ďalšieho formulára
- v našej aplikácii môžeme pracovať
aj s viacerými formulármi:
- niekedy sa nám môže hodiť pre
ďalšie výpisy, grafiku, ako dialógové
okno pre zadávanie parametrov a pod.
(takýto formulár môže fungovať
- byť otvorený paralelne s hlavným
formulárom),
- inokedy potrebujeme otvoriť nový
formulár tak, aby bol hlavný formulár
zatiaľ blokovaný a čakalo sa, kým
sa tento nový nezavrie, napr. pre informácie
o programe
- v menu File zvolíme New a Form - automaticky
sa vytvorí nový unit (Unit2.pas) - do
tohoto nového formulára môžeme
poukladať ľubovoľné komponenty, napr. text
pomocou Label1, alebo tlačidlo Button1 s textom
Ok
do Button1Click
môžeme priradiť napríklad Close - uzavretie
formulára:
|
procedure TForm2.Button1Click(Sender: TObject);
begin
Close;
end;
|
- aby sme tento nový formulár mohli
otvoriť z hlavného okna, musíme za
Implementation vložiť riadok uses Unit2;
a napr. na nejaké tlačidlo priradiť otvorenie
formulára:
napr.
|
procedure TForm1.Button1Click(Sender: TObject);
begin
Form2.ShowModal; // alebo Form2.Show;
end;
|
- ShowModal znamená, že sa nové
okno otvorí tak, že sa čaká na jeho
uzavretie - až potom sa pokračuje v hlavnom formulári
- ak by sme namiesto toho použili Show,
tak by sa druhé okno otvorilo a boli by aktívne
obe: hlavné aj toto nové
skonštruovanie nového formulára
- nový formulár (napr. okno s informáciami
o programe) môžeme vytvoriť aj priamo v programe,
napr.
napr.:
|
procedure TForm1.Button1Click(Sender: TObject);
var
f:TForm;
begin
if Shift=[ssRight] then begin
f:=TForm.Create(self);
with f do begin
Name := 'mojformular';
Caption := 'O programe';
Width := 350;
Height := 253;
BorderStyle := bsSingle;
Position := poScreenCenter;
with TLabel.Create(f) do begin
Name := 'Label';
Parent := f;
Font.Height := 24;
Font.Name := 'Arial';
Caption := 'Niečo o mojom programe:'#13#13+
'je to ukážkový program'#13+
'na prácu s rôznymi komponentmi';
Left := 20;
Top := 16;
AutoSize:=true;
end;
with TButton.Create(f) do begin
Name := 'Ok';
Parent := f;
Caption := 'Ok';
Left := 72;
Top := 192;
Width := 75;
Height := 25;
ModalResult := mrOK;
end;
ShowModal; // zobrazí nový formulár a čaká na jeho zatvorenie
Free; // zruší nový formulár
end;
end;
end;
|
Poznámka
- ak v prostredí Delphi pri vytváraní
formulára zvolíme cez pravoklikové
menu "View as Text", zobrazí sa
textová forma definícií komponentov
na formulári - toto môžeme využiť pri
konštruovaní formulára, resp. komponentov
v našom programe
|