|
|
Osztály hierarchia lekérdezése
1. rész
|
|
Példaprogram letöltése
10448 bájt
|
A Delphi Help-jében minden komponensnél megtaláljuk azt az információt, hogy mely osztályokból van származtatva. De mi a helyzet azokkal a komponensekkel, amik nem a Delphi részei, vagyis később telepítettük őket. A mellékelt példában egy olyan Delphi kiegészítést készítünk, amely egy ablakban hierarchikusan megjeleníti az összes TComponent-ből származó komponenst. A listában megjelennek az egyénileg telepített komponensek is, és minden komponensről megtudhatjuk, hogy melyik komponens csomagban található meg.
A példaprogram kipróbálásához telepítse a ClassTreePackage.dpk-t a Delphi alá.
A telepítés után létrejön egy Animare menü a Help menü előtt, benne egy Delphi Class Tree menüponttal. Ha már telepített korábban Delphi kiegészítéseket, amelyek cégünktől származnak, akkor az új menüpont a többi után jelenik meg.
A Delphi kiegészítéssel már több előző cikkünk is foglalkozik, így most csak a lényegi részt írjuk le részletesen.
A Form-on, amiben az adatokat megjelenítjük található egy TComboBox, és egy TTreeView komponens. A ComboBox-ban a komponensek, illetve osztályok ABC sorrendben vannak felsorolva, innen könnyedén kikereshetjük azt az osztályt, amire kíváncsiak vagyunk. A TTreeView-ben hierarchikusan vannak elrendezve az osztályok, de itt is ABC sorrendben.
A komponens csomagokat, és a bennük található komponenseket az IOTAPackageServices interfészen keresztül kérdezhetjük le. Ehhez a BorlandDEServices interfészt kell felhasználnunk, amit a Delphi IDE inicializál.
var
PackageServices: IOTAPackageServices;
...
if Assigned(BorlandIDEServices) then begin
PackageServices:=(BorlandIDEServices as IOTAPackageServices);
A GetPackageCount függvénnyel lekérdezhetjük a komponens csomagok számát. Egy ciklussal végigmegyünk az összes komponens csomagon, és az azokban található komponens osztályokról megállapítjuk azokat az osztályokat, amikből származik. Tehát a ciklus eleje a következő:
with PackageServices do begin
for i:=0 to GetPackageCount-1 do begin
A komponens csomagban található komponensek száma a GetComponentCount függvényel kérdezhető le. Ennek egy paramétere van, a komponens csomag sorszáma. Egy belső while ciklusban végigmegyünk a komponens listán:
t:=0;
while t<GetComponentCount(i) do begin
A komponens neve a GetComponentName függvénnyel kérdezhető le. Az első paraméter a csomag sorszáma, a második pedig a komponens sorszáma, a csomagon belül. A visszakapott értéket eltároljuk a compname változóban.
compname:=GetComponentName(i, t);
A cl változó TClass típusú. Ennek segítségével állapítjuk meg a komponens osztály szülő osztályait. Ehhez viszont először a FindClass függvénnyel le kell kérdezni a komponens osztályt. A függvény paramétere az osztály neve, vagyis jelen esetben a komponens neve.
Egy ciklusban a szülő osztályok neveit kigyűjtjük, és az anch TStringList típusú listában eltároljuk.
while Assigned(cl) do begin
anch.Insert(0, cl.ClassName);
cl:=cl.ClassParent;
end;
Az osztályokat el kell tárolni a TreeView-ben és a ComboBox-ban. Egy ciklussal végigmegyünk az előbb elkészített listán. A 3. elemtől indulunk, mivel az első két elem minden esetben a TObject és a TPersistent. A FindClassNode függvénnyel megnézzük, hogy az osztály neve szerepel-e már a TreeView listában. Ez a függvény a TForm1 osztályban van deklarálva, lejjebb részletesen is megnézzük. Most elég annyi, hogy a függvény visszatérési értéke egy TTreeNode objektum, amiben az osztály neve tárolva van, vagy nil, ha még nincs tárolva. A visszatérési értéket a TreeNode változóban tároljuk. Ha az osztály neve már tárolva van, akkor a ParentNode változónak átadjuk a TreeNode értékét, ellenkező esetben felvesszük az elemet a listára a TreeView komponens AddChldObject függvényével. Azért ezzel, mert ennek van egy plusz paramétere, egy pointer arra az adatra, amit az elem mellé el szeretnénk tárolni. Mivel a pointer is tulajdonképpen egy szám, ezért mi ezt arra használjuk fel, hogy a komponens csomag sorszámát tároljuk benne. Erre később lesz szükségünk. Az osztály nevét még felvesszük a ComboBox-ba is, kivéve a TComponent osztályt, ami minden esetben a 3. a listában.
ParentNode:=nil;
for c:=2 to anch.Count-1 do begin
TreeNode:=FindClassNode(anch[c]);
if Assigned(TreeNode) then begin
ParentNode:=TreeNode;
end else begin
clname:=anch[c];
ParentNode:=TreeView1.Items.AddChildObject(ParentNode, clname, Pointer(i));
if c>2 then ComboBox1.Items.Append(clname);
end;
end;
Miután az összes osztályt felvettük a listára, a TreeView-t sorba rendezzük az AlphaSort eljárással, és az első elemet (TComponent) kinyitjuk.
TreeView1.AlphaSort;
TreeView1.Items[0].Expand(false);
Fent már szóltunk a FindClassName függvényről. Ez mindössze annyit tesz, hogy egy ciklussal végigmegy a TreeView elemein, és összehasonlítja azok szövegét a paraméterként megkapott osztály névvel. Ha megtalálta a keresett nevet, akkor az aktuális elemmel tér vissza, ellenkező esetben az eredmény nil. Amikor kiválasztunk egy elemet a ComboBox-ból, akkor szintén ezt a függvényt használjuk az osztály megkereséséhez.
Amikor kiválasztunk egy osztály nevet a listából, akkor a Form alján elhelyezett StatusBar-ban megjelenik a csomag neve, és az abban található komponensek száma. Ezekhez az adatokhoz szintén az IOTAPackageServices interfészen keresztül fogunk hozzáférni. A TreeView OnChange eseményénél megkapjuk a Node paraméterben a kiválasztott elem objektumát. Ennek data property-jében van eltárolva annak a komponens csomagnak a sorszáma, amiben az osztály található. A GetPackageName függvénnyel lekérdezzük a csomag nevét, a már előzőleg is használt GetComponentCOunt függvénnyel pedig a benne tárolt komponensek számát.
|
Könyv
Ez a cikk megtalálható ebben a könyvben:
Delphi Software Offline 2001 évkönyv 477. oldal
Felhasználási feltételek
A Software Online szoftverfejlesztői magazin mindegyik cikke, minden megjelent képe, és egyéb publikált anyaga szerzői jog védelme alatt áll! Bármilyen formában történő másodlagos terjesztésük, közzétételük vagy felhasználásuk kizárólag a kiadó előzetes írásbeli engedélyével történhet!
|