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

Tipy a triky v Delphi, díl 189. – seznam písem v ComboBoxu

Jan Šindelář 15.6.2005

Dnešní tip opět vylepší uživatelskou přívětivost našich aplikací. Konkrétně si dnes ukážeme jednoduchý tip, kdy podobně jako Word či jiné textové editory zobrazíme seznam písem v ComboBoxu přímo v daném písmu. I tentokrát se tedy bude jednat spíše o tip pro začátečníky.

Funkci, kdy textový editor či jiné aplikace umožňují uživatelům přímo vidět nejen názvy fontů, ale přímo jejich vzhled při výběru v ComboBoxu, považuji za velmi podařený nápad a značným způsobem usnadňuje práci. Proto se dnes naučíme toto vylepšení implementovat i do našich aplikací.

Postup je poměrně jednoduchý. Nejprve umístíme na formulář ComboBox (či jinou obdobnou komponentu), který bude seznam fontů zobrazovat. Jelikož za běžných podmínek jsou prvky ComboBoxu obvykle textové řetězce a všechny jsou navíc zobrazeny stejným písmem, je jasné, že se budeme muset tentokrát o vykreslování seznamu postarat sami. Opět se tedy dostáváme k tématu uživatelsky kreslených objektů. To nám umožní vložit do ComboBoxu prakticky libovolný obsah, tedy nejen text, ale i grafiku a nebo může být každý řádek psán jiným fontem jako v našem případě.

V Object Inspectoru tedy nastavíme pro náš ComboBox v parametru Style hodnotu csOwnerDrawFixed. Pro náš příklad zvolíme pevnou (stejnou) výšku řádků pro každý prvek. Pokud bychom ComboBox plnili například různě velkými obrázky, nastavili bychom hodnotu csOwnerDrawVariable. V takovém případě by pak byla volána pro každý z prvků zvlášť událost OnMeasureItem pro nastavení příslušné velikosti.

Přepnutím stylu do tohoto "uživatelsky kresleného módu" si tedy otvíráme možnosti pro vlastní tvořivost. Kdykoliv je třeba prvek ComboBoxu vykreslit, pošle systém naší aplikaci příslušnou zprávu, což následně vyvolá událost OnDrawItem, ve které už se pak my postaráme o zbytek.

Před samotným vykreslováním, které už je pak samo o sobě velmi jednoduché, zbývá ještě jeden zdánlivě komplikovaný problém. Kde vzít seznam v systému dostupných fontů a jejich názvy? Pomůže nám objekt TScreen, o němž jsme si povídali skoro přesně před rokem ve 145. dílu seriálu. Ten udržuje (mimo jiné) právě seznam dostupných fontů, takže jej použijeme k naplnění našeho ComboBoxu a to například v události OnCreate formuláře.

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
  for i := 0 to Screen.Fonts.Count - 1 do ComboBox1.Items.Add(Screen.Fonts.Strings[i]);
end;

procedure TForm1.ComboBox1DrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  with (Control as TComboBox).Canvas do
    begin
      Font.Name := Screen.Fonts.Strings[Index];
      FillRect(Rect);
      TextOut(Rect.Left, Rect.Top, PChar(Screen.Fonts.Strings[Index]));
    end;
end;

end.

A tím je náš dnešní příklad hotov. Pro lepší efekt bych doporučil o něco zvětšit velikost písma v ComboBoxu (a příslušným způsobem rovněž výšku řádku), aby byly fonty lépe viditelné. Jako obvykle si můžete stáhnout ukázkový projekt.