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

Tipy a triky v Delphi, díl 131. - rozšíření PageControl

Jan Šindelář - 24.3.2004

Klasickou komponentu PageControl (pozor na záměnu s velmi podobnou komponentou TabControl) jistě dobře znáte. Jedná se o panel, rozdělený na množství jednotlivých záložek. Aktivní je vždy jen jedna a ostatní překrývá. Na každou takovou stránku (záložku) pak můžeme umístit prakticky libovolné další vizuální komponenty.

PageControl se dá s úspěchem použít v případě, kdy množství vizuálních komponent překročí únosnou míru a jejich prosté umístění na formulář by bylo nepřehledné. Proto použijeme PageControl, kde můžeme ovládací prvky a možnosti naší aplikace přehledně roztřídit na jednotlivé záložky. Obvykle se této komponenty využívá pro různá nastavení a konfigurace aplikací, kde bývá množství možností veliké a uživatel si tak snadno může vybírat mezi jednotlivými kategoriemi přepínáním mezi záložkami. Ale to není zdaleka jediný případ. Nás dnes bude zajímat spíše druhá kategorie použití, kdy například některé textové editory řeší otevření více dokumentů právě použitím záložek, kdy každý dokument je na samostatné záložce. Zde totiž může pro uživatele hrát roli i pořadí jednotlivých záložek a o tom bude právě dnes řeč.

Za normálních okolností totiž uživatel nemůže dělat nic jiného, než mezi záložkami přepínat. Určitě by ale uvítal možnost měnit za běhu aplikace dle své libosti i pořadí jednotlivých záložek. A není snad příhodnější způsob než použít metodu drag & drop, kdy uživatel pomocí myši uchopí záložku za její "ouško" a přesune na potřebné místo.

Vše se dá provést poměrně snadno ošetřením třech událostí komponenty PageControl jak vidíme ze zdrojového kódu. Na formulář umístěte komponentu PageControl a pro otestování příkladu vytvořte čtyři záložky (TabSheet).


unit
Unit1;

interface

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

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    TabSheet3: TTabSheet;
    TabSheet4: TTabSheet;
    procedure PageControl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure PageControl1DragDrop(Sender, Source: TObject; X, Y: Integer);
    procedure PageControl1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.PageControl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  PageControl1.BeginDrag(False);
end;

procedure TForm1.PageControl1DragDrop(Sender, Source:TObject; X, Y: Integer);
const
  TCM_GETITEMRECT = $130A;
var
  TabRect: TRect;
  j: Integer;
begin
  if (Sender is TPageControl) then
  for j := 0 to PageControl1.PageCount - 1 do
    begin
      PageControl1.Perform(TCM_GETITEMRECT, j, LParam(@TabRect));
      if PtInRect(TabRect, Point(X, Y)) then
        begin
          if PageControl1.ActivePage.PageIndex <> j then PageControl1.ActivePage.PageIndex := j;
          Exit;
        end;
    end;
end;

procedure TForm1.PageControl1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
  if (Sender is TPageControl) then Accept := True;
end;

end.

Nyní již jen stačí po spuštění uchopit záložku a přesunout na libovolnou pozici. Vše se dá ještě vylepšit tím, že při ukončování aplikace si uložíme pořadí záložek a při příštím spuštění nabídneme uživateli jím nastavené pořadí.

Příklad samozřejmě funguje i v případě, že změníme styl komponenty PageControl a místo záložek (oušek) použijeme tlačítka.