|
ApEl - Bed°ich HavlφΦek Lu₧ice 23, 785 01 èternberk tel/fax 0643 - 411917 liwin@liwin.cz |
Pyrotechnikem
snadno a rychle
aneb Ud∞lej si sßm...
Strßnka je dost bohatß
obsahem.
Vzhledem k v²Üi telefonnφch poplatk∙ doporuΦuji stßhnout a
prostudovat Offline.
A za v²Üi telefonnφch poplatk∙ doporuΦuji stßhnout
za₧iva... vÜak vφte koho.
Nebudu vßm radit, jak vyrßb∞t
semtex, jak mφchat Molotovovy koktejly, nebo jak foukat
do bublifuku, aby bubliny byly co nejv∞tÜφ,
nejnatlakovan∞jÜφ a s maximßlnφ explozivnφ silou. Dßm vßm jen pßr tip∙, jak zu₧itkovat poΦφtaΦ trochu jinak ( a lΘpe ), a taky jak dßt sv²m bli₧nφm najevo svou nßklonnost - pravda, trochu neobvykl²m zp∙sobem, ale lΘpe neobvykle, ne₧ v∙bec. A hlavn∞ snad koneΦn∞ pohnu nßvÜt∞vnφky naÜich strßnek a probudφm je z jejich letargie -v₧dy¥ za dlouhΘ dva m∞sφce existence prachßrny nep°iÜel ₧ßdn² p°φsp∞vek, nßpad, nebo alespo≥ litßnie rozho°ΦenΘho posti₧enΘho. Jako by lidovß tvo°ivost na tomto poli snad ani neexistovala. |
Princip atentßtu - °eΦeno s klasikem - je
jednoduch² jako Kolumbovo vejce .
Stejn∞ tak princip bomby je prost jak²chkoli obtφ₧nostφ a
zßludnostφ - alespo≥ co se softwarov²ch bomb t²Φe, i kdy₧
°ekl bych, ₧e to platφ obecn∞.
PopφÜeme si zde jeden typ bomby - ten nejjednoduÜÜφ,
nejmΘn∞ nebezpeΦn², ale souΦasn∞ mnohotvßrn² a pom∞rn∞
·Φinn².
Bombu samotnou m∙₧eme rozd∞lit do t°φ zßkladnφch Φßstφ:
Vytvo°it bombu v LiWin je snadnΘ. VÜak taky prvnφ naÜe bomby vznikly za ·Φelem propagace tohoto programovacφho prost°edku.
╚asovaΦ
Prvnφ pot°ebnou ingredienci - ΦasovaΦ - mßme k dispozici v
ka₧dΘm objektu. Vlo₧φme si tedy do aplikace n∞jak² objekt,
nejlΘpe univerzßlnφ vizußlnφ objekt - to kdybychom cht∞li
do ΦasovaΦe doplnit n∞jakΘ funkce, t°eba nastavovßnφ
pomocφ vlo₧en²ch °φdφcφch prvk∙. Objekt nazveme t°eba
Timer.
SpuÜt∞nφ ΦasovaΦe je jednoduchΘ:
Timer_Start( Elapse, Count);
kde Elapse udßvß Φasov²
interval jednotliv²ch tik∙, Count pak poΦet tik∙, po kterΘm
je Φinnost ΦasovaΦe ukonΦena. Interval standartn∞
nastavujeme na 1sekundu, tak₧e jako Count pak staΦφ zadat
po₧adovanΘ zpo₧d∞nφ v sekundßch.
SpuÜt∞n² ΦasovaΦ pak v pravideln²ch intervalech volß
metodu UTM_Tick( Count ); kterΘ v parametru Count p°edßvß
zb²vajφcφ poΦet tik∙. Tuto metodu pot°ebovat nebudeme,
b∞hem Φekßnφ ( Φφhßnφ ) nepo₧adujeme od bomby ₧ßdnou
Φinnost - naopak je ₧ßdoucφ, aby zat∞₧ovala systΘm co
nejmΘn∞. Tak₧e tuto metodu nebudeme definovat. Nadefinujeme
pouze metodu UTM_Stop, kterß je volßna p°i ukonΦenφ
Φinnosti ΦasovaΦe (p°eteΦenφ).
A v tΘto metod∞ pouze zavolßme dalÜφ prvek naÜφ bomby -
detektor aktivity.
A n∞jak takhle m∙₧e vypadat programovΘ vybavenφ objektu
Timer:
***********áááá Object
Timerááááá ************
Func Start( Delay );
** Spusteni bomby se zpozdenim DELAY **
{
áááá
Show( MainWindow,0 );áá ** Schovani okna bomby **
ááááá Timer_Start(
1, Delay );áááá ** Spusteni casovace **
}
Serve UTM_Stop; ** Preteceni casovace **
{á Detector.Start; ** Spusteni detekce aktivity **
}
Detekce aktivity
P°φkaz v obsluze udßlosti
UTM_Stop je volßnφ detektoru aktivity, kter² si nadefinujeme v
dalÜφm objektu. Tentokrßt m∙₧eme pou₧φt nejjednoduÜÜφ
objekt - aktivnφ rßm - nebo¥ v tomto prvku nebude t°eba nic
nastavovat Φi zobrazovat. Vyu₧ijeme op∞t pouze jeho ΦasovaΦ.
Detektor bude tikat donekoneΦna, a v pravideln²ch (op∞t
sekundov²ch) intervalech kontrolovat, zda je poΦφtaΦ v klidu.
Zjistφ-li aktivitu, odpßlφ nßlo₧.
Pro detekci aktivity jsme do LiWin za°adili jednoduchou funkci
GetActivity ( ach ty nßzvy ), kterß zkoumß, zda se mezi
jednotliv²mi volßnφmi funkce pohnul kurzor. Pravda, Ülo by
zjistit daleko vφce, ale necht∞li jsme zbyteΦn∞ zasahovat do
Φinnosti Windows - v praxi bohat∞ staΦφ uveden² zp∙sob.
Takhle tedy bude vypadat programovΘ vybavenφ detektoru:
************áááá Object
Detectoráááá ************
Func Start;
{ Timer_Start(1,0); ** nastaveni casovace na 1s,
nekonecne cyklu **}
serve
UTM_Tick;ááááááááááááááááááá **
obsluha tiku casovace **
{áá ifáá ( GetActivity > 0 )áá thenáá {áá
áááááááááááááá
timer_stop;áááááááááááááá ** pri
zjisteni aktivity stopni casovac **
áááááááááááááá Charge.Boom;áááááááá **
a odpal naloz **
ááááááááááá }
}
vizußlnφ efekty mohou prob∞hnout v okn∞ samotnΘ bomby, kterΘ pro tento ·Φel znovu ukß₧eme. Okno m∙₧eme p°emφstit na po₧adovanou pozici a dßt mu ₧ßdanou velikost p°φkazem MoveObject - p°i tom nezapome≥te, ₧e musφte pou₧φt sou°adnicovou soustavu LiWin, Φili 0-100 v obou osßch. Co v okn∞ ukß₧ete, zßle₧φ na vßs, v tomto sm∞ru poskytuje LiWin dostatek mo₧nostφ.
vizußlnφ efekt prob∞hne
v okn∞ prßv∞ aktivnφ aplikace - tento zp∙sob je
efektn∞jÜφ, ale nevyu₧ijete zde pln∞ grafickΘ
mo₧nosti LiWin - animace, pohyb a.j. - pro kreslenφ v
cizφch oknech jsou mo₧nosti pon∞kud omezenΘ, nebo¥
se zde vyu₧φvß standartnφ Windows mechanismus
kreslenφ.
Pro zjiÜt∞nφ cφle vyu₧ijeme funkci GetActiveWindow,
kterß vracφ handle prßv∞ aktivnφho okna. A do
cizφho okna m∙₧eme vykreslit obsah urΦenΘho objektu,
respektive jeho aktußln∞ nastaven² pohled, p°φkazem DrawToWin(
Source, Target, x, y, width, height), kde Source
je objekt nebo handle objektu, jeho₧ pohled (grafickΘ
rozhranφ) chceme zobrazit, Target je handle objektu, do
n∞ho₧ budeme promφtat, a zbytek jsou sou°adnice.
Nap°φklad by to mohlo vypadat takhle - funkce je
definovanß v objektu Charge:
Func Boom;
{ View(1); DrawToWin( Self, GetActiveWindow, 0, 0, 100,
100); }
V tomto p°φpad∞ se v objektu Charge nastavφ pohled
Φ.1, a promφtne se do prßv∞ aktivnφho okna na celou
jeho plochu. Bude-li souΦßstφ pohledu animace,
nezobrazφ se (respektive skryt∞ se p°ehraje v objektu
Charge).
Pozor - v tomto p°φpad∞ se pracuje s cel²m oknem,
nejen s jeho klientsk²m prostorem.
Vizußlnφ efekt prob∞hne
na ploÜe. Pro zobrazovßnφ na ploÜe jsme do LiWin
p°idali n∞kolik ·Φelov²ch funkcφ pro pro rychlΘ
p°ekreslovßnφ a obnovovßnφ pozadφ, tak₧e je mo₧no
realizovat zde velmi zajφmavΘ efekty - pohyblivΘ a
animovanΘ objekty, scrolling, a jß nevφm co jeÜt∞.
Funkce SaveDesktop ulo₧φ aktußlnφ
vzhled plochy do bitovΘ mapy, kterou nßsledn∞
pou₧φvß pro obnovenφ pozadφ p°i p°ekreslovßnφ
objekt∙.
Funkce DrawToDesktop vymaluje nastaven²
pohled kdekoli na ploÜe, a p°i p°emφst∞nφ obnovφ
p∙vodnφ vzhled - to vÜe bez jedinΘho bliknutφ. P°i
tom fungujφ vÜechny funkce nastavenφ pohledu:
zapφnßnφ a vypφnßnφ vrstev, posouvßnφ vrstev a
dalÜφ, pouze vrstvu automatickΘ animace nelze
pou₧φt, nebo¥ jejφ re₧im vykreslovßnφ je p°φliÜ
specifick² a nebylo jej mo₧no zobecnit.
Pro uvedenφ plochy do p∙vodnφho stavu slou₧φ funkce RestoreDesktop,
kterß na plochu promφtne bitovou mapu vytvo°enou
p°φkazem SaveDesktop, nebo funkce RedrawWindow(
0 ), kterß aktivuje standartnφ mechanizmus
Windows pro p°ekreslenφ okna, v tomto p°φpad∞
plochy.
Po ukonΦenφ Φinnosti na ploÜe doporuΦujeme uvolnit
kopii plochy z pam∞ti - k tomu slou₧φ funkce ReleaseDesktop.
pro explozi pou₧ijeme
n∞jak² standartnφ Windows box - nap°φklad chybovΘ
hlßÜenφ. V LiWin BASIC m∙₧ete takto pou₧φt zatφm
pouze MessageBox, kter² slou₧φ pro zobrazenφ
informacφ, hlßÜenφ, v²strah a podobn∞ - v tom
p°φpad∞ nepot°ebujeme objekt Charge, ale staΦφ
zm∞nit volßnφ nßlo₧e na volßnφ p°φmo MessageBoxu
- bude to vypadat takto:.
MsgBox( Message, Title, Spec); viz manußl.
Jinak nenφ ₧ßdn² problΘm kter²koli box napodobit -
v∞tÜinou je to jen otßzka kreslenφ.
DalÜφ mo₧nostφ je
pou₧φt zdroje, respektive aplikace p°idru₧enΘ k
vlo₧en²m snφmk∙m. Tφmto zp∙sobem m∙₧ete t°eba
p°ehrßt video nebo jin² multimedißlnφ soubor v
p°idru₧enΘm za°φzenφ, Φi otev°φt grafick² nebo
textov² editor - v podstat∞ m∙₧ete ud∞lat cokoli.
V tomto p°φpad∞ nevklßdejte do snφmkovΘ kolekce
objektu samotn² soubor, ale propojovacφ balφΦek.
Ud∞lßte to takhle:
- najd∞te po₧adovan² soubor, kter² budete chtφt
spustit
- klikn∞te na jeho ikonu prav²m tlaΦφtkem a
zkopφrujte do schrßnky
- v LiWin otev°ete snφmkovou kolekci (film) urΦenΘho
objektu (Charge), a vlo₧te obsah schrßnky do filmu
V tomto p°φpad∞ se do filmu zkopφruje pouze
propojovacφ balφΦek s odkazem na vybran² soubor a s
n∞kter²mi dalÜφmi informacemi. Tento balφΦek
zabφrß jen mßlo mφsta v pam∞ti.
V²buch potom bude vypadat takhle:
Func Boom;
{ OpenObject( self, Slide, Verb); }
O funkci OpenObject se
doΦtete v manußlu - struΦn∞ °eΦeno aktivuje OLE
objekt vlo₧en² do snφmkovΘ kolekce na pozici Slide
urΦenΘho objektu zp∙sobem dan²m v parametru Verb.
P°φkaz OpenObject(self, 1, 1)
nap°φklad aktivuje prvnφ snφmek vlastnφho objektu
prvnφm mo₧n²m zp∙sobem ( v∞tÜinou je to editace)
O dalÜφch mo₧nostech a
zp∙sobech by se daly napsat stohy strßnek - Kenneth Starr by
jimi jist∞ naplnil pßr kamion∙, a zdaleka by danou
problematiku ani sebe nevyΦerpal. N∞co k tomu najdete v
manußlu, a n∞co zjistφte sami, tak₧e p∙jdeme dßl.
V²buch lze samoz°ejm∞ doplnit zvukem - a to op∞t bu∩to
p°ehrßvaΦem danΘho formßtu prost°ednictvφm p°φkazu OpenObject,
a nebo vnit°nφm p°ehrßvaΦem zvuk∙ (u LiWin Basic pouze ve
formßtu WAV) p°φkazem Sound_Play( FileName).
Co po v²buchu...
Tady jsou v podstat∞ dv∞ mo₧nosti - bu∩to po v²buchu bombu
odstranit, nebo ji spustit znovu. Oba p°φpady jsou stejn∞
jednoduchΘ. V prvnφm p°φpad∞ vlo₧φme do funkce Boom
p°φkaz CloseWindow( MainWindow). A v druhΘm
p°φpad∞ jednoduÜe zavolßme metodu Start objektu Timer - asi
takto: Timer.Start( NewDelay); kde newDelay je
nov∞ zadanΘ zpo₧d∞nφ.
Mal² p°φklad
Zkusme si sestrojit
nejjednoduÜÜφ LiWin bombu, kterß bude pouze zobrazovat
p°eddefinovanß chybovß hlßÜenφ. HlßÜenφ budou
definovßna v poli °et∞zc∙ Error, a budou se nßhodn∞
zobrazovat v "znßhodn∞n²ch" pravideln²ch
intervalech. ╚asy budou zadßvßny jako parametry p°i
spuÜt∞nφ aplikace.
Bomba se bude sklßdat z objekt∙ Timer a Charge, souΦßstφ
objektu Charge bude detekce aktivity. Objekty vlo₧φme do
aplikace ( staΦφ aktivnφ rßmy, i kdy₧ je to jedno, m∙₧ete
tam vlo₧it cokoli), a nadefinujeme jim nßsledujφcφ program:
******áá Bomba Errors - Object Timeráá *******
Func Init; **
Inicializace objektu Timer, lokalni definice**
{áá
ááá Delay = getparam(1);ááááááááááááááá **
Nastaveni Time podle prvniho parametru **
áááá If (Delay = 0) then {Delay = 10;} ** Pokud
neni zadan, nastavi se na 10**
}á
Func Start( Dl); **
spusteni budiku **
{
áá Show(MainWindow, 0);ááá ** Schovej se **
áá timer_start(1, Dl);ááááááááá ** a
natoc si budika **
}á
Func Run;áááááá **
start programu **
{áá ** Spusteni bomby pri startu aplikace**
ááá Start( Delay);
}
Serve UTM_Stop; **
Co delat, kdyz timer dotika **
{áá Charge.GetUp; **Naloz!!! Vstavat !!! **
}
** Konec programove definice
objektu Timer **
******************ááá Object Chargeááá ********************á
Func Init; **
inicializace objektu Charge - lokalni definice ***
{á ArrayStr Error(1..100);
ááá NextDelay
= GetParam(2);á ** cas pro opakovane spousteni **
ááá Errorcount
= 100;áááááááááááá ** definujte podle
poctu skutecne definovanych hlaseni **
áá Error( 1) = ' Nevφm, co se to se mnou d∞je,
kßmo.
N∞jak se mi to vymklo z rukou.' ;
áá Error( 2) = ' PoruÜenφ ochrany na adrese
00A7:78AC
Pravd∞podobn∞ p°eh°ßtß elektronka PCL85
Do jejφho zchlßdnutφ bude uvedenß pam∞¥ovß lokace
nep°φstupnß' ;
** Definice dalsich Erroruuu **
}á
Func GetUp;
** Probuzeni bomby - start detekce aktivity**
{áá Timer_Start(1, 0);}
Serve UTM_Tick; **
Obsluha tiku casovace **
{áá if (GetActivity>0) then {
áááááááááááá Timer_Stop;ááááá **
Zastaveni casovace **
áááááááááááá MsgBox( ' Error', error( random( 1, ErrorCount)
), mb_Ok + mb_Exclamation); ** zobrazi se box **
ááááááááááá if ( NextDelay>0 )á then
{ááááááááááááááááááááááááááááááááááá
**á pokud je zadan cas pro opakovani **
áááááááááááááááááá Timer.Start( noise(
NextDelay, NextDelay/3); **á znovu zapal doutnak **
áááááááááááá }áá elseá
{ááááááááááááááááááááááááááááááááááááááááááááááááááááááááá
**á jinak **
áááááááááááááááááá closewindow( MainWindow )áááááááááááááááááááá
**á se ztrat **
áááááááááááá }
** Restart bomby s casem NextDelay ( plus minus
30%), je-li NextDelay > 0á **
}á
Tak to je vÜechno. Nenφ to
zrovna slo₧itΘ, co °φkßte ?
Detekce aktivity a exploze byly slouΦeny do jednoho objektu
(Charge). Zde je taky deklarovßno pole °et∞zc∙, do kter²ch
m∙₧ete ulo₧it text chybov²ch hlßÜenφ. P°i tom musφte
nastavit prom∞nnou ErrorCount, kterß musφ obsahovat poΦet
definovan²ch hlßÜenφ. ZobrazenΘ hlßÜenφ se vybφrß
nßhodn∞ v rozp∞tφ 1..ErrorCount ( funkce Random).
Pokud je program spuÜt∞n s parametrem pro opakovanΘ
zobrazenφ, budou se zobrazovat dalÜφ chybovß hlßÜenφ v
zadanΘm intervalu - tento interval je znßhodn∞n funkcφ Noise
o cca 1/3.
Nenφ-li tento parametr zadßn, program se ukonΦφ
I kdy₧ to zrovna nenφ ukßzka p°ehlednΘho a srozumitelnΘho
programovßnφ. T°eba pou₧itφ nßzvu Timer pro objekt
ΦasovaΦe bomby je trochu neÜ¥astnΘ - asi se vßm v textu
programu bude plΘst volßnφ systΘmovΘho ΦasovaΦe s
volßnφm objektu. Tak t°eba Timer.Start volß ΦasovaΦ bomby,
tedy metodu Start objektu Timer, kde₧to Timer_Start je volßnφ
standartnφ funkce, kterß inicializuje ΦasovaΦ ve vlastnφm
objektu.Ale nechce se mi p°episovat p°edchozφ text, tak₧e to
nechßm tak. Sna₧te se vÜak podobn²m zßdrhel∙m vyhnout,
fantazii se v pojmenovßvßnφ objekt∙ meze nekladou.
Bomby je v²hodn∞jÜφ uklßdat jako objekty. V tom p°φpad∞
je t°eba nap°ed vlo₧it do aplikace objekt, do kterΘho teprve
vlo₧φte jednotlivΘ prvky bomby. Po odlad∞nφ pak tento objekt
ulo₧φte jako komponentu. Takto vytvo°enΘ komponenty pak
m∙₧ete podle pot°eby nahrßvat a spouÜt∞t ve specißln∞ pro
tento ·Φel vytvo°enΘ aplikaci
DalÜφ mo₧nost - a mnohem v²hodn∞jÜφ - je uklßdat pouze
samotnΘ nßlo₧e, tedy objekty, realizujφcφ samotn² v²buch.
╚asovaΦ a detekce aktivity budou pracovat v₧dy stejn∞, mohou
tedy b²t souΦßstφ spouÜt∞cφ aplikace. V tomto p°φpad∞
bude spuÜt∞nφ nßlo₧e vypadat takto:
If ( Charge<> 0 )
then { DeleteObject(Charge); } ** Zruseni predchozi
naloze **
LoadObject( Self, ObjectFileName, 'Charge'); **
Nacteni naloze ze souboru ObjectFileName **
Prvnφ p°φkaz zajistφ
odstran∞nφ p°edchozφ nßlo₧e - objektu Charge - pokud je
ji₧ v aplikaci. Druh² p°φkaz vytvo°φ ve volajφcφm objektu
objekt Charge tak, ₧e jej naΦte ze souboru danΘho °et∞zcem
ObjectFileName. V praxi bude v²hodn∞jÜφ nahrßvat nßlo₧
p°φmo do hlavnφho okna, tedy do objektu Application. Pak
m∙₧eme objekt nßlo₧e pou₧φt pro p°ekrytφ hlavnφho okna,
co₧ bude v²hodnΘ u bomb, kterΘ pro v²buch pou₧φvajφ
vlastnφ okno bomby, nap°. pro chybovß hlßÜenφ nebo
nßroΦnΘ grafickΘ efekty (animace, pohyb). V tom p°φpad∞
bude prvnφm parametrem v p°φkazu LoadObject
mφsto Self hodnota Application.
SpuÜt∞nφ nßlo₧e bude automatickΘ - p°i vytvo°enφ objektu
je volßna jeho metoda Init, kterß zajistφ vytvo°enφ
mφstnφch definovan²ch prvk∙, a po za°azenφ objektu do
aplikace pak jeho metoda Run, kterß definuje jeho Φinnost p°i
spuÜt∞nφ.
Do metody Run tedy m∙₧eme umφstit volßnφ funkce,
provßd∞jφcφ explozi, p°φpadn∞ ji tam p°φmo definovat.
P°edchozφ p°φklad by v tom p°φpad∞ vypadal takto:
********************* Object Charge *******************
Func Init; **
inicializace objektu Charge - lokalni definice ***
{á ArrayStr Error(1..100);
áá Errorcount
= 100;áááááááááááá ** definujte podle
poctu skutecne definovanych hlaseni **
áá Error( 1) = ' Nevφm, co se to se mnou d∞je,
kßmo.
N∞jak se mi to vymklo z rukou.' ;
** Definice dalsich Erroruuu **
}á
Func Run; **
Spusteni objektu naloze**
{áá áááááá MsgBox( ' Error', error( random( 1, ErrorCount)
), mb_Ok + mb_Exclamation); ** zobrazi se box **
ááá áááááá CloseWindow(Self); ** po explozi
vypadni ( zrus se ) **
}
V tomto p°φpad∞ se nßlo₧ po
explozi sama zruÜφ. Pokud toto zajistφte u vÜech nßlo₧φ,
m∙₧ete vypustit prvnφ °ßdek z p°edchozφ ukßzky
spouÜt∞nφ nßlo₧φ ze souboru.
Pozor - pro zruÜenφ sebe sama (Self) v₧dy pou₧φvejte funkce
CloseWindow, a ne DeleteObject. Ve druhΘm p°φpad∞ toti₧
objekt sßm sebe zruÜφ jeÜt∞ p°ed ukonΦenφm vlastnφho
programu, co₧ zpravidla vede k chyb∞.
Tφmto zp∙sobem se celß v∞c znaΦn∞ zjednoduÜÜφ -
vytvo°φte si pouze univerzßlnφ aplikaci, kterß bude
spouÜt∞t urΦenΘ nßlo₧e. Aplikace bude obsahovat blok
ΦasovaΦe a detekce aktivity, a m∙₧ete do nφ zapracovat
nastavovßnφ zßkladnφch parametr∙ bomby pomocφ vhodn²ch
ovlßdacφch prvk∙. Aplikace pak bude spouÜt∞t vybranΘ
nßlo₧e v definovan²ch intervalech a libovoln∞ dlouho - p°i
tom bude v pam∞ti minimßln∞ p°ekß₧et.
A tak m∙₧ete sv²m bli₧nφm p°ipravit doslova oh≥ostroj
p°ekvapenφ, kter² prom∞nφ jejich prßci na poΦφtaΦi v
jedno velikΘ dobrodru₧stvφ.
V nßlo₧φch samotn²ch se pak m∙₧ete soust°edit pouze na co
nejp∙sobiv∞jÜφ zpracovßnφ efektu v²buchu, a nemusφte
°eÜit problΘmy s naΦasovßnφm a ostatnφmi funkcemi bomby.
M∙₧ete tak realizovat slo₧itΘ nßlo₧e posklßdanΘ z
libovolnΘho mno₧stvφ objekt∙, a rozehrßt p°ed udiven²mi
zraky posti₧en²ch u₧ivatel∙ opravdovΘ divadlo plnΘ
pohybliv²ch a animovan²ch objekt∙, barev a zvuk∙. Jedin²m
limitujφcφm faktorem bude jen vaÜe fantazie.
╚asem se v Prachßrn∞ v rubrice M∙₧ete si stßhnout objevφ jednak univerzßlnφ spouÜt∞Φ bomb, ale taky pßr zajφmav²ch nßlo₧φ. VÜechno bude otev°enΘ, tak₧e si to budete moci detailn∞ prostudovat.
V²hody a nev²hody LiWin
bomb
K v²hodßm pat°φ p°edevÜφm
snadnß a rychlß realizace slo₧it∞jÜφch a graficky
propracovan∞jÜφch bomb - vφce Φasu ne₧ samotnΘ
programovßnφ vßm zabere vizußlnφ zpracovßnφ efektu.
Hlavnφ nev²hodou je p°edevÜφm ni₧Üφ mobilita - zpravidla
musφte p°enßÜet p°ehrßvaΦ LiWin a zdrojov² soubor
aplikace, plus samoz°ejm∞ dalÜφ soubory pou₧itΘ p°i
explozi ( zvuky, multimedißlnφ soubory, nebo objekty
nßlo₧φ). Dßle pak trochu vφc zabranΘ pam∞ti a
systΘmov²ch prost°edk∙, a v neposlednφ °ad∞ omezenΘ
mo₧nosti p°i zobrazovßnφ grafiky mimo vlastnφ okno aplikace.
Nev²hody tedy p°eva₧ujφ - LiWin bomby nejlΘpe vyu₧ijφ ti,
kte°φ sv∙j poΦφtaΦ sdφlejφ s jin²mi osobami, aby jim tu
a tam zp°φjemnili ₧ivot. A nebo pro v²voj a testovßnφ
nov²ch bomb, kterΘ potom p°ed∞lßte do n∞jakΘho k≤dov∞
efektivn∞jÜφho jazyka.
V∞tÜina EXE bomb, kterΘ najdete
v Prachßrn∞, byla vytvo°ena v Borland Pascalu pro Windows.
Tento jazyk je sice dost ukecan² ( co₧ platφ o Pascalu obecn∞
), ale mß neobyΦejn∞ efektivnφ kompilßtor vytvß°ejφcφ
velmi ·sporn² cφlov² k≤d. A dovolφ taky sahat pom∞rn∞
hluboko do Windows, co₧ je vÜak trochu dvojseΦnß zbra≥ -
proto radφm experimentovat opatrn∞.
Windows aplikace zde lze vytvß°et v podstat∞ dv∞ma zp∙soby -
objektov∞ a neobjektov∞. DoporuΦuji prvnφ zp∙sob, i kdy₧ je
na prvnφ pohled slo₧it∞jÜφ a pracn∞jÜφ. Nebudu se zde
rozepisovat do podrobnostφ - pokud mßte BPW, mßte jist∞ i
manußly ( nebo ne? ), a tam je toho k p°eΦtenφ a₧ a₧.
Tak hezky popo°ad∞ - ΦasovaΦ
tu taky najdeme. Pro jeho nastavenφ a spuÜt∞nφ slou₧φ
nßsledujφcφ funkce:
function SetTimer(Wnd: HWnd; IDEvent: Integer; Elapse:
Word; TimerFunc: TFarProc): Word;
Zavolßnφm tΘto funkce otev°ete ΦasovaΦ, kter²
bude posφlat zprßvu WM_Timer vaÜemu oknu, respektive oknu,
reprezentovanΘmu manipulaΦnφm Φφslem Wnd. ╚asovaΦ bude
tikat v intervalech zadan²ch v milisekundßch parametrem Elapse.
Parametr IDEvent bude slou₧it pro identifikaci p°φsluÜnΘho
ΦasovaΦe - aby program v∞d∞l, kter² ΦasovaΦ zrovna tiknul,
pokud jich spustφte pro danΘ okno vφce. V parametru TimerFunc
m∙₧eme zadat callback proceduru (bude volßna
"zevnit°" p°i ticφch ΦasovaΦe).
Funkce vracφ identifikaΦnφ hodnotu, kterou budeme pot°ebovat
pro zruÜenφ danΘho ΦasovaΦe ( KillTimer).
Uka₧me si Φinnost bomby na jednoduchΘm p°φkladu: v tomto
p°φpad∞ se jednß o ten druh², mΘn∞ vhodn² zp∙sob -
n∞komu se mo₧nß bude zdßt jednoduÜÜφ, ale slo₧itost a
nep°ehlednost programu v tomto p°φpad∞ roste se Φtvercem
slo₧itosti bomby (a mo₧nß i s krychlφ).
Program Bombicka;
uses wintypes,winprocs,owindows,win31;
vará timer:word;
áááá counter:longint;
áááá ExitLoop:boolean;
áááá NewCursorPos,OldCursorPos: TPoint;á
{ realizace vybuchu - v
tomto pripade bombaá minimalizuje aktivni okno}
procedure Boom;
var dc:hdc;wnd:hwnd;r:TRect;
begin
á Wnd := GetActiveWindow;á { Vezmi aktivni okno, }
á ShowWindow( Wnd, SW_MINIMIZE); { a minimalizuj ho
}
á ExitLoop := True;á { ukonceni cyklu Loop -
vyrazenφ aplikace }
end;á
{á casovac a spoustec s
detekci aktivity }
procedure
TimerProc(wnd,msg,idTimer:integer;dwtime:longint);far;
begin
á if Counter > 0 then { je-li neco v pocitadle }
ááá begin
ááááá dec(Counter);áá { zmensi pocitadlo}
ááááá GetCursorPos(OldCursorPos);{Ulozeni
pozice kurzoru}
ááá end
á else
ááá begin
ááááá GetCursorPos(NewCursorPos); {Nacteni
aktualni pozice kurzoru}
ááááá If Longint(NewCursorPos)<>Longint(OldCursorPos)
thená boom; {je-li zmena, bouchni}
ááá end;
end;á
{ hlavni cyklus, zpracovani
zprav Windows }
procedure Loop;
vará Msg: TMsg;
begin
á while (GetMessage(Msg, 0, 0, 0)) and not ExitLoop do
á begin
ááá TranslateMessage(msg);
ááá DispatchMessage(msg);
á end;
end;
{ ****á Hlavni program
****}
begin
á exitLoop:=false;
á counter := 10;ááááááááááááááááááááááá
{ zpozdeni v sekundach }
á timer:=settimer(0,1,1000,@timerproc); {spusteni
casovace}
á
loop;áááááááááááááááááááááááááááááááá
{ hlavni cyklus }
á KillTimer(0,Timer);áááááááááááááááááá {
zruseni casovace }
end.á
Tato bombiΦka, jak jste si jist∞ vÜimli,
pouze minimalizuje prßv∞ aktivnφ okno. ╚as zpo₧d∞nφ v
sekundßch vlo₧φte do globßlnφ prom∞nnΘ Counter.
Jak to pracuje vßm asi nemusφm moc vysv∞tlovat.
V programu jsou t°i procedury - procedura TimerProc je callback
procedura, jejφ₧ adresa je p°edßna ΦasovaΦi p°i jeho
nastavenφ v hlavnφm programu. Tato procedura musφ b²t v₧dy far
a s uveden²mi typy parametr∙ ( na jejich jmΘn∞ nezßle₧φ).
Procedura je volßna p°i ka₧dΘm tiknutφ ΦasovaΦe. P°i tom
se dekrementuje poΦφtadlo, tedy prom∞nnß Counter - pokud je
hodnota poΦφtadla v∞tÜφ ne₧ nula - nebo se testuje, jestli
se pohnul kurzor myÜi, pokud je poΦφtadlo vynulovßno. A kdy₧
se novß pozice bude liÜit od p∙vodnφ, zavolß se procedura
Boom.
Ta realizuje vlastnφ v²buch. Nejprve si zjistφ manipulaΦnφ
Φφslo (handle) prßv∞ aktivnφho okna (funkce
GetActiveWindow), a kdy₧ je mß, zaΦne tam provßd∞t svΘ
nekalΘ rejdy.
A co vÜechno tam m∙₧e d∞lat? Prakticky ·pln∞ vÜechno -
prost°ednictvφm handle je mo₧no s oknem libovoln∞
manipulovat. M∙₧ete ho p°emφstit, zav°φt, kreslit do n∞j,
zjistit o n∞m spoustu v∞cφ a jß nevφm co jeÜt∞.
Na konci v²buchu nastavenφm prom∞nnΘ ExitLoop zajistφme
ukonΦenφ cyklu v procedu°e Loop. Tφm se ukonΦφ b∞h ·lohy
a program se vy°adφ z cyklu zprßv Windows.
Procedura Loop zajiÜ¥uje vlastnφ b∞h bomby, respektive jejφ
stßlou p°φtomnost v cyklu Windows. Cyklus p°ijφmß zprßvy
Windows a v tomto p°φpad∞ je kompletn∞ propouÜtφ dßl. Jak
to funguje se op∞t doΦtete v manußlu, ale doporuΦuji v∞novat
tomu minimßlnφ pozornost, proto₧e tφmto zp∙sobem se dnes
Window aplikace prost∞ ned∞lajφ.
Podφvejme se te∩, jak bude stejn² p°φklad vypadat, kdy₧ na to p∙jdeme p°es objekty:
Program Bombicka;áá {
tentokrat ojektove }
uses wintypes,winprocs,owindows,win31,wincrt;á
Type
áááá PBomba = ^TBomba;
áááá TBomba = object(TWindow)
áááááá Timer:word;
áááááá Counter:Longint;
áááááá Constructor Init(AParent:PWindowsObject);
áááááá Destructorá Done; virtual;
áááááá Procedureáá SetupWindow;virtual;
áááááá Procedureáá WMTimer( var Msg: TMessage);
áááááááááááááááááá virtual WM_First + WM_Timer;
áááááá procedureáá Boom;
áááá End;á áááá TBombaApp =
object(TApplication)
áááááá procedure InitMainWindow; virtual;
áááá end;á var
áááá NewCursorPos,OldCursorPos: TPoint;
áááá Application:TBombaApp;á
Constructor
TBomba.Init(AParent:PWindowsObject);
begin
á inherited Init(AParent,'Bomba');
á counter := 10;ááááááááááááááááááááááá {
zpozdeni v sekundach }
end;á
Procedureáá
TBomba.SetupWindow;
begin
á inherited setupWindow;
á timer:=settimer(HWindow,1,1000,nil); {spusteni
casovace}
end;á
Destructorá
TBomba.Done;
begin
á KillTimer(HWindow,Timer);
á Inherited done;
end;á
procedure TBomba.Boom;
var wnd:hwnd;
begin
á Wnd := GetActiveWindow;á { Vezmi aktivni okno, }
á ShowWindow( Wnd, SW_MINIMIZE); { a minimalizuj ho
}
á free;áááááá { a muzes jit treba do ...}
end;á
{ obsluha casovace a
spoustec s detekci aktivity }
procedure TBomba.WMTimer(var msg:TMessage);
begin
á if Counter > 0 then { je-li neco v pocitadle }
ááá begin
ááááá dec(Counter);áá { zmensi pocitadlo}
ááááá GetCursorPos(OldCursorPos); {Ulozeni
pozice kurzoru}
ááá end
á else
ááá begin
ááááá GetCursorPos(NewCursorPos); {Nacteni
aktualni pozice kurzoru}
ááááá If Longint(NewCursorPos)<>Longint(OldCursorPos)
thená boom; {je-li zmena, bouchni}
ááá end;
end;á
{ ****á Inicializace
aplikace ****}
PROCEDURE TbombaApp.InitMainWindow;
Begin
ááá MainWindow := New(PBomba, Init(nil));
End;á
{ ****á Hlavni program
****}
begin
á Application.Init('');
á showWindow(Application.MainWindow^.hwindow,sw_Hide); {schovej
se}
á Application.Run;
á Application.Done;
end.á
Program nßm trochu nabyl na objemu, ₧e jo.
Ale nenφ to tak hroznΘ.
A jakΘ z toho plynou v²hody?
Tak p°edn∞ - mßme te∩ bombu jako plnohodnotnou Windows
aplikaci, reprezentovanou hlavnφm oknem. To je sice b∞hem
hlavnφ Φinnosti bomby Offscreen, ale m∙₧eme ho vyu₧φt -
vlo₧it do n∞j ovlßdacφ prvky, popisky, vÜelijakΘ
fraje°inky, aby sv∞t vid∞l, jacφ jsme paÜßci. Ono by to
sice v p°edchozφm p°φpad∞ Ülo taky, ale bylo by to mnohem
slo₧it∞jÜφ.
Program funguje v podstat∞ stejn∞, ale jsou tu drobnΘ
odliÜnosti. Za prvΘ - mφsto chumlu funkcφ a procedur mßme
p∞kn∞ zapouzd°enΘ objektovΘ typy, kterΘ jen staΦφ vlo₧it
do aplikace. Nemusφme se zab²vat n∞jakou filtracφ zprßv (
co₧ bychom jinak museli ), p°ekladaΦ za nßs vÜechno ud∞lß
sßm. Nßm staΦφ jen "naladit" urΦitou metodu
urΦitΘho objektu na urΦitou zprßvu - v tomto p°φpad∞ jsme
metodu WMTimer naladili na zprßvu WM_Timer, kterß, jak jist∞
vφte, je naÜemu objektu, respektive oknu, vysφlßna p°i
ka₧dΘm tiknutφ naÜeho ΦasovaΦe.
UvedenΘ p°φklady jsou jen programovΘ kostry, a v praxi budou
vφcemΘn∞ nepou₧itelnΘ. Od bomby zpravidla vy₧adujeme
mo₧nost naΦasovat si ji, jak chceme, a nastavit dalÜφ
parametry. Ale to si jist∞ dod∞lßte sami.
Pokud jste ji₧ n∞co ve Windows vytvo°ili, jist∞ si aplikaci
dotvo°φte k obrazu svΘmu. Nap°φklad okno bomby m∙₧ete
vytvo°it z typu TDlgWindow a posklßdat si jeho vizß₧ ve
Workshopu. M∙₧ete do n∞j vlo₧it ovlßdacφ a nastavovacφ
prvky atd. V tom p°φpad∞ p°emφstφme "schovßnφ"
okna aplikace, kterΘ je v p°φkladu umφst∞no v hlavnφm
programovΘm bloku, do metody, kterß bude startovat bombu.
V²hody a nev²hody BPW bomb
V tomto p°φpad∞ v²hody p°eva₧ujφ. BombiΦky jsou p∞kn∞
skladnΘ, ·spornΘ, a p°i troÜe fantazie a znalosti BPW
m∙₧ete ud∞lat prakticky cokoli. Funkci bomby, respektive jejφ
explozi, zm∞nφte pouh²m p°edefinovßnφm procedury Boom (nebo
jak si ji nazvete).
Jedinou nev²hodou je pom∞rn∞ slo₧itΘ programovßnφ
grafick²ch efekt∙, kterΘ vy₧aduje pom∞rn∞ hlubokΘ znalosti
prost°edφ BPW, a taky dost programßtorskΘ kßzn∞. Hlavn∞
nesmφte zapomφnat, ₧e co v grafickΘm rozhranφ vytvo°φte,
musφte po pou₧itφ zruÜit - jinak bude mφt bomba druhotn²
efekt ₧routa pam∞ti a systΘmov²ch prost°edk∙.
Programovat v DELPHI je radost. Ale co se
t²Φe bomb, jsou zde mo₧nosti velmi omezenΘ.Mßme tu
samoz°ejm∞ k dispozici ΦasovaΦe, funkce pro prßci s grafikou
a v∙bec vÜechno, co takovß bomba pot°ebuje, ale chybφ tady
jedna maliΦkost - jednoduchß cestiΦka ven mimo vlastnφ
aplikaci.
Tak nap°φklad nezjistφte handle prßv∞ aktivnφho okna -
pokud ovÜem nenφ aktivnφ prßv∞ n∞kterΘ okno bomby.
GrafickΘ v²stupy jsou jednoduchΘ, ale jen do vlastnφch
objekt∙ aplikace. Chcete-li kreslit ven, jste na tom stejn∞
jako u BPW - i kdy₧ nevφm, moc hluboko jsem do toho neÜel,
mo₧nß existuje zp∙sob, jak je jednoduÜe p°esm∞rovat.
Na druhou stranu zde velmi snadno vytvo°φte dokonalΘ
napodobeniny vÜech mo₧n²ch errorbox∙, tipov²ch oken,
terminßl∙, dotaznφk∙, da≥ov²ch formulß°∙ a vÜelijak²ch
jin²ch blßznivin, kterΘ p°i sprßvnΘm podßnφ dokß₧φ
n∞kdy u₧ivatele vystresovat daleko ·Φin∞ji, ne₧ skuteΦnß
exploze monitoru a p°ilehl²ch budov.
Jak takovou bombiΦku ud∞lat? Prost∞ si vytvo°φte dva
formulß°e - v jednom bude Φasovacφ mechanizmus, druh² pak
bude slou₧it jako v²buÜn² prostor.
K funkci programu samotnΘho nemß cenu se rozepisovat - vÜe
bude fungovat jako v p°edchozφch p°φpadech. Vy jen
nadefinujete obsluhu udßlostφ jednotliv²ch prvk∙ (nastavenφ
zpo₧d∞nφ aj.), a obsluhu udßlosti OnTimer vlo₧enΘho
ΦasovaΦe - bude prakticky stejnß, jako metoda WMTimer v
p°φkladu Borland Pascalu, bude se liÜit jen hlaviΦkou:
procedure TForm1.OnTimer(Sender: TObject);
Ostatnφ bude prakticky stejnΘ jako v
p°edchozφch p°φkladech.
Trochu podrobn∞ji se o mo₧nostech DELPHI v tomto sm∞ru
rozepφÜi pozd∞ji, a₧ prozkoumßm jeho dalÜφ mo₧nosti.
V²hody a nev²hody...
S v²hodami a nev²hodami je to tady podobnΘ jako u LiWin -
snadnß realizace n∞kter²ch typ∙ bomb, ale na druhΘ stran∞
trochu omezenΘ mo₧nosti, co se t²kß vyu₧itφ grafick²ch
funkcφ pro ·pravu cizφch oken - i kdy₧ lze vyu₧φt (nevφm
zatφm, v jakΘ mφ°e a s jak²m omezenφm ) funkce Borland
Pascalu.
Hlavnφ nev²hodou z∙stßvß nemo₧nost zjistit aktivnφ okno
mimo vlastnφ aplikaci. Pokud vφte, jak na to, dejte mi prosφm
v∞d∞t.
DalÜφ nev²hodou je dost nafouknut² cφlov² k≤d, kter² i u
jednoduch²ch aplikacφ nebude menÜφ ne₧ Φtvrt megabajtu.
Objekty DELPHI majφ toti₧ spoustu u₧iteΦn²ch vlastnostφ -
ale majφ je, i kdy₧ je t°eba prßv∞ nepot°ebujete.