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

Tipy a triky v Delphi, díl 13. - Otevření zadaného adresáře v Průzkumníku Windows; Zobrazení dialogu "Otevřít v programu"; Zobrazení dialogu "Vlastnosti"; Adresářový strom; Zjištění cest k důležitým systémovým složkám; Zobrazení zkrácené cesty

Jan Šindelář - 17.10.2001

Otevření zadaného adresáře v Průzkumníku Windows

Průzkumník Windows. Možná jedna z prvních aplikací, na kterou začali uživatelé po vydání Windows 95 nadávat (tedy někteří; obzvláště ti, co byli zvyklí na klasický dvojitý panel jako má NC). Někdy se nám může v našich aplikacích hodit umět otevřít danou složku právě v Průzkumníkovi (jako standardní aplikaci pro práci se soubory ve Windows) a umožnit tak třeba uživateli provést nepřímo některé drobné úpravy, pokud to není zrovna "náplní práce" naší aplikace či zkrátka z jakéhokoliv jiného důvodu. Následující funkce, jejímž jediným parametrem je adresář, to zařídí:

.
.
.
uses ShellApi;
.
.
.

procedure UkazSlozku(Slozka : string);
begin
ShellExecute(Application.Handle, PChar(`explore`), PChar(Slozka), nil, nil, SW_SHOWNORMAL);
end;

Zobrazení dialogu "Otevřít v programu"

Tento tip je ze stejného soudku jako ten předchozí a vlastně i princip je stejný. Otevře známé dialogové okno se seznamem aplikací nainstalovaných v systému, ze kterých si můžete vybrat tu, pomocí které se otevře dosud neasociovaný (což nemusí nutně znamenat že neznámý) typ souboru. Parametrem procedury je soubor, který chceme otevřít.

procedure Otevrit(Soubor: String);
begin
ShellExecute(Application.Handle, `open`, PChar(`rundll32.exe`), PChar(`shell32.dll,OpenAs_RunDLL ` + Soubor), nil, SW_SHOWNORMAL);
end;

Zobrazení dialogu "Vlastnosti"

A do třetice. Ukážeme si, jak k danému souboru zobrazit známý systémový dialog Vlastnosti, který je obvykle přístupný přes kontextové menu pravého tlačítka.

procedure Vlastnosti(Soubor:String);
var
  sei: TShellExecuteInfo;
begin
  FillChar(sei, SizeOf(sei), 0);
  sei.cbSize := SizeOf(sei);
  sei.lpFile := PChar(Soubor);
  sei.lpVerb := `properties`;
  sei.fMask  := SEE_MASK_INVOKEIDLIST;
  ShellExecuteEx(@sei);
end;

Adresářový strom

Zobrazování souborů v adresářovém stromu zná dobře asi každý uživatel Windows. Ukážeme si teď, jak na to. Náš příklad je zjednodušen tím, že budeme zobrazovat pouze názvy souborů a adresářů bez jejich odpovídajících ikonek. To však není problém případně dodělat, pokud budete chtít. Něčemu podobnému jsme se zde již věnovali, takže inspiraci máte.

Nyní tedy již vlastní zdrojový kód:

procedure GetDirectories(Tree: TTreeView; Directory: string; Item: TTreeNode; IncludeFiles: boolean);
var
  SearchRec: TSearchRec;
  ItemTemp:  TTreeNode;
