Tipy a triky v Delphi, díl 4.

V dnešním díle našeho malého seriálu si nejprve ukážeme pár triků s Taskbarem a ikonami na ploše, naučíme se do svých aplikací přidat startovací logo (tzv. splashscreen) a detekci stisknuté klávesy při startu. No a nakonec si zkusíme "deaktivovat" tlačítko na ukončení aplikace.
Hrátky s Taskbarem a tlačítkem Start

Určitě jste již viděli, že během instalace různých aplikací dojde nejen k maximalizaci instalačního programu na celou obrazovku, ale pro větší efekt zmizí i Taskbar (Hlavní panel). Někdy se nám prostě může hodit, aby tento "rušivý" element" nekazil dojem z naší krásné aplikace. :)

Jak tedy na to? Pomůžou nám v tom dvě funkce z Windows API. První z nich, FindWindow, zjistí handle k Taskbaru a druhá funkce, ShowWindow, zase s patřičnými parametry zajistí jeho zmizení.

procedure SchovejTaskbar;
var hTaskBar : THandle;
begin
hTaskbar := FindWindow(`Shell_TrayWnd`, Nil);
ShowWindow(hTaskBar, SW_HIDE);
end;

procedure UkazTaskbar;
var hTaskBar : THandle;
begin
hTaskbar := FindWindow(`Shell_TrayWnd`, Nil);
ShowWindow(hTaskBar, SW_SHOWNORMAL);
end;

Další na řadě je tlačítko Start. Naučíme se, jak znemožnit jeho stisknutí, i když tento tip patří již opravdu spíše do kategorie kuriozit a vážně mě nenapadá způsob jeho seriózního využití. Nutno ještě poznamenat, že ono "znemožnění stisknutí" se týká pouze myši, protože pokud použijete příslušné tlačítko na klávesnici, Startmenu se objeví.

procedure DeaktivujTlacitkoStart;
begin
EnableWindow(FindWindowEx(FindWindow(`Shell_TrayWnd`, nil),0,`Button`,nil),false);
end;

procedure AktivujTlacitkoStart;
begin
EnableWindow(FindWindowEx(FindWindow(`Shell_TrayWnd`, nil),0,`Button`,nil),true);
end;

Pracovní plocha a ikony

Následující příklad nám ukáže, jak si drobně vylepšit pracovní plochu. Opět je to asi jeden z tipů, který mnoho z vás nepoužije (leda byste programovali nějakou šikovnou utilitu na úpravu Windows), ale přesto bude zajímavé si o něm říci.

O co se tedy bude konkrétně jednat? Naučíme se měnit barvu podkladu a textu ikon, a hlavně se naučíme, jak docílit toho, aby byl text ikon transparentní. V základní konfiguraci Windows, bez použití dalších pomocných programů, vypadá pracovní plocha docela nepěkně, protože i když si zvolíte hezkou tapetu, celý efekt nám kazí nevzhledné popisky ikon, u kterých nelze nastavit transparentnost (průhlednost). Naučíme se tedy, jak tyto parametry měnit.

Napíšeme si dvě procedury. Jedna bude mít za úkol měnit nastavení barev podle chuti, druhá vrátí vše do původního stavu. Připomínám, že nesmíte zapomenout přidat do Uses knihovnu CommCtrl.

.
.
.
uses CommCtrl;
.
.
.

procedure SetDesktopIconColor(BarvaTextu, BarvaPozadi: TColor; Trans: Boolean);

var Window: HWND;

begin
Window := FindWindow(`Progman`, `Program Manager`);
Window := FindWindowEx(Window, HWND(nil), `SHELLDLL_DefView`, ``);
Window := FindWindowEx(Window, HWND(nil), `SysListView32`, ``);
if Trans then ListView_SetTextBkColor(Window, $ffffffff)
        else ListView_SetTextBkColor(Window, BarvaPozadi);
ListView_SetTextColor(Window, BarvaTextu);
ListView_RedrawItems(Window, 0, ListView_GetItemCount(Window) - 1);
UpdateWindow(Window);
end;

Parametry procedury jsou, myslím, jasné a netřeba dalšího vysvětlování. Jak to vlastně funguje ? Nejprve najdeme "okno", kde se ikony nalézají (funkce FindWindow a FindWindowEx). Je to potomek Program Manageru a obsahuje ListView, kde jsou uloženy všechny ikony plochy. Jejich parametry poté jen změníme podle našich požadavků.

Následující procedurou vrátíme vše zase zpět (tak, jak to mají Windows uloženo v nastavení):

procedure NastavPuvodniBarvy;
var
  Druh: Integer;
  Barva: TColor;
begin
  Druh := COLOR_DESKTOP;
  Barva := GetSysColor(COLOR_DESKTOP);
  SetSysColors(1, Druh, Barva);
end;

Téhož lze dosáhnout i tím, že zvolíme Obnovit v kontextovém menu pracovní plochy.

Startovací logo - Splashscreen

Tento tip už je o poznání užitečnější než předchozí a využít ho ve svých aplikacích může téměř kdokoliv. Oč se vlastně přesně jedná? Myslím, že vysvětlovat není co, všichni to znáte a vidíte každý den. Aplikace během startu, při kterém kupříkladu načítá nastavení, zobrazí své logo (tzv. splashscreen), kde může být zobrazen kromě (někdy) hezkého obrázku i třeba průběh načítání či podobné užitečné informace. Je to rozhodně lepší než "prázdná" obrazovka, kdy si uživatel nemůže být jist, co se vlastně děje.

