Hrajeme si na Explorer - 1. díl - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

Hrajeme si na Explorer - 1. díl

11. září 2001, 00.00 | Tímto článkem zahajujeme nový seriál. Jeho konečným cílem bude sestavit aplikaci, která bude umět zobrazovat soubory v adresářích obdobně jako program Explorer, včetně různých režimů zobrazení a třídění.

Úvod

Nedávno jsem na Builderu napsal článek o tom, jak získat handle ikony asociované k souboru. Použil jsem k tomu funkci SHGetFileInfo. V diskuzi pod článkem se objevily názory (oprávněné), že na toto existují i jiné funkce s jednodušším použitím. Já jsem namítal, že SHGetFileInfo toho umí víc, něž jen získat handle ikony. A odtud už byl jen krůček ke vzniku tohoto seriálu.

Cílem bude sestavit aplikaci, která bude umět zobrazovat soubory v adresářích obdobným způsobem jako v klasických složkách ve Windows - tedy jako program Explorer. Ukážeme si na nejenom, co všechno umí zmiňovaná funkce SHGetFileInfo, ale i několik dalších užitečných postupů. Celkově je seriál koncipován spíš pro začínající či mírně pokročilé programátory v Delphi, ale inspiraci v něm jistě najdou i odborníci.

Na konci každého dílu bude k dispozici ke stažení program v té fázi, k jaké vývoj zatím dospěl. V dnešním - prvním - dílu se podíváme na úplný základ. Uděláme výpis souborů ve formě "velkých ikon", zatím nijak netříděný ani jinak upravený - na to dojde později.

Jdeme na to

"Explorer"

Na obrázku vidíte, jak bude vypadat výsledek dnešního snažení (málem jsem napsal smažení :-). Vytvoříme novou aplikaci a přidáme tam několik ovládacích prvků a komponent. Ty nejdůležitější jsou tyto:

  • DirEdit: TEdit - sem budeme zadávat adresář, který chceme zobrazit. Doporučuji do vlastnosti Text nějaký adresář pro začátek nastavit jako defaultní.
  • ShowBtn: TButton - tlačítko, po jehož stisknutí se zobrazí výpis souborů v daném adresáři
  • FileView: TListView - zde se budou zobrazovat soubory. Pro dnešní díl je třeba nastavit ViewStyle na hodnotu vsIcon.
  • LargeFileImages: TImageList - zde budou ikony zobrazovaných souborů, je velice důležité nastavit vlastnost ShareImages na True (vysvětlím za chvíli)! Width a Height nastavíme na 32. Tuto komponentu přiřadíme jako vlastnost LargeImages u FileView.

Tak, snad jsem nic důležitého nevynechal. Teď ke způsobu, jakým budeme získávat ikony jednotlivých souborů. Windows si udržují v paměti systémový seznam ikonek ke všem typům souborů, na které jste od jejich spuštění narazili. Tento seznam ikon (image list) se dá v Delphi ovládat pomocí komponenty TImageList. Musíme ale nějak zjistit handle tohoto systémového seznamu ikon a přiřadit ho do vlastnosti Handle naší komponenty. A ono zjištění handle za nás udělá právě funkce SHGetFileInfo. Malé opakování - její deklarace (v unitě ShellAPI):

function SHGetFileInfo(pszPath: PAnsiChar; dwFileAttributes: DWORD; 
  var psfi: TSHFileInfo; cbFileInfo, uFlags: UINT): DWORD; stdcall;

Funkce umí zjišťovat různé informace o souboru, který předáme v parametru pszPath. Takřka všechny informace jsou předány ve struktuře psfi (do cbFileInfo musíme zapsat její velikost). Pomocí parametru uFlags říkáme, co vlastně chceme vědět (pomocí součtu několika speciálních konstant).

Letmým pohledem do Win32 API nápovědy zjistíme, že pokud v uFlags uvedeme konstantu SHGFI_SYSICONINDEX, v položce psfi.iIcon získáme index ikony daného souboru v systémovém seznamu ikon a návratovou hodnotou funkce bude handle tohoto seznamu. To je přesně, co chceme. Jelikož o index v seznamu nám ve skutečnosti nejde, můžeme použít libovolný soubor - nabízí se třeba EXE soubor naší aplikace. Celou proceduru pak umístíme do události OnCreate hlavního formuláře. Ještě bych dodal, že k uFlags přidáme i konstantu SHGFI_LARGEICON, aby bylo jasné, že chceme handle k seznamu velkých ikon (nikoliv malých - 16x16 bodů).

