Delphi - A merevlemezek foglaltságát jelző komponens

forráskód letöltése
A cikk egy olyan komponens elkészítését öleli fel, mely a számítógépben elérhető valamennyi merevlemez foglaltságát kijelzi grafikusan és szövegesen egyaránt. Az adott merevlemez grafikonja fölé tolva az egérmutatót az információk számadatok formájában is láthatóak lesznek.
A mellékelt példaprogram megnyitása előtt a FixedDisks.pas-ban lévő komponenst telepítenie kell a Delphi alá.
A komponens gyermekkomponensek kompozíciója, melyekből annyit hoz létre a befogadó objektum, ahány merevlemez-meghajtó van a számítógépben, illetve amennyi pillanatnyilag elérhető. Vizsgáljuk meg ezeket most külön-külön is.
TDiskSpace komponens
A TDiskSpace komponens önmagában arra képes, hogy a környezetéből (jelen esetben a szülő komponenstől, és nem a felhasználótól) kapott paraméter segítségével begyűjtse a szükséges információkat az adott merevlemezről, elvégezze a szükséges számításokat, valamint gondoskodjon a vizuális megjelenítésről. A kapott paraméter a számítógépben elérhető fix-lemezmeghajtó betűjele.
A komponenst a TGraphicControl osztályból származtatjuk, így alkalmas grafikai és szöveges elemek megjelenítésére a Canvas property-je segítségével. A szülőosztályból örökölt Paint metódus felülírásával pedig előírhatjuk, hogyan viselkedjen a kontrol, amikor megkapja a WM_PAINT üzenetet a szülőtől.
A szülőobjektumból (mely most egy másik komponens) kapott paramétert egy nyilvános property-jében kapja meg, ez a DiskCharacter nevű property.
Az osztály MakeElements nevű eljárása végzi el az adatgyűjtő és kirajzoló funkciókat. Az adatgyűjtéshez a GetDiskFreeSpaceEx nevű Windows API függvényt használja fel. A függvény bemenő paramétere a meghajtó neve, kimenő paraméterei a számadatok a meghajtó foglaltságáról.
GetDiskFreeSpaceEx
BOOL GetDiskFreeSpaceEx(
LPCTSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailable,
PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes
);
Paraméterek
LPCTSTR lpDirectoryName
A meghajtó betűjele, például ’C:\’.
PULARGE_INTEGER lpFreeBytesAvailable
Az összes szabad terület byte-ban, melyhez a hívó szál hozzáférhet.
PULARGE_INTEGER lpTotalNumberOfBytes
Az összes terület byte-ban, melyhez a hívó szál hozzáférhet.
PULARGE_INTEGER lpTotalNumberOfFreeBytes
A lemezen található összes szabad terület. Ennek értéke lehet NULL.
Visszatérési érték
Sikeres végrehajtás esetén az eredmény valamilyen nullától különböző érték.
A komponens kódjában a következőképpen hívódik meg:
procedure TDiskSpace.CountSpaces(dc:string);
var diskstr : string;
begin
  diskstr := dc + ':\';
    GetDiskFreeSpaceEx(PChar(diskstr),FreeSpaceAvailable,       TotalSpace,@TotalFree);
end;
A fentebb említett MakeElements eljárás a Paint függvény felüldefiniált változatában hívódik meg, így az ablak létrejöttekor, valamint annak újrarajzolásakor is meghívódik, mindig a pillanatnyi állapotot tükrözve.
A TFixedDisks komponens
A komponens lesz a szülőobjektuma a TDiskSpace komponens(ek)nek. A feladata, hogy feltöltse adattal a TDiskSpace osztály egyedeinek DiskCharacter property-jét, vagyis meghatározza, hogy hány darab merevlemez érhető el a PC-ben pillanatnyilag. A komponens ezután felületén megjeleníti a meghajtó-számú gyermekkomponenst. A meghajtó-szám meghatározása a GetDriveType nevű API függvénnyel történik, mely bemenő paraméterként egy meghajtó-betűjelet fogad, visszatérési értéke pedig egy meghajtó típust reprezentáló konstans. Mivel a komponens szempontjából csak a merevlemezek száma fontos, visszatérési értékként csak a DRIVE_FIXED értéket vizsgáljuk. Ennek megvalósítása a programban:
function TFixedDisks.GetDriveChars:TChars;
begin
  for d:=1 to 26 do allfixed[d] := '.';
  s := ' ';
  a := 0;
  for i:= 'A' to 'Z' do begin
       inc(a); s := ' '; s := string(i) + ':\';
       diskType := GetDriveType(PChar(s));
       if (diskType = DRIVE_FIXED) then allfixed[a] := i;
     end;
  GetDriveChars := allfixed;
end;
A komponens egy karaktertömbbe gyűjti a szignifikáns karaktereket, majd ezt felhasználva meghatározza a meghajtók számát. A két adat segítségével a felületén megjelenő kontrolokat egy tag objektum-tömbben helyezi el. A gyermekkomponensek Parent property-jét természetesen erre az objektumra kell állítani.
...
for i:= 0 to fNum-1 do begin
    FDiskSpace[i] := TDiskSpace.Create(self);
    for j:=1 to 26 do begin
      if ((list[j] <>'.') and (j > old)) then begin
        old := j;
        FDiskSpace[i].DiskCharacter := string(list[j]);
        break;
      end;
    end;
    FDiskSpace[i].Parent := self;
    FDiskSpace[i].Left := 0;
    FDiskSpace[i].Top := (30*i);
 end;
A komponens felületének megrajzolásakor méretét dinamikusan választja meg. A rendelkezésre álló meghajtó-adatok már fejlesztési időben is láthatóak.