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

Tipy a triky v Delphi, díl 20. - Třídění položek v ListView; Přidání položky do seznamu naposledy otevřených dokumentů; Smazání souboru do koše; Zjištění celkové fyzické paměti; Volná fyzická paměť; Virtuální paměť

Jan Šindelář - 5.12.2001

Třídění položek v ListView

Pokud často používáte k zobrazování dat různé tabulky či seznamy v podobě ListView, jistě se vám bude hodit následující tip. Pokud použijete ListView bez dalších dodatečných úprav, klikáním na hlavičky jednotlivých sloupců (v případě, že máte zvolen typ zobrazení vsReport) se nestane nic. Mnohem užitečnější a také častěji používaná varianta je ta, že se po kliknutí na danou hlavičku položky setřídí podle zvoleného sloupce, a to buď vzestupně (po prvním kliknutí), nebo sestupně (po následujícím kliknutí). A přesně toto vylepšení si teď ukážeme.

Nejprve si na formulář umístěte ListView a vhodně jej naplňte vašimi položkami. Na počtu sloupců nezáleží (pochopitelně že musíte mít alespoň jeden), ale je třeba, aby byl zvolen typ zobrazení jako vsReport.

Nyní jen přidejte do událostí OnColumnClick a OnCompare následující kódy a je též třeba nadefinovat dvě globální proměnné. Jedna slouží k hlídání "směru" třídění, druhá zase určuje sloupec, podle něhož jsou data právě setříděna.

private
{ Private declarations }
Descending: Boolean;
SortedColumn: Integer;


procedure TForm1.ListView1ColumnClick(Sender: TObject;  Column: TListColumn);
begin
TListView(Sender).SortType := stNone;
  if Column.Index <> SortedColumn then
  begin
    SortedColumn := Column.Index;
    Descending := False;
  end
  else
    Descending := not Descending;
  TListView(Sender).SortType := stText;
end;

procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
  Data: Integer; var Compare: Integer);
begin
if SortedColumn = 0 then Compare := CompareText(Item1.Caption, Item2.Caption)
                    else if SortedColumn > 0 then Compare := CompareText(Item1.SubItems[SortedColumn-1], Item2.SubItems[SortedColumn-1]);
if Descending then Compare := -Compare;
end;

Všimněte si též parametru SortType v první proceduře. Ten určuje, zda a jakým způsobem budou data tříděna, a může se vyskytovat ve čtyřech variantách:

Poslední věcí, kterou by bylo vhodné doplnit, je nějakým způsobem indikovat a zobrazit jednak sloupec, podle kterého jsou data setříděna, a pak také směr třídění (vzestupné či sestupné), aby měl uživatel na první pohled jasno. S indikací si nemusíme lámat hlavu, protože tyto informace máme uloženy v proměnných ze sekce Private. Zbývá nám jen tyto informace nějak zobrazit. Jak jistě víte, obvykle se k tomu využívá malá ikonka zobrazená v hlavičce příslušného sloupce, podle kterého jsou data zrovna setříděna. Ikonkou bývá většinou šipka směřující dolu či nahoru podle směru setřídění. Toto grafické vylepšení však již doufám každý zvládne sám. Všechny parametry o aktuálním stavu třídění znáte a změna ikony se provádí běžným způsobem ve vlastnostech daného ListView.

Přidání položky do seznamu naposledy otevřených dokumentů

V menu Start jste si jistě všimli nabídky Dokumenty, která obsahuje kromě odkazu na složku Dokumenty na disku též seznam několika naposledy použitých dokumentů z různých aplikací. Přidávají je sem různé (například textové) editory, takže pokud má vaše aplikace podobné zaměření (na editování čehokoliv), naučíme se, jak do tohoto seznamu přidat položku. Budou k tomu potřeba knihovny ShellAPI a ShlOBJ a samotný kód je již velice krátký:

procedure PridatPolozku(soubor:string);
begin
SHAddToRecentDocs(SHARD_PATH, PChar(soubor));
end;

Smazání souboru do koše

Teď si ukážeme jeden ze způsobů, jak vybraný soubor smazat do Koše (Recycle Bin). Pomůže nám k tomu knihovna ShellAPI. Důležitý je příznak FOF_ALLOWUNDO, který právě zajistí to, že soubor nebude smazán přímo, ale bude použit Koš.

function DoKose(const filename : string) : boolean;
var FileOp : TSHFileOpStruct;
begin
if integer(GetFileAttributes(PChar(Filename))) <> -1 then
  begin
  ZeroMemory(@FileOp, SizeOf(FileOp));
  FileOp.wFunc := FO_DELETE;
  FileOp.pFrom := PChar(Filename);
  FileOp.fFlags := FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION;
  Result:=(SHFileOperation(FileOp)=0);
  end
else
  Result := False; 
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if DoKose(`c:\soubor.txt`) then ShowMessage(`Soubor byl přesunut do Koše`);
end;

Zjištění celkové fyzické paměti

K tomuto příkladu snad není třeba zvláštních úvodů. Následující kód prostě zobrazí celkové množství fyzické paměti v systému v kB.

procedure TForm1.Button1Click(Sender: TObject);
var mem:TMemoryStatus;
begin
GlobalMemoryStatus(mem);
ShowMessage(FormatFloat(`#,###" kB"`, Mem.dwTotalPhys / 1024));
end;

Volná fyzická paměť

A tento příklad pro změnu zobrazí volnou fyzickou paměť.

procedure TForm1.Button1Click(Sender: TObject);
var mem:TMemoryStatus;
begin
GlobalMemoryStatus(mem);
ShowMessage(FormatFloat(`#,###" kB"`, Mem.dwAvailPhys / 1024));
end;

Virtuální paměť

A následují příklady pro tytéž parametry u virtuální paměti.

Nejprve celková velikost virtuální paměti:

procedure TForm1.Button1Click(Sender: TObject);
var mem:TMemoryStatus;
begin
GlobalMemoryStatus(mem);
ShowMessage(FormatFloat(`#,###" kB"`, Mem.dwTotalVirtual / 1024));
end;

A na úplný závěr ještě zbývá volná virtuální paměť:

procedure TForm1.Button1Click(Sender: TObject);
var mem:TMemoryStatus;
begin
GlobalMemoryStatus(mem);
ShowMessage(FormatFloat(`#,###" kB"`, Mem.dwAvailVirtual / 1024));
end;