Člen systému BillBoard.cz - reklama na Internetu zdarma
ApEl - Bedřich Havlíček
Lužice 23, 785 01 Šternberk
tel/fax 0643 - 411917
liwin@liwin.cz

Zpátky do Prachárny

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.

Napište nám...

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.


Jak funguje bomba

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

  1. časovač - dříve upravený budík, děravý kýbl doplněný důmyslnou mechanickou soustavou, svíčka nebo jiný zpožďovací mechanismus, dnes většinou více či méně složité elektronické systémy. Někdy postačí i osoba, jejíž zápal pro svatou věc či vidina sladkého posmrtného ráje přebije všechny instinkty (včetně základního), i zdravý rozum.
    V našem případě to bude systémový prostředek, který máme k dispozici ve většině programovacích prostředků.
    Účelem časovače je, aby bomba bouchla, až budeme v dostatečné vzdálenosti, nebo až bude v dostatečné blízkosti objekt našeho zájmu
  2. detekce aktivity - zajistí, aby bomba bouchla, až se bude něco dít. Komu by se taky chtělo bouchat jen tak bez publika, že jo... Poté, co časovač odtiká to svoje, předá řízení tomuto bloku.
    V případě našich bomb - aby nebylo nutné hlouběji vstupovat do cyklu Windows - se jen hlídá pohyb myši. Většinou to stačí - myš má dneska kde kdo, a když už ji má, tak ji dříve či později použije (pokud ovšem není ortodoxním zastáncem krkolomných hotkeys typu Ctrl-Alt-LeftShift-P).
  3. nálož - o tom není třeba se rozepisovat. V případě softwarové bomby je to neobvyklá nebo neočekávaná činnost počítače ( zformátování HD, Remove Windows, Rewrite FAT apod.), která ma za cíl vyvést uživatele pokud možno co nejvíce z míry. My jsme se poněkud neprozřetelně a úzkoprse zavázali, že naše bomby budou neškodné, takže uvedené příklady si jistě zpracujete sami..

Zpět


LiWin bomba

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 **
           
}
}

Nálož
Charge může být další objekt, který bude řídit samotnou explozi. Případně je možno detekci aktivity i samotnou explozi definovat v jednom objektu.
Exploze může probíhat několika způsoby:

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.

Zpět

 


Bomby a BPW

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

Zpět

 


Bomby a DELPHI

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.