Avšak pozor na to, aby startovací logo nezdržovalo samotný start aplikace. Mám tím na mysli to, že program, který má několik desítek kilobajtů, během startu nic nenačítá a je spuštěn během chvíle, vlastně žádné úvodní logo nepotřebuje. Dávat ho tam pouze pro efekt sice můžete, ale pamatujte, že by mělo zmizet co nejrychleji. Uživatel je zvědav na vaši aplikaci a ne na vaše logo.

Zde je tedy postup:

- Nejprve si do našeho projektu přidáme nový formulář (v našem příkladu se bude jmenovat Logo), na který můžete umístit, cokoliv vás napadne. Nejčastěji to bude komponenta Timage, která bude vyplňovat celý formulář a bude obsahovat vaše logo v podobě obrázku. Asi bude též vhodné nastavit vlastnosti formuláře tak, aby nebyl vidět pruh s titulkem okna (vlastnost BorderStyle nastavíme na bsNone).

- Dále je nutné zajistit, aby tento formulář nebyl automaticky vytvořen po startu aplikace, ale abychom jeho zobrazení měli pod kontrolou my. Toho dosáhneme tak, že si otevřeme vlastnosti projektu (menu Project->Options). Zde na kartě Forms vidíme dva seznamy, Auto-create forms a Available forms. Zatím budou všechny vaše dosud vytvořené formuláře projektu pravděpodobně pod Auto-create včetně Loga. Příslušnou šipkou přesuneme formulář loga mezi Available forms.

- Když máme takto náš formulář připraven k použití, přistoupíme k vlastní úpravě kódu. Otevřeme si projektový soubor naší aplikace (přípona .dpr) a upravíme jej nějak takto:

program Project1;

uses
  Forms,
  Unit1 in `Unit1.pas` {Form1},
  Logo in `Logo.pas` {Logo};

{$R *.RES}

begin
Logo := TLogo.Create(nil);
Logo.Show;

{sem přijde váš kód}

Application.Initialize;
Application.CreateForm(TForm1, Form1);

Logo.Hide;
Logo.Release;

Application.Run;

end.

Mezi Logo.Show a Logo.Hide umístíme (kromě Application.Initialize a Application.CreateForm) tu část kódu programu, která se stará o např. již zmiňované načtení nastavení apod., zkrátka tu činnost, která se bude skrytě provádět během zobrazení loga. Poté logo schováme (příkazem Logo.Hide a Logo.Release) a až na úplný závěr příkazem Application.Run spustíme samotný program.

Detekce stisknuté klávesy během startu aplikace

Tato funkce trošku souvisí s předchozím tipem. Ukážeme si, jak otestovat, zda byla během startu aplikace stisknuta daná klávesa. Využití je různé, aplikace se může např. spustit ve speciálním módu apod.

Opět musíme upravit projektový soubor aplikace. Nejprve přidáme do Uses knihovnu Windows, jejíž funkci GetKeyState budeme potřebovat. Poté přidáme do kódu samotný test ještě před Application.Initialize, takže můžeme náš předchozí příklad se startovacím logem rozšířit asi takto:

program Project1;

uses
  Forms, Windows,
  Unit1 in `Unit1.pas` {Form1},
  Logo in `Logo.pas` {Logo};

{$R *.RES}

begin
Logo := TLogo.Create(nil);
Logo.Show;

if GetKeyState(vk_F8) < 1 then MessageBox(0,`Během startu bylo stisknuto F8`,`Pozor`,mb_ok);

Application.Initialize;
Application.CreateForm(TForm1, Form1);

Logo.Hide;
Logo.Release;

Application.Run;

end.

V našem příkladu se při stisku klávesy F8 objeví jednoduché upozornění. Samozřejmě je to pouze pro názornost a nemusím snad připomínat, že můžete doplnit libovolný kód.

Jak vyřadit z činnosti tlačítko Close

Potřebujete, aby vaše aplikace nešla ukončit? Pak vám může pomoci následující tip, který znemožní použití uzavíracího tlačítka okna a odstraní položku Zavřít ze systémového menu okna. V kombinaci s vhodným přesměrováním klávesové zkratky ALT-F4 v nastavení událostí hlavního formuláře a za použití triku, který schová aplikaci po stisku CTRL-ALT-DEL (viz druhý díl našeho seriálu), se stane aplikace (téměř) neukončitelnou. :)

procedure DisableClose(okno:string);
var hwndHandle : THANDLE;
    hMenuHandle : HMENU;

begin
hwndHandle := FindWindow(nil, okno);
if (hwndHandle <> 0) then
begin
  hMenuHandle := GetSystemMenu(hwndHandle, FALSE);
  if (hMenuHandle <> 0) then DeleteMenu(hMenuHandle, SC_CLOSE, MF_BYCOMMAND);
end;
end;

Parametrem procedury je titulek okna, na který chceme trik aplikovat. Z toho vyplývá jedna důležitá věc: že můžete nechat deaktivovat tlačítko Close u libovolné běžící aplikace. Bohužel, opět nefunkční pod Windows 2000.

Co bude příště ?

Ukážeme si, jak restartovat či vypnout počítač, jak toto detekovat ve svých aplikacích a jak spouštět a ukončovat cizí aplikace.
Diskuze (10) Další článek: Intel Itanium základem jednoho z nejvýkonnějších vědeckých výpočetních systémů

Témata článku: , , , , , , , , , , , , , , , ,