begin
  Tree.Items.BeginUpdate;
  if Directory[length(Directory)] <> `\` then Directory := Directory + `\`;
  if FindFirst(Directory + `*.*`, faDirectory, SearchRec) = 0 then
  begin
    repeat
      if (SearchRec.Attr and faDirectory = faDirectory) and (SearchRec.Name[1] <> `.`) then
      begin
        if (SearchRec.Attr and faDirectory > 0) then
          Item := Tree.Items.AddChild(Item, SearchRec.Name);
        ItemTemp := Item.Parent;
        GetDirectories(Tree, Directory + SearchRec.Name, Item, IncludeFiles);
        Item := ItemTemp;
      end
      else if IncludeFiles then
        if SearchRec.Name[1] <> `.` then
          Tree.Items.AddChild(Item, SearchRec.Name);
    until FindNext(SearchRec) <> 0;
    FindClose(SearchRec);
  end;
  Tree.Items.EndUpdate;
end;

Parametry procedury obsahují jednak strom - TreeView -, který se má použít, dále adresář, případně konkrétní větev a logickou proměnnou, udávající zda se mají či nemají zobrazit též soubory.

Proceduru můžeme například použít v následující ukázce, která zobrazí strom disku C: včetně souborů. Předpokladem je, že Váš projekt obsahuje již připravenou komponentu TreeView (zde konkrétně TreeView1).

procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
GetDirectories(TreeView1, `C:\`, nil, True);
end;

Zjištění cest k důležitým systémovým složkám

Často se naskytne potřeba přistupovat k různým systémovým složkám. S prostým předpokladem, že se na každém počítači nachází adresář Windows v kořenovém adresáři disku C a z toho odvozovat vše ostatní je samozřejmě naprostý nesmysl a daleko bychom se nedostali, protože Vám samozřejmě při instalaci nic nebrání v tom, umístit složku Windows, kam si jen vzpomenete. Proto tu máme jednu šikovnou funkci, která nám tyto důležité systémové cesty zjistí (pokud existují). Budeme potřebovat knihovnu Shlobj a jako obvykle si uvedeme příklad v podobě události stisknutí tlačítka.

.
.
.
uses Shlobj;
.
.
.

procedure TForm1.Button1Click(Sender: TObject);
var
  pidl: PItemIDList;
  cesta: array[0..MAX_PATH] of char;
begin
  SHGetSpecialFolderLocation(Handle, CSIDL_HISTORY, pidl);
  SHGetPathFromIDList(pidl,cesta);
  ShowMessage(cesta);
end;

Nejdůležitějším parametrem celé ukázky je CSIDL_HISTORY, což je zrovna v tomto konkrétním příkladě nadefinovaná konstanta pro adresář History. Příklad by tedy nebyl úplný bez kompletního seznamu konstant pro ostatní složky, takže zde jej máme:

CSIDL_DESKTOP
CSIDL_INTERNET
CSIDL_PROGRAMS
CSIDL_CONTROLS
CSIDL_PRINTERS
CSIDL_PERSONAL
CSIDL_FAVORITES
CSIDL_STARTUP
CSIDL_RECENT
CSIDL_SENDTO
CSIDL_BITBUCKET
CSIDL_STARTMENU
CSIDL_DESKTOPDIRECTORY
CSIDL_DRIVES
CSIDL_NETWORK
CSIDL_NETHOOD
CSIDL_FONTS
CSIDL_TEMPLATES
CSIDL_COMMON_STARTMENU
CSIDL_COMMON_PROGRAMS
CSIDL_COMMON_STARTUP
CSIDL_COMMON_DESKTOPDIRECTORY
CSIDL_APPDATA
CSIDL_PRINTHOOD
CSIDL_ALTSTARTUP
CSIDL_COMMON_ALTSTARTUP
CSIDL_COMMON_FAVORITES
CSIDL_INTERNET_CACHE
CSIDL_COOKIES
CSIDL_HISTORY

Překládat jednotlivé položky asi nemá smysl, protože buď je jejich název jasný a nebo se vyskytuje v této podobě i v české verzi Windows.

Zobrazení zkrácené cesty

A na závěr tu máme jeden, troufám si tvrdit, velice užitečný tip opravdu pro každého. Často se stává, že celková cesta i samotný název souboru jsou dohromady natolik dlouhé, že se nevejdou celé do titulků oken a různých dalších zobrazovacích prvků aplikace. V tom případě se takto dlouhý název ořízne a konec není vidět. To je v tom horším případě. Mnohem lepší řešení, které by jste měli používat, je tzv. zkrácený název. Sami jistě dobře víte oč se jedná, celý dlouhý řetězec se upraví tak, že je vidět jen ta nejdůležitější část a ten méně podstatný zbytek je nahrazen trojicí teček. Nyní si ukážeme jak na to. Není třeba vymýšlet žádné vlastní složité postupy, pomůže nám knihovna FileCtrl.

Předpokládejme, že máte například někde na hlavním formuláři aktuální adresář uložen v běžně používané komponentě Label. Lépe řečeno, řetězec s celou cestou aktuálního adresáře potřebujete vměstnat do Labelu. Nejprve nastavte jeho vlastnost Autosize na False a poté ručně zvolte vhodnou maximální délku. Nyní již zbývá jen upravit samotný řetězec, který poté necháme Label zobrazit. Ten upravíme tímto jedním řádkem:

Label1.Caption:=MinimizeName(Cesta, Label1.Canvas,Label1.Width);

Proměnná Cesta je typu String a obsahuje původní celou a nezkrácenou cestu. Ve výsledném Labelu se již zobrazí výsledný zkrácený řetězec.