Pobieranie informacji o napędach systemu
Aby zidentyfikować napędy zainstalowane w systemie, konieczne jest użycie funkcji WinAPI. W gruncie rzeczy jest to proste, należy jednak poznać kilka fundamentalnych zasad i poznać sposób użycia funkcji WinAPI.
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:
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:
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. Jeżeli dysk jest następuje pobranie jego etykiety, a później tworzona jest nowa pozycja w komponencie TListView. 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. 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:
Dobrze. Teraz trzeba jakoś zdobyć literę zaznaczonej pozycji w komponencie. Zrób to w ten sposób:
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:
Jeżeli nie jest możliwe określenie danych z dysku to na etykietach przypisany zostaje znak ???.
Oto cały kod programu:
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:
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:
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;
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. Jeżeli dysk jest następuje pobranie jego etykiety, a później tworzona jest nowa pozycja w komponencie TListView. 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. 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:
5 komentarzy
Ale po czym można odróżnić napęd CD-ROM od nagrywarki CD-ROM
Bardzo dobry artykuł. Ale czy można odróżnić napęd CD-ROM od nagrywarki CD-ROM lub DVD
hahaha, nagrywarka CD _Read_Only_ Memory ;]