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

Tipy a triky v Delphi - díl 141.

Jan Šindelář 2.6.2004

Po minulém hraní s myší si dnes zkusíme naprogramovat velice jednoduchou a přitom poměrně efektní aplikaci. Možná znáte (a třeba i někteří používáte) nástroj Lupa, který je součástí programů pro usnadnění používání Windows. Právě takový program si dnes zkusíme vytvořit.

Náš dnešní program je tedy jasný, takže se pustíme rovnou do práce. Pro začátek se podíváme na zmiňovaný nástroj Lupa, abychom si udělali představu o tom, jak bude naše aplikace přibližně fungovat. Ve Windows XP (a tuším i 2000) jej najdete v menu Start -> Programy -> Příslušenství -> Usnadnění. Základem je jednoduché okno, kde se ve zvětšené podobě zobrazuje okolí kurzoru. Kromě několika doplňkových parametrů je tím základním faktor zvětšení, který udává, kolikrát chceme oblast kolem kurzoru zvětšit.

Aplikace, kterou si dnes vytvoříme, bude pracovat velmi podobným způsobem, i když bude mnohem jednodušší. Na prázdný formulář umístíme pouze komponentu Image, do které se bude překreslovat zvětšený výřez obrazovky kolem kurzoru. Zarovnání nastavíme na alClient, aby komponenta vyplnila celý obsah formuláře. Druhá a poslední komponenta bude Timer. Její interval pak určuje rychlost překreslování, takže pro plynulost bude vhodné nastavit pochopitelně co nejnižší hodnotu. V události OnTimer pak bude prakticky většina kódu aplikace.

Samotná funkce nejprve zjistí, zda není aplikace minimalizovaná (v tom případě se samozřejmě nic nekreslí). Poté zjišťujeme pozici kurzoru a pokud je kurzor nad oknem naší aplikace (jakoby zvětšujeme sama sebe), rovněž se nic nekreslí. Poté už jen získáme tu část pracovní plochy (obdélníkovou plochu kolem kurzoru, který tvoří její střed), která odpovídá velikosti našeho okna a překreslíme ji do připravené komponenty Image. Vše je ale přepočítáno podle faktoru zvětšení (či zmenšení, viz. dále).

unit Unit1;

interface

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

const zoomfaktor = 2;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Srect, Drect, PosForm: TRect;
  iWidth, iHeight: Integer;
  iTmpX, iTmpY: Real;
  C: TCanvas;
  hDesktop: Hwnd;
  Cur: TPoint;
begin
  if not IsIconic(Application.Handle) then
    begin
      hDesktop := GetDesktopWindow;
      GetCursorPos(Cur);
      PosForm := Rect(Left, Top, Left + Width, Top + Height);
      if not PtInRect(PosForm, Cur) then
        begin
          iWidth := Image1.Width;
          iHeight := Image1.Height;
          Drect := Rect(0, 0, iWidth, iHeight);
          iTmpX := iWidth / ((zoomfaktor / 2) * 4);
          iTmpY := iHeight / ((zoomfaktor / 2) * 4);
          Srect := Rect(Cur.x, Cur.y, Cur.x, Cur.y);
          InflateRect(Srect, Round(iTmpX), Round(iTmpY));
          if Srect.Left < 0 then OffsetRect(Srect, -Srect.Left, 0);
          if Srect.Top < 0 then OffsetRect(Srect, 0, -Srect.Top);
          if Srect.Right > Screen.Width then OffsetRect(Srect, -(Srect.Right - Screen.Width), 0);
          if Srect.Bottom > Screen.Height then OffsetRect(Srect, 0, -(Srect.Bottom - Screen.Height));
          C := TCanvas.Create;
          try
            C.Handle := GetDC(GetDesktopWindow);
            Image1.Canvas.CopyRect(Drect, C, Srect);
          finally
            ReleaseDC(hDesktop, C.Handle);
            C.Free;
          end;
          Application.ProcessMessages;
        end
    end;
end;

end.

Důležitý je parametr zoomfaktor, který je definován jako konstanta na začátku zdrojového kódu. Pokud vložíme číslo jedna, bude do okna pouze kopírováno okolí myši v původní velikosti. Dvojka pak způsobí dvojnásobné zvětšení a tak dále. Můžete však zadat i (kladné) číslo menší než jedna. V tom případě bude v našem okně zmenšený náhled pracovní plochy (okolí myši). A ti zvídaví z vás mohou zkusit vložit i záporné číslo (nula pochopitelně nemá smysl). Uvidíte, co se stane.