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

Tipy a triky v Delphi, díl 47. - Vlastní položky v kontextovém menu aplikace v taskbaru; Test platnosti ISBN

Jan Šindelář - 3.7.2002

Vlastní položky v kontextovém menu aplikace v taskbaru

U běžné aplikace je na hlavním panelu (taskbaru) zobrazena její ikona či spíše tlačítko s ikonou. Tím máme přehled o spuštěných programech a pochopitelně tak můžeme i mezi aplikacemi přepínat. Poklepáním pravým tlačítkem na toto "tlačítko" se zobrazí kontextové menu, které obsahuje podle dané aplikace rozličné obvyklé funkce jako je například Zavřít, Minimalizovat, Přesunout atd.. Menu je velmi podobné tomu, které se zobrazí po poklepání na titulkový pruh aplikace (avšak pozor, je pouze podobné, nejedná se o stejné menu). A právě do tohoto systémového menu, které se zobrazuje na hlavním panelu, se naučíme přidat vlastní položky.

Celou věc opět řeší systém zpráv Windows. Vytvoříme si vlastní obsluhu volání Application.OnMessage, ve které budeme poté testovat vyvolání kontextového menu a zda byla vybrána námi přidaná položka. Na základě toho bude provedena příslušná akce, což bude v našem případě prostý výpis textu.

.
.
.

private
    { Private declarations }
    procedure OnAppMessage(var Msg: TMsg; var Handled: Boolean);
.
.
.
const
  SC_MyMenuItem = WM_USER + 1;
.
.
.

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := OnAppMessage;
  AppendMenu(GetSystemMenu(Application.Handle, FALSE), MF_SEPARATOR, 0, ``);
  AppendMenu(GetSystemMenu(Application.Handle, FALSE), MF_STRING, SC_MyMenuItem, `&Naše položka`);
end;

procedure TForm1.OnAppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.message = WM_SYSCOMMAND) and (Msg.wParam = SC_MyMenuItem) then
begin
  ShowMessage(`Byla vybrána naše položka z menu`);
  Handled := True;
end;
end;

Test platnosti ISBN

Tento tip nebude jistě pro každého, spíše pro velmi malou skupinku čtenářů, kteří hned bez přemýšlení vědí, co to zkratka ISBN vůbec znamená. Ne, není to žádná z nepřeberného množství počítačových zkratek. ISBN je zkratka pro mezinárodní unikátní číslo pro knihy, které se tak dají lépe strojově zpracovávat. Pokud sáhnete do své knihovny pro libovolnou knihu měla by na lícové straně vazby (nebo na jiném místě) toto číslo obsahovat. Záměrně píši "měla by obsahovat", protože nejsem žádný knihovník ani odborník na knihy, takže si nejsem jist, jestli neexistují nějaké výjimky. Z oficiálních zdrojů jsem se dozvěděl, že se tato metoda používá již 30 let, takže logicky starší knihy kód neobsahují. Zároveň některé země nemusí tento standard podporovat, takže pokud máte nějaký unikát z velmi cizokrajné a izolované země, zřejmě ani na takové knize kód nenajdete. 159 zemí civilizovaného světa však tento systém již desítky let používají.

Funkce, kterou si teď ukážeme, testuje platnost zadaného ISBN, neboť toto číslo (podobně jako například rodné číslo) musí splňovat jisté parametry. Pokud tedy kupříkladu programujete nějakou databázi knih, může se vám tato funkce hodit jako kontrola vstupních dat. Za správnost algoritmu neručím, neboť nejsem jeho autorem, ale na náhodně vybraném vzorku knih v mojí knihovně vše fungovalo bez problému. Kód ISBN, který je předáván funkci jako parametr, se zadává včetně pomlček, které obsahuje.

function IsISBN(ISBN: String): Boolean;
var
  Number, CheckDigit: String;
  CheckValue, CheckSum, Err: Integer;
  i, Cnt: Word;
begin
Result := False;
CheckDigit := Copy(ISBN, Length(ISBN), 1);
Number := Copy(ISBN, 1, Length(ISBN) - 2);
if (Length(Number) = 11) and (Pos(CheckDigit, `0123456789X`) > 0) then
begin
  if (CheckDigit = `X`) then CheckSum := 10
  else Val(CheckDigit, CheckSum, Err);
  Cnt := 1;
  for i := 1 to 12 do
    begin
    if (Pos(Number[i], `0123456789`) > 0) then
      begin
      Val(Number[i], CheckValue, Err);
      CheckSum := CheckSum + CheckValue * (11 - Cnt);
      Inc(Cnt);
      end;
    end;
  if (CheckSum mod 11 = 0) then Result := True;
end;
end;