Živě.cz o počítačích a internetu

Tipy a triky v Delphi, díl 140. - základy s myší

Jan Šindelář - 26.5.2004

V grafickém uživatelském prostředí dnešních operačních systémů si už práci bez myši dokáže představit jen málokdo. Pravda ovšem je, že správně bychom měli aplikace programovat tak, aby byly ovladatelné i bez myši jen pomocí klávesnice. Na to zkuste alespoň občas myslet, i když dnes už asi nebude toto příliš velký problém a myš najdete opravdu všude.

Myš je tedy důležitá, jejím prostřednictvím uživatel ovládá většinu objektů na obrazovce a proto systém (a jeho prostřednictvím i vaše aplikace) neustále monitoruje její stav a činnost. Generuje pak příslušné události, na které v našich programech příslušným způsobem reagujeme.

Tyto základní události (resp. akce, které jim předcházejí) jsou vlastně jen čtyři. Je to stisknutí tlačítka, uvolnění tlačítka, pohyb myši po objektu a poslední je kliknutí, což je vlastně kombinace prvních dvou akcí. Navíc je kliknutí omezeno i "lokálně", tzn. že stisknutí i uvolnění tlačítka musí být provedeno na stejném místě (přesněji nad stejným objektem) a navíc jej lze v jistých případech vyvolat i klávesnicí.

Důležité je rovněž připomenout to, že když klikneme na nějaký objekt, přesněji řečeno stiskneme a držíme tlačítko, daný objekt si myš "přivlastní" až do té doby, dokud opět tlačítko neuvolníme, takže i když během této doby myš přesuneme na jiné místo, žádná jiná komponenta není schopna s myší reagovat, dokud není tlačítko uvolněno. Ano, metoda drag & drop sice naznačuje něco jiného, ale o tom bude řeč zase někdy jindy.

Pojďme si tedy blíže popsat zmiňované události. O události OnClick není celkem co říci. Nemá žádné parametry navíc a jak bylo řečeno, je vyvolána stiskem a následným uvolněním tlačítka myši nad objektem.

Události OnMouseDown (stisknutí tlačítka) a OnMouseUp (uvolnění tlačítka) jsou už o něco zajímavější. Jsou vlastně téměř identické, mají stejné parametry a liší se pouze tím, že reagují na opačnou akci uživatele. Kromě základního parametru Sender je to dále parametr Button, který indikuje, které tlačítko myši bylo stisknuto (levé, prostřední či pravé). Parametr Shift pak udává, zda byla současně se stiskem tlačítka podržena i některá z pomocných kláves (Ctrl, Alt, Shift) a konečně poslední dva parametry udávají souřadnice kurzoru myši v klientské části daného objektu (tedy ne souřadnice na obrazovce, pozor).

Událost OnMouseMove nastane tehdy, pokud uživatel nad objektem pohne myší. Z toho je jasné, že při plynulém pohybnu myší po objektu je tato událost generována poměrně často, takže pozor na kód, který do této události umístíte. Kromě chybějícího parametru Button (jehož funkce je vlastně nahrazena parametrem Shift) jsou ostatní parametry stejné jako u předchozích událostí.

Nyní následuje kód jednoduchého projektu, formulář může zůstat prázdný.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  case Button of
    mbLeft:
      begin
        Canvas.Brush.Color := clRed;
        Canvas.Ellipse(x - 20, y - 20, x + 20, y + 20);
      end;
    mbRight:
      begin
        Canvas.Brush.Color := clBlue;
        Canvas.Rectangle(x - 20, y - 20, x + 20, y + 20);
      end;
  end;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer);
begin
  if ssShift in Shift then
    begin
      Canvas.Brush.Color := clLime;
      Canvas.Ellipse(x - 20, y - 20, x + 20, y + 20);
    end
  else
    begin
      Canvas.Brush.Color := clYellow;
      if ssCtrl in Shift then Canvas.Rectangle(x - 20, y - 20, x + 20, y + 20);
    end;
end;

end.

V kódu jsou využity všechny zmiňované vlastnosti. Při stisknutí levého tlačítka (událost OnMouseDown) bude nakreslen červený kruh, pravé tlačítko zase nakreslí modrý čtverec. V události OnMouseMove je zase využita kombinace s funkčními klávesami Shift a Ctrl, takže pokud stisknete během pohybu myši (tlačítko myši mačkat nemusíte) klávesu Shift, bude kreslen zelený kruh, klávesa Ctrl zase bude kreslit žlutý čtverec. V obou případech bude obrazec kreslen samozřejmě po celou dobu pohybu myší, takže kurzor bude za sebou nechávat "stopu".