var
  SFI: TSHFileInfo; // deklarujeme globálně, budeme potřebovat vícekrát

procedure TForm1.FormCreate(Sender: TObject);
begin
  LargeFileImages.Handle := SHGetFileInfo
    PChar(Application.ExeName), // jelikož nám jde o handle ImageListu,
    0,                          // můžeme použít libovolný soubor - třeba
    SFI, SizeOf(SFI),           // "exáč" aplikace
    SHGFI_SYSICONINDEX + SHGFI_LARGEICON
  );
end;

Ještě dlužím vysvětlení, proč jsme na počátku u LargeFileImages nastavovali vlastnost ShareImages na True. Důvodem je, že normálně tato komponenta při ukončení aplikace maže seznam ikon, který obsahuje, z paměti. Asi si dokážete představit, co by to způsobilo za chaos, kdyby toto udělala se seznamem všech ikon v systému (můžete si to klidně vyzkoušet). Proto seznam ikon prohlásíme za sdílený a komponenta ho při ukončení nesmaže.

Zobrazení souborů

Nyní, když už máme handle systémového seznamu ikon, můžeme se vrhnout na proceduru zajišťující zobrazení jednotlivých souborů. Bude "pověšená" na události OnClick tlačítka ShowBtn. Princip je vcelku jednoduchý. Nejdřív vymažeme všechny existující položky v FileView a pak budeme prohledávat soubory a podadresáře v daném adresáři. Na to budeme používat standardní funkce FindFirst, FindNext a FindClose. Myslím, že je tu nemusím nějak vysvětlovat, každý Delphař je snad zná.

Pro každý nalezený soubor přidáme jednu položku do FileView. Možná jste si všimli, že v Exploreru ve Windows bývají soubory vypsány bez přípony (i když to závisí na nastavení u konkrétního typu) a s prvním písmenem velkým. Potěšující zpráva je, že s úpravou jména se nemusíme vůbec zatěžovat - udělá to za nás funkce SHGetFileInfo, stačí do parametru uFlags přidat konstantu SHGFI_DISPLAYNAME. Výsledek (upravené jméno souboru a la Explorer) najdeme v položce szDisplayName předávané struktury TSHFileInfo. Samozřejmě k uFlags přidáme i vlajky SHGFI_SYSICONINDEX a SHGFI_LARGEICON, abychom v položce iIcon zmíněné struktury měli index ikony daného souboru, který zapíšeme do vlastnosti ImageIndex příslušné položky.

Procedura tedy vypadá takto:

procedure TForm1.ShowBtnClick(Sender: TObject);
var
  Found: Integer;
  SearchRec: TSearchRec;
begin
  // odstraníme všechny položky
  FileView.Items.Clear;
  // zahájíme hledání
  Found := FindFirst(DirEdit.Text + '\*.*', faAnyFile - faVolumeID, SearchRec);
  // opakujeme, dokud existují vyhovující soubory
  while Found = 0 do
  begin
    if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then
      with FileView.Items.Add do // přidíme položku
      begin
        SHGetFileInfo
          PChar(DirEdit.Text + '\' + SearchRec.Name), // cesta k souboru
          0,                                          // atributy - žádné
          SFI, SizeOf(SFI),                           // struktura TSHFileInfo
          // vlajky: chceme získat index velké ikony a jméno souboru
          SHGFI_SYSICONINDEX + SHGFI_LARGEICON + SHGFI_DISPLAYNAME
        );
        Caption := SFI.szDisplayName; // nastavíme název
        ImageIndex := SFI.iIcon;      // a index ikony
      end;
    Found := FindNext(SearchRec);
  end;
  // konec hledání
  FindClose(SearchRec);
end;

Závěr

Dnes jsme vytvořili úplný základ aplikace (ke stáhnutí zde), příště se podíváme na další způsoby zobrazení - v Exploreru nazývané "Malé ikony", "Seznam" a "Podrobnosti".

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: