Informacje o dyskach

Strona g│≤wna

 

Informacje o dyskach 

Je┐eli chcesz uzyskaµ informacje dotycz▒ce konfiguracji dysk≤w na Twoim komputerze to ten artyku│ jest dla Ciebie. Podstawow▒ funkcj▒ jest GetDriveType. Funkcja ta zawiera jeden parametr, a mianowicie literΩ dysku dla kt≤rego chcesz uzyskaµ informacje. 

Funkcja ta zwraca takie oto warto╢ci:

 

Warto╢µ Znaczenie
0 Typ napΩdu niemo┐liwy do okre╢lenia.
1 Nie istnieje napΩd o podanej literze.
DRIVE_REMOVABLE Dyskietka lub napΩd wymienny
DRIVE_FIXED NapΩd niewymienny
DRIVE_REMOTE NapΩd sieciowy
DRIVE_CDROM CD - ROM
DRIVE_RMADISK Ram-dysk - wirtualny dysk.

W tym artykule napiszemy program, kt≤ry bΩdzie w│a╢nie podawa│ informacje dotycz▒ce dysku. Na formularzu umie╢µ komponent ListView - w nim bΩd▒ zaznaczone dyski. Umie╢µ na formie tak┐e komponent ImageList. Dodaj do niego z dwie ikony symbolizuj▒ce odpowiednio: ikonΩ CD oraz ikonΩ dysku twardego. 

Dobrze przejd╝my do rzeczy najwa┐niejszej, czyli uzyskanie informacji o dyskach. Oto procedura OnCreate naszego programu: 

procedure TMainForm.FormCreate(Sender: TObject);
var
  i : Integer; // zmienna potrzebna do wykonania petli
  DriveType : Integer;  // informacja o typie dysku
  ListItem: TListItem;
  Bufor:array[0..MAX_PATH] of Char; // zawiera etykiete dysku
  MaxCompLength, FileSystemFlags : DWORD;
