Zobrazení kurzoru v DelphiX - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

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)

Tématické zařazení:

 » Rubriky  » Komponenty  

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: