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

Tipy a triky v Delphi, díl 66. - Restart Exploreru; Načtení ikony CD; Je přihlášen administrátor ?

Jan Šindelář - 13.11.2002

Restart Exploreru

Explorerem v tomto případě není míněn Internet Explorer, ale programový manažer systému, tedy vlastně celé uživatelské prostředí. Sice netuším, k čemu přesně by se tato funkce v běžných aplikacích dala využít, ale restartování Exploreru provedete následujícím jednoduchým postupem:

procedure TForm1.Button1Click(Sender: TObject);
  var
    hwndShell: hwnd;
begin
  hwndShell := FindWindow(`Progman`, nil);
  PostMessage(hwndShell, WM_QUIT, 0, 0);
  ShellExecute(0, `open`, `Explorer`, nil, nil, SW_SHOWNORMAL);
end;

K fungování tohoto příkladu je nutné přidat do projektu knihovnu ShellAPI.

Načtení ikony CD

Následující tip je opět velmi jednoduchý a navíc i v reálných aplikacích hodně použitelný. Ukážeme si, jak načíst z vloženého disku CD jeho ikonu, pokud takovou samozřejmě obsahuje. Tato ikona se dá najít v souboru autorun.inf, přesněji řečeno cesta k této ikoně, a pokud vložené CD takovou ikonu obsahuje, programy jako je Průzkumník či jiné souborové manažery ji zobrazí místo obrázku "obyčejného" CD. Jak vidíte ze zdrojového kódu, celá záležitost je vlastně velmi primitivní. Pokud CD obsahuje soubor autorun.inf, což je vlastně obyčejný INI soubor, nahlédneme do něj a zjistíme, zda je zde odkaz na ikonu. Pokud ano, najdeme ji na disku a načteme. Funkce tedy v případě úspěchu vrací obrázek ikony a s ním již pak můžete běžným způsobem pracovat. Jediným vstupním parametrem funkce je písmeno CD mechaniky, ze které chceme ikonu přečíst. V ukázce vidíte i jednoduchý příklad použití pomocí komponenty Image a ještě připomínám, že kvůli využívání funkcí pro práci s INI soubory je třeba přidat do projektu knihovnu Inifiles.

function GetCDIcon(Drive: Char): TIcon;
var
  ico: TIcon;
  ini: TIniFile;
  s: string;

begin
  Result := nil;
  if not FileExists(Drive + `:\autorun.inf`) then Exit;
  ini := TIniFile.Create(Drive + `:\autorun.inf`);
  ico := TIcon.Create;
  try
    s := ini.ReadString(`Autorun`, `ICON`, ``);
    if s = `` then Exit;
    if FileExists(s) then ico.LoadFromFile(s);
    if FileExists(Drive + `:\` + s) then ico.LoadFromFile(Drive + `:\` + s);
    Result := ico;
  finally
    ini.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Image1.Picture.Icon := GetCDIcon(`w`);
end;

Je přihlášen administrátor ?

Tak přesně na tuto otázku nám odpoví dnešní poslední funkce. Často je pro programy důležité vědět, jestli právě přihlášený uživatel má administrátorská práva, protože některé funkce programu pak podle toho mohou či nemusí být přístupné. K tomuto testu tedy slouží následující funkce, která vrací True v případě administrátorských práv.

function IsAdmin: Boolean;
var
  hAccessToken: THandle;
  ptgGroups: PTokenGroups;
  dwInfoBufferSize: DWORD;
  psidAdministrators: PSID;
  x: Integer;
  bSuccess: BOOL;
begin
  Result := False;
  bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, hAccessToken);
  if not bSuccess then
    if GetLastError = ERROR_NO_TOKEN then bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken);
  if bSuccess then
  begin
    GetMem(ptgGroups, 1024);
    bSuccess := GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, 1024, dwInfoBufferSize);
    CloseHandle(hAccessToken);
    if bSuccess then
    begin
      AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdministrators);
      {$R-}
      for x := 0 to ptgGroups.GroupCount - 1 do
        if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
        begin
          Result := True;
          Break;
        end;
      {$R+}
      FreeSid(psidAdministrators);
    end;
    FreeMem(ptgGroups);
  end;
end;

Příklad bude fungovat i pod Windows 9x, přesněji řečeno, funkce nezpůsobí žádné chybové hlášení, takže není problém s případnou zpětnou kompatibilitou.