begin
{  wykonaj petle analizujac kazda litere dysku }
  for I := Ord('A') to Ord('Z') do
  begin
    DriveType := GetDriveType(PChar(Chr(i) + ':\')); // pobierz typ dysku


  {
    jezeli typ  dysku to 0 ( nie mozna okreslic ) lub 1 ( nie istnieje taki dysk )
    to pomin w opisie.
  }
    if not (DriveType = 0) and not (DriveType = 1) then
    begin
  {  uzyskaj informacje dotyczace etykiety dysku }
      GetVolumeInformation(PChar(Chr(i) + ':\'), Bufor, SizeOf(Bufor),
      nil, MaxCompLength, FileSystemFlags, nil, 0);

      ListItem := ListView.Items.Add; // dodaj pozycje
      ListItem.Caption := Chr(i) + ':\' + ' '  + Bufor; // ustaw tekst
   {
      Tutaj w zaleznosci od rodzaju dysku do komponentu ListView do okreslnej
      pozycji zostaje przypisana okreslona ikonka symoblizujaca dysk.
   }
      if (DriveType = DRIVE_CDROM) then ListItem.ImageIndex := 0;
      if (DriveType = DRIVE_FIXED) then ListItem.ImageIndex := 1;
      if (DriveType = DRIVE_REMOVABLE) then ListItem.ImageIndex := -1;
    end;                                               
  end;
end;

Procedura wykonuje pΩtle. Wiadomo, ┐e dyski mog▒ byµ ponumerowane od A do Z. Na pocz▒tek do zmiennej DriveType zostaje przypisany rezultat wykonania funkcji GetDriveType. P≤╝niej nastΩpuje sprawdzenie, czy zmienna DriveType nie ma przypadkiem warto╢ci 0 lub 1 co oznacza│oby, ┐e niemo┐liwe jest okre╢lenie dysku - wtedy operacje zostan▒ pominiΩte. Ok, je┐eli dysk jest nastΩpuje pobranie jego etykiety, a p≤╝niej tworzona jest nowa pozycja w komponencie ListView. To nie wszystko. Trzeba jeszcze wybraµ ikonΩ. W│a╢ciwo╢µ ImageIndex okre╢la numer ikony. Po prostu dobierana jest odpowiednia ikona w zale┐no╢ci od rodzaju dysku. Aha, bardzo wa┐na rzecz. Trzeba we w│a╢ciwo╢ci LargeImages komponentu ListView wybraµ komponent ImageList1.

Dobrze, wiesz ju┐ jak uzyskaµ listΩ dysk≤w znajduj▒cych siΩ w systemie. Teraz co╢ trudniejszego mianowicie uzyskanie dok│adniejszych informacji o samych dyskach, czyli liczba klaster≤w, sektory przypadaj▒cy na klaster itp. To wszystko umo┐liwia nam funkcja GetDiskFreeSpace. Trzeba w niej podaµ wszystkie zmienne, kt≤re przechowywaµ bΩd▒ informacje o w│a╢ciwo╢ciach dysku. 

Zadeklarujmy te zmienne:

var
  DirName: String; // litera dysku
  Sectors: DWORD; // sektory w klasterze  
  Bytes: DWORD; // bajty w sektorze
  FreeClust: DWORD; // wolne klastery
  TotalClust: DWORD; // wszystkie klastery

Dobrze. Teraz trzeba jako╢ zdobyµ literΩ zaznaczonej pozycji w komponencie. Zr≤b to w ten spos≤b:

DirName := ListView.Selected.Caption[1]; // pobierz pierwszy znak napisu - litere dysku

Po prostu uzyskujemy pierwszy znak zaznaczonej pozycji... Na formularzu umie╢µ 4 etykiety tekstowe, kt≤re wy╢wietla│y bΩd▒ te informacje. Teraz samo wyw│anie funkcji GetDiskFreeSpace: 

 {  Funkcja GetDiskFreeSpace podaje rozne informacje dotyczace  danego dysku }
  if GetDiskFreeSpace(PChar(DirName + ':\'), Sectors, Bytes, FreeClust, TotalClust) then
  begin
  {  przypisz dane do etykiet tekstowych }
    lblSectors.Caption := 'Sektory w klastrze: ' + IntToStr(Sectors);
    lblBytes.Caption := 'Bajty w sektorze: ' + IntToStr(Bytes);
    lblFreeClust.Caption := 'Wolne klastry: ' + IntToStr(FreeClust);
    lblTotalClust.Caption := 'Wszystkie klastry: ' + IntToStr(TotalClust);
  { jezeli niemozliwe jest odczytanie wlasciwosci przypisz etykieta symbolom znak ???? }
  end else
  begin
    lblSectors.Caption := '???';
    lblBytes.Caption := '???';
    lblFreeClust.Caption := '???';
    lblTotalClust.Caption := '???';
  end;

Je┐eli nie jest mo┐liwe okre╢lenie danych z dysku to na etykietach przypisany zostaje znak ???.

Oto ca│y kod programu: 

//////////////////////////////////////////////////////////////////
//                                                              //
//               Unit MainFrm for DrivesInfo                    //
//             Copyright © 2001 by Adam Boduch                  //
//      Service for programmers: http://programowanie.of.pl     //
//                E-mail:  boduch@poland.com                    //
//         29.06.2001 r.                                        //
//                                                              //
//////////////////////////////////////////////////////////////////

unit MainFrm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ImgList, StdCtrls;

type
  TMainForm = class(TForm)
    ListView: TListView;
    ImageList1: TImageList;
    lblSectors: TLabel;
    lblBytes: TLabel;
    lblFreeClust: TLabel;
    lblTotalClust: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure ListViewClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.DFM}

procedure TMainForm.FormCreate(Sender: TObject);
var
  i : Integer; // zmienna potrzebna do wykonania petli
  DriveType : Integer;  // informacja o typie dysku
  ListItem: TListItem;
  Bufor:array[0..MAX_PATH] of Char; // zawiera etykiete dysku
  MaxCompLength, FileSystemFlags : DWORD;
begin
{  wykonaj petle analizujac kazda litere dysku }
  for I := Ord('A') to Ord('Z') do
  begin
    DriveType := GetDriveType(PChar(Chr(i) + ':\')); // pobierz typ dysku

  {
    jezeli typ  dysku to 0 ( nie mozna okreslic ) lub 1 ( nie istnieje taki dysk )
    to pomin w opisie.
  }
    if not (DriveType = 0) and not (DriveType = 1) then
    begin
    {  uzyskaj informacje dotyczace etykiety dysku }
      GetVolumeInformation(PChar(Chr(i) + ':\'), Bufor, SizeOf(Bufor),
      nil, MaxCompLength, FileSystemFlags, nil, 0);
      
      ListItem := ListView.Items.Add; // dodaj pozycje
      ListItem.Caption := Chr(i) + ':\' + ' '  + Bufor; // ustaw tekst
   {
      Tutaj w zaleznosci od rodzaju dysku do komponentu ListView do okreslnej
      pozycji zostaje przypisana okreslona ikonka symoblizujaca dysk.
   }
      if (DriveType = DRIVE_CDROM) then ListItem.ImageIndex := 0;
      if (DriveType = DRIVE_FIXED) then ListItem.ImageIndex := 1;
      if (DriveType = DRIVE_REMOVABLE) then ListItem.ImageIndex := -1;
    end;                                               
  end;
end;

procedure TMainForm.ListViewClick(Sender: TObject);
var
  DirName: String; // litera dysku
  Sectors: DWORD; // sektory w klastru
  Bytes: DWORD; // bajty w sektorze
  FreeClust: DWORD; // wolne klastery
  TotalClust: DWORD; // wszystkie klastery
begin
  DirName := ListView.Selected.Caption[1]; // pobierz pierwszy znak napisu - litere dysku

  {  Funkcja GetDiskFreeSpace podaje rozne informacje dotyczace  danego dysku }
  if GetDiskFreeSpace(PChar(DirName + ':\'), Sectors, Bytes, FreeClust, TotalClust) then
  begin
  {  przypisz dane do etykiet tekstowych }
    lblSectors.Caption := 'Sektory w klastrze: ' + IntToStr(Sectors);
    lblBytes.Caption := 'Bajty w sektorze: ' + IntToStr(Bytes);
    lblFreeClust.Caption := 'Wolne klastry: ' + IntToStr(FreeClust);
    lblTotalClust.Caption := 'Wszystkie klastry: ' + IntToStr(TotalClust);
  { jezeli niemozliwe jest odczytanie wlasciwosci przypisz etykieta symbolom znak ???? }
  end else
  begin
    lblSectors.Caption := '???';
    lblBytes.Caption := '???';
    lblFreeClust.Caption := '???';
    lblTotalClust.Caption := '???';
  end;
end;

end.

 

Przydatn▒ mo┐e tak┐e byµ funkcja DiskSize, kt≤ra podaje pojemno╢µ dysku oraz DiskFree, kt≤ra podaje ilo╢µ wolnego miejsca na dysku. Funkcje te zwracaj▒ rezultat w postaci zmiennej typu Int64. Jako parametr tych funkcji trzeba podaµ numer dysku. Dysk opatrzony liter▒ A ma numer 1; dysk B - numer 2 itd. Czyli np:

WolneMiejsce.Caption ;= IntToStr(DiskFree(3)); // wolne miejsce na dysku C:

Oto ╝r≤d│a programu, kt≤ry pisali╢my w tym artykule:

DrivesInfo.zip ( 3 kB )

Adam Boduch