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

Tipy a triky v Delphi, díl 91. - Vizuální témata Windows XP

Jan Šindelář - 21.5.2003

Vizuální témata Windows XP

Nový vzhled Windows se systémem "skinů" (témat) nejen že znechutil některé uživatele (a teď ponechme stranou jak velká část uživatelů to je), ale také přinesl některé problémy programátorům. O některých problémech s Delphi jsme zde již také kdysi hovořili, ale to je již naštěstí minulost a s příchodem Delphi 7 můžeme bez potíží (nebo dodatečných úprav) vizuálních témat v našich aplikacích snadno používat.

Přesto se ovšem může přihodit situace, kdy zkrátka aplikace nevypadá pod vlivem nových stylů pěkně. Ve starších verzích Windows je třeba vše v pořádku, ale styly Windows XP celé okno aplikace nějak nepěkně "rozhodí". Abychom na to mohli nějak reagovat, hodila by se nám funkce, která dokáže zjistit jestli jsou styly aktivní či ne. Naše aplikace pak podle toho může kupříkladu mírně upravit vlastnosti nějaké vizuální komponenty, která pod XP nevypadá úplně dokonale. Jednoduchý test, který by prostě ověřil je-li aplikace spuštěna pod Windows XP, samozřejmě nestačí, protože i pod Windows XP si může uživatel styly vypnout. Proto si na to musíme vytvořit zvláštní funkci. Vrací logickou hodnotu True nebo False a její použití vidíte v přiložením příkladu.

Další věc, která s problémem úzce souvisí, je detekce změny použitého stylu. Jak víte, změnit styl není pro uživatele nic obtížného a je to otázkou několika vteřin. I na takovou událost pak může naše aplikace příslušným způsobem reagovat. Tentokrát nám k tomu nebude sloužit funkce, ale systém zpráv Windows.

Společný zdrojový kód pro oba příklady tedy následuje zde:

unit Unit1;

interface

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

const
  WM_THEMECHANGED = $031A;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure WMTHEMECHANGED(var Msg: TMessage); message WM_THEMECHANGED;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function ThemeActive: Boolean;
const
  themelib = `uxtheme.dll`;
type
  TIsThemeActive = function: BOOL; stdcall;
var
  IsThemeActive: TIsThemeActive;
  huxtheme: HINST;
begin
  Result := False;
  if (Win32Platform  = VER_PLATFORM_WIN32_NT) and (((Win32MajorVersion = 5) and (Win32MinorVersion >= 1)) or (Win32MajorVersion > 5)) then
  begin
    huxtheme := LoadLibrary(themelib);
    if huxtheme <> 0 then
    begin
      try
        IsThemeActive := GetProcAddress(huxtheme, `IsThemeActive`);
        Result := IsThemeActive;
      finally
        if huxtheme > 0 then FreeLibrary(huxtheme);
      end;
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if ThemeActive then ShowMessage(`Temata jsou zapnuta.`)
                  else ShowMessage(`Temata jsou vypnuta.`);
end;

procedure TForm1.WMTHEMECHANGED(var Msg: TMessage);
begin
  ShowMessage(`Doslo ke zmene tematu.`);
  Msg.Result := 0;
end;

end.

Ještě připomínám, že za změnu tématu je považována nejen změna jako taková, ale též výběr jiného barevného profilu téhož tématu a nebo samozřejmě i jeho úplné vypnutí (přepnutí do klasického zobrazení) či naopak zapnutí.

Tolik tedy pro dnešek k vizuálním tématům Windows XP.