Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Komponenty
Zobrazení kurzoru v DelphiX
27. srpna 2000, 00.00 | Detailní návod jak zobrazit neblikající kurzor v DelphiX komponentách. Článek je přípravou na seriál o tvorbě her v Delphi..
Pokud ještě nemáte žádné zkušenosti z komponentami DelphiX, doporučuji přečíst si první nějaký jiný článek, nejlépe článek Delphi vs hry na serveru Prognet abyste tento mohli pochopit. Pokud jste již tak učinili, čtěte dál.
DelphiX jsou vítečné komponenty, ale pokud jste již nějaký projekt s těmito komponentami spustili, určitě jste si všimnuli, že pokud přejedete kurzorem myši přes formulář, začne kurzor blikat. Toto je velice nepříjemné, a právě proto je zde tento návod, jak zobrazit kurzor s DelphiX, samozřejmě bez blikání.
Tedy, jak ? Přes windows cesta nevede, a proto budeme vykreslovat na povrch
(surface) DXDraw svůj vlastní obrázek pokaždé, když uživatel pohne s myší.
Toto nám zajistí procedura OnMouseMove. Tento zdánlivě složitější způsob
nám oproti windows však nabízí další možnosti, a to jak neomezený počet
barev, tak neomezenou velikost kurzoru (neomezená sice je, ale pokud dáte
kurzor velikosti 500x500, bude se uživatel asi docela divit...). Nejdříve ale
musíme odstranit standartní windowsovský kurzor, který by nám asi překážel.
To uděláme jednoduchou procedurou ShowCursor(false)
. Jak snadné.
Poté si musíte sehnat nebo nakreslit nějaký ten kurzor a uložit jej ve formátu
bmp. Také si musíte zjistit, kde budete chtít mít na kurzoru HotSpot, tedy místo,
které určuje polohu kurzoru. A to je asi tak vše. Zde je už jen návod:
Jako demonstrační verzi jsem zvolil aplikaci, ve které se zobrazuje kromě kurzoru ještě obrázek dalších čtyř kurzorů, a pokud na některý z nich kliknete, kurzor se změní. Začneme tedy tím, že vytvoříme nový projekt (File/ New Application) a na něj vložíme komponenty DXDraw a DXImageList. U DXDraw nastavíme Align na AlClient, aby se nám roztáhnul po celém formuláři. U komponenty DXImageList poklepeme na vlastnost Items a poté klikáním na ikonu AddNew přidáme čtyři položky. Do vlatnosti Picture u jednotlivých položek nahrajeme již zmíněné obrázky kurzorů. Já jsem je nahrál následovně - položka 0 - kurzor šipka, p.1 - kurzor kříž, p.2 - kurzor ruka a p.3 - kurzor hodiny. Poté jsem určil hotSpoty jednotlivých kurzorů (u šipky a ruky to je levý horní roh - souřadnice 0,0 a u kříže a hodin to je prostředek - souřadnice 25,25). Tyto hodnoty musíme někam uložit, a proto jsem definoval pole bodů:
var cHotSpot:array [0..5] of Tpoint; // pole hotspotů kurzoru
Dále musíme vědět, který kurzor je aktivní, abychom věděli, z které položky cHotSpot musíme číst souřadnice hotspotu. To zajistíme další proměnnou:
var SelCursor:integer; // aktivní kurzor
To by asi ke kurzoru stačilo. Podíváte-li se ale ještě jednou na obrázek
nahoře, zjistíte, že kromě aktivního kurzoru, s kterým hýbete jsou zde ještě
obrázky čtyř kurzorů. Pokud na některý z nich kliknete, změní se kurzor.
Jak ale zajistit, do jaké oblasti uživatel kliknul ? Poslouží nám k tomu
funkce PtInRect(point, rectangle)
, která testuje, zda se bod point
nalézá v oblasti rectangle. Pokud ano, vrací hodnotu true, opačně false. Začneme
tím, že si nadefinujeme oblasti polem, které je složeno z TRect:
cRectangle:array [0..5] of Trect; // pole oblastí obrázků kurzorů
Tímto jsme s definováním proměnných skončili a můžeme se pustit do programování. Zde je výpis procedury MainForm.OnCreate, která je volána, když se vytvoří formulář. Vysvětlení je dál:
procedure TMainForm.FormCreate(Sender: TObject);
begin
ShowCursor(false); // zakázat zobrazení kurzoru
// nastavení hotspotů kurzorů
cHotSpot[0].x:=2; // šipka
cHotSpot[0].y:=2;
cHotSpot[1].x:=25; // kříž
cHotSpot[1].y:=25;
cHotSpot[2].x:=15; // ruka
cHotSpot[2].y:=1;
cHotSpot[3].x:=25; // hodiny
cHotSpot[3].y:=25;
selCursor:=0; // vybraný kurzor je šipka
// nastavení oblastí, kde jsou na formuláři nakresleny kurzory
cRectangle[0].Left:=20; // šipka
cRectangle[0].Top:=20;
cRectangle[0].Right:=70;
cRectangle[0].Bottom:=70;
cRectangle[1].Left:=20; // kříž
cRectangle[1].Top:=70;
cRectangle[1].Right:=70;
cRectangle[1].Bottom:=140;
cRectangle[2].Left:=20; // ruka
cRectangle[2].Top:=140;
cRectangle[2].Right:=70;
cRectangle[2].Bottom:=210;
cRectangle[3].Left:=20; // hodiny
cRectangle[3].Top:=210;
cRectangle[3].Right:=70;
cRectangle[3].Bottom:=260;
end;
Myslím, že další komentář je již docela zbytečný, přesto jenom v rychlosti popíšu jednotlivé kroky. Nejdříve tedy procedurou ShowCursor(false) zakážeme windows, aby zobrazoval kurzor. Dále nastavíme hotspoty jednotlivých kurzorů a nakonec nastavíme oblasti, ve kterých jsou nakresleny kurzory a na které může uživatel kliknout.
Jako další krok vytvoříme proceduru DXDraw.OnMouseMove, do které přidáme následující kód. Vysvětlení je opět níže:
procedure TMainForm.DXDraw1MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
if not DXDRaw1.CanDraw then exit;
DXDraw1.Surface.Fill(0);
// nakreslení obrázků čtyř kurzorů
DXImageList1.Items[0].Draw(DXDraw1.surface,20,20,0);
DXImageList1.Items[1].Draw(DXDraw1.surface,20,70,0);
DXImageList1.Items[2].Draw(DXDraw1.surface,20,140,0);
DXImageList1.Items[3].Draw(DXDraw1.surface,20,210,0);
// nakreslení aktivního kurzoru
DXImageList1.Items[SelCursor].Draw(DXDraw1.surface,
x-cHotSpot[selCursor].x,y-cHotSpot[selCursor].y,0);
// do caption formu přidat pozici kurzoru
MainForm.Caption:='Kurzor demo - x: '+IntToStr(x)+' y: '+IntToSTR(y);
//a flip...
DXDraw1.Flip;
end;
První řádek kódu (if not DXDRaw1.CanDraw then exit;)
zajistí, že pokud se na povrch DXDraw nedá kreslit, z procedury se vyskočí.
Tento řádek můžete klidně vynechat. Řádek další (DXDraw1.Surface.Fill(0);
)
vyplní povrch černou barvou, tedy celou kresbu vymaže. Následuje kreslení
čtyř obrázků kurzorů, které je prováděno pomocí funkce Draw. První
parametr určuje povrch, další dva x-ovou a y-ovou souřadnici a poslední
vzorek. Následuje kreslení aktivního kurzoru, pozor na to, že x-ová a y-ová
souřadnice není prostě x a y, ale musíme od těchto hodnot odečíst hotSpot.x
a hotSpot.y. Více snad pochopíte z tohoto obrázku:
Dalším řádkem (
MainForm.Caption:='Kurzor demo - x: '+IntToStr(x)+' y: '+IntToSTR(y);
)změníme
titulek formuláře na Kurzor demo - x: x-ová pozice kurzoru y: y-ová pozice
kurzoru. Jelikož všechny obrázky, které jsme kreslili, jsme kreslili na
skrytý povrch, musíme ještě posledním řádkem (DXDraw1.Flip;
)
zajistit, aby se povrchy vyměnily a my jsme vše viděli.
Konečná fáze je přidání procedury DXDraw.OnMouseDown, která je volána, pokud uživatel stiskne tlačítko myši. Jak jsem již napsal, testujeme pomocí funkce PtInRect, zda-li se hotSpot kurzoru nachází v jedné ze čtyř oblastí. Pokud tomu tak je, změní se SelCursor na číslo odpovídající kurzoru, na který uživatel kliknul. Zde je kód:
procedure TMainForm.DXDraw1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var Pos:Tpoint;
i:integer;
begin
Pos.x:=x;
Pos.y:=y;
// zjištění, do oblasti kterého
// kurzoru uživatel kliknul myší
for i:=0 to 5 do
begin
if PointInRect(pos,cRectangle[i])
then SelCursor:=i;
end
end;
Pro lepší představu je zde ještě obrázek:
A to je konec.
zde si můžete stáhnout demo aplikaci (205 kB)
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007