Az elôzô leckében megtanultuk, hogy hogyan lehet az objektumokat létrehozni. Ebben a leckében pedig arról lesz szó, hogy hogyan lehet a már korábban létrehozott objektumokat manipulálni.
Az objektumok törlése
A legkézenfekvôbb manipulálás a törlés. Ez elvileg nagyon egyszerûen kivitelezhetô a SysDestroyObject függvénnyel, ha ismerjük az objektum azonosítóját, vagy a megtestesített fájl nevét:
rc = SysDestroyObject(objektumazonosító/fájlnév)
A függvény 1-et ad vissza sikeres végrehajtás esetén, ellenkezô esetben pedig 0-át. Amennyiben a törlendô objektum egy gyûjtô, akkor annak a tartalmát is megsemmisíti.
Objektumok megtalálása
Sajnos a REXX segédfüggvények között nincs olyan, amellyel le lehetne kérdezni az objektumok teljes listáját. A gyûjtôket viszonylag könnyû megtalálni, ha tudjuk, hogy a Munkaasztal milyen könyvtárban található. Ha pl. a Munkaasztal a C:\DESKTOP könyvtárban van, akkor csak azt kell megnéznünk, hogy milyen alkönyvtárak vannak a C:\DESKTOP-ban, és máris tudjuk gyûjtôk listáját, mivel minden gyûjtôhöz egy alkönyvtár tartozik. A kulcs tehát a Munkaasztal könyvtárának megtalálása. A Munkaasztal önmaga is egy gyûjtô, csak épp ennek a gyûjtônek be van állítva a munkaterület attribútuma. Az aktív munkaterületek listája az OS2SYS.INI fájlban található a FolderWorkareaRunningObjects alkalmazás alatt. Az alkalmazás kulcsai tárolják a munkaterületnek beállított gyûjtôk könyvtárait. Rendszerint az elsô kulcs a Munkaasztal könyvtára, bár ez nem garantált. Hogy biztosak legyünk a dolgunkban, érdemes egy gyûjtôt létrehozni a Munkaasztalon, majd pedig leellenôrizni az OS2SYS.INI-bôl kihámozott Munkaasztal-alkönyvtárban, hogy megjelent-e a létrehozott gyûjtô alkönyvtára. Az alábbi példaprogram éppen ezen az elven mûködik:
/* A Munkaasztal megtalálása */
CALL RxFuncADD 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
CALL SysLoadFuncs
CALL SysIni 'SYSTEM', 'FolderWorkareaRunningObjects', 'ALL:', 'workarea.'
folderName = 'XYXYXY'
rc = SysCreateObject('WPFolder', folderName, '<WP_DESKTOP>', 'NOTVISIBLE=YES;OBJECTID=<'folderName'>;', 'R')
theDesktop = ''
curDir = Directory()
DO i = 1 TO workarea.0
thisOne = workarea.i || '\' || folderName
IF Directory(thisOne) = thisOne THEN
DO
theDesktop = workarea.i
CALL Directory theDesktop
LEAVE
END
END
SAY 'A Munkaasztal könyvtára:' theDesktop
rc = SysDestroyObject('<'folderName'>')
EXIT
Ha valamilyen okból kifolyólag mégsem sikerülne ily módon megtalálni a Munkaasztalt, akkor elvileg végig lehet keresni a létrehozott gyûjtôt az összes lokális meghajtón, bár ez viszonylag sok idôt vehet igénybe.
Az objektumazonosítók listája
A Munkaasztal által ismert objektumazonosítók listája megtalálható az OS2.INI fájlban, a PM_Workplace:Location alkalmazás kulcsai alapján. Ezt a listát könnyedén lekérdezhetjük az alábbi sorral:
CALL SysIni 'USER', 'PM_Workplace:Location', 'ALL:', 'objid.'
A fenti utasítás lefutása után az összes objektumazonosító megtalálható lesz az objid. összetett változóban. A kulcsok alatt tárolt bináris adatok szintén felhasználhatók az objektumok azonosítására. Ezeket az objektumonként egyedi bináris adatokat (angolul handle, amit többnyire kezelônek fordítanak, pedig nekem sokkal jobban tetszik a fogantyú elnevezés :-) a rendszer hozza létre, amikor az objektum elkészül. A bináris kezelôket használják aztán az egyéb alkalmazások kulcsként. Az ily módon használt kezelôket hexadecimális formában tárolja a rendszer. Amikor adatként szerepelnek, akkor viszont már rendszerint bináris formátumúak. A kezelôk lehetnek 2 (16 bit) vagy pedig 4 bájt (32 bit) hosszúak. A 2. leckében az INI fájlok kiolvasására használt példaprogram segítségével meg lehet állapítani, hogy melyik fajta kezelôvel van dolgunk.
Következô példaprogramunkban azt fogjuk demonstrálni, hogy hogyan lehet kideríteni, hogy milyen objektumok találhatóak két általunk kiválasztott gyûjtôben. A gyûjtôk a WPAbstract osztályból származnak. Az ilyesfajta gyûjtôknek a listája a PM_Abstract:FldrContent alkalmazás alatt található, mint az alkalmazás kulcsai, amelyek a gyûjtôk 16 bites kezelôjének hexadecimális reprezentációi.
/* Objektumok kilistázása két gyûjtôben */
CALL RxFuncADD 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
CALL SysLoadFuncs
CALL SysIni 'USER', 'PM_Workplace:Location', 'ALL:', 'objid.'
objects. = 'nem definiált'
DO i = 1 TO objid.0
handle = SysIni('USER', 'PM_Workplace:Location', objid.i)
handle = C2X(Reverse(Left(handle, 2)))
handle = Strip(handle, 'L', '0')
id = objid.i
objects.id = handle
objects.handle = id
END
ids.0 = 2
ids.1 = '<WP_DESKTOP>'
ids.2 = '<WP_INFO>'
DO i = 1 TO ids.0
id = ids.i
handle = objects.id
SAY Left(id, 30) handle
valami = SysIni('USER', 'PM_Abstract:FldrContent', handle)
DO WHILE valami <> ''
PARSE VAR valami handle 3 5 valami
handle = C2X(Reverse(Left(handle, 2)))
handle = Strip(handle, 'L', '0')
SAY ' 'Left(objects.handle, 30) handle
END
END
EXIT
A program elsô részében kiolvassuk az OS2.INI fájlból az objektumazonosítókat. Ezek után minden egyes objektumazonosítóhoz csatoljuk a kezelôjét is. Az asszociatív memória technikájának segítségével oldjuk meg az adatok tárolást. A program végén megjelenítjük a két kiválasztott gyûjtôben eltárolt objektumok azonosítóit és kezelôit. Amennyiben valamelyik objektumnak nem lenne azonosítója, akkor a "nem definiált" szöveg jelenik meg az azonosító helyett. Ha már ki tudjuk olvasni a kezelôket, akkor csak egy lépés választ el bennünket attól, hogy az objektumokról további információkat is megtudjunk. A legtöbb adat ugyanis bináris "körítéssel" tárolt, így a PARSE és a TRANSLATE utasítások segítségével könnyedén kiszûrhetjük a számunkra érdekes dolgokat:
valami = SysIni('USER', 'PM_Abstract:FldrContent', handle)
DO WHILE valami <> ''
PARSE VAR valami handle 3 5 valami
handle = Strip(C2X(Reverse(Left(handle, 2))), 'L', '0')
ertek = SysIni('USER', 'PM_Abstract:Objects', handle)
IF ertek = 'ERROR:' THEN ITERATE
/* egy sorosra alakít */
ertek = Translate(ertek, '^', '0A'x)
/* kiszûri a nem nyomtatható karaktereket */
ertek = Translate(ertek, Copies('00'x, 256), XRange('7F'x, '1F'x))
ertek = Translate(Translate(ertek, 'FF'x, ' '), ' ', '00'x)
IF objects.handle <> '' THEN
objid = Left(objects.handle, 25)
ELSE
objid = Left(handle, 25)
/* kihámozzuk a címet */
PARSE VAL ertek 'WPAbstract' objtitle 'WPObject'
objtitle = Strip(Translate(objtitle, ' ', 'FF'x))
objtitle = Strip(Left(objtitle, Length(objtitle)-1))
SAY ' 'objid objtitle
END
Objektumok megnyitása
Egy REXX programból meg lehet nyitni az objektumot minden olyan nézetben, amelyet az objektum támogat. A megnyitáshoz azonban tudni kell az objektum azonosítóját, vagy az objektum által reprezentált fájl nevét és annak teljes elérési útvonalát. Amennyiben ezek egyike ismert, nincs egyéb hátra, mint beállítani az objektum OPEN kulcsát arra a nézetre, amellyel meg akarjuk nyitni. Az OPEN (és egyéb kulcsok) beállításainak megváltoztatására a SysSetObjectData függvényt használhatjuk:
rc = SysSetObjectData(objektum, beállítások)
Amennyiben a beállítások paraméterek helyén az OPEN=DEFAULT értéket adjuk meg és lefuttatjuk a fenti sort, akkor az egyenértékû lesz azzal, mintha az objektumra duplán ráklikkantottunk volna. Ekkor ugyanis az objektum meg fog nyílni az alapértelmezett nézetben. A nézet fogalmát persze tágan kell értelmezni. Ha az objektum egy gyûjtô, akkor a gyûjtô a szó szoros értelmében meg fog nyílni, egy programobjektum esetében viszont (többnyire) elindul a megtestesített program. Amennyiben az OPEN=SETTINGS beállítást adjuk meg, akkor az objektum beállításainak oldalai fognak megjelenni.
/* Objektumok megnyitása */
CALL RxFuncADD 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
CALL SysLoadFuncs
rc = SysSetObjectData('<WP_DESKTOP>', 'OPEN=TREE')
rc = SysSetObjectData('<WP_DESKTOP>', 'OPEN=DETAILS')
rc = SysSetObjectData('<WP_DESKTOP>', 'OPEN=SETTINGS')
EXIT
A fenti példaprogram azt demonstrálja, hogy hogyan lehet megnyitni a Munkaasztalt három különbözô (TREE=fa, DETAILS=részletes, SETTINGS=beállítások) nézetben.
Az objektum-beállítások megváltoztatása
Az elôzô részben megismert SysSetObjectData függvény segítségével minden olyan objektum-beállítást módosíthatunk, amelyeket már az objektum létrehozásánál is használhattunk. Az alábbi programrészlet például azt mutatja be, hogy hogyan lehet a Segédeszközök gyûjtô beállításait egyetlen sorral megváltoztatni:
rc = SysSetObjectData('<WP_TOOLS>', 'DETAILSFONT=14.Tms Rmn Italic;', 'DETAILSVIEW=STANDARD;')
A SysSetObjectData függvény segítségével az ikonokat és a gyûjtôk hátterét is meg lehet változtatni. A háttért beállító kulcs a BACKGROUND. A háttérként használt képnek bitmap formátumban kell lennie és az \OS2\BITMAPS könyvtárban kell lennie, vagy pedig meg kell adni a fájl teljes elérési útvonalát. Az objektum ikonját az ICONFILE kulcs módosításával lehet elérni. Az ikonfájl vagy az objektum .ICON kiterjesztett attribútumában, vagy pedig az OS2.INI fájlban kerül eltárolásra.
A SysSetObjectData mellett a SysSetIcon függvényt is használhatjuk az ikon kicserélésére:
rc = SysSetIcon(fájlnév, ikon fájlnév)
Sikeres végrehajtáskor 1, sikertelen esetében pedig 0 a visszatérési érték. Figyeljük meg, hogy a SysSetIcon segítségével csak olyan objektumok ikonja változtatható, amelyek valamilyen fájlt reprezentálnak, így például nem használható árnyékobjektumok esetében.
Biztosan észrevettük már, hogy bár az OS/2 nagyon sok ikont használ, mégis csak keveset lehet megtalálni a merevlemezen. Ez azért van, mert a legtöbb ikon DLL-ekben rejtôzik és csak úgy jeleníthetjük meg ôket, ha objektumokhoz rendeljük ôket. A hozzárendelés az ICONRESOURCE kulcs beállításával történhet. Persze még azt is ismernünk kell, hogy az adott ikon milyen sorszám alatt és melyik DLL-ben található. Az alábbi program azt demonstrálja, hogy hogyan is lehet ezeket az ikonokat megjeleníteni:
/* Ikonok megjelenítése */
CALL RxFuncADD 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
CALL SysLoadFuncs
folderid = '<ZSOLT_KADAR>'
rc = SysCreateObject('WPFolder', 'Ikonok', '<WP_DESKTOP>', 'OBJECTID=' || folderid || ';', 'R')
class = 'WPAbstract'
icons. = 1
icons.0 = 3
icons.1 = 'PMWP'
icons.PMWP.0 = 95
icons.2 = 'WPCONFIG'
icons.WPCONFIG.0 = 17
icons.3 = 'WPPRTMRI'
icons.WPPRTMRI.0 = 26
DO i = 1 TO icons.0
module = icons.i
say 'Keresek a(z) 'module'.DLL-ben...'
DO j = 1 TO icons.module.0
title = module Right(j,2)
rc = SysCreateObject(class, title, folderid,,
'ICONRESOURCE=' || j module || ';', 'R')
END
END
EXIT
A futás után kapni fogunk egy ikonokkal teli gyûjtôt. Persze nem minden sorszám alatt találunk ikont, így lesznek olyan objektumok is, amelyekhez nem tartozik majd valódi ikon. A DLL-eket és az azokban tárolt ikonok számát próbálgatással határoztuk meg Warp 4 alatt. Akinek van ideje, az próbálgathat más DLL-eket is, és ha újabb OS/2 verzió kerülne a keze alá, akkor érdemes lehet a programban megadott DLL-enkénti ikon-darabszámokat is egy kicsit feltuningolni. Érdemes lehet az OS/2 könyvtárában taláható INI.RC fájlt is tanulmányozni. Ezt a fájlt használja az OS/2 telepítôprogramja a Munkaasztal létrehozására, ezért ebbôl a fájlból nagyon sok hasznos beállítást (ikonforrásokat, objektumazonosítókat, kulcsokat stb.) elleshetünk.
REXX GYÍK:
K1. Meg lehet gyorsan állapítani az objektum kezelôje alapján, hogy gyûjtôvel van-e dolgunk?
V1. A gyûjtôk kezelôjének elsô hexadecimális helyiértékén a tapasztalat szerint mindig 3 áll. Más objektumoknál ez az érték 1 vagy pedig 2.
Gyakorlatok:
1. Írjon egy programot, amely véletlenszerûen kiválaszt egy bitmapet az \OS2\BITMAP könyvtárból és azt állítja be a Munkaasztal hátterének!
| Kádár Zsolt 1998. 10. 02. | [ Elôzô lecke | Következô lecke | Tartalom ] |