IV. Objektumok manipulálása

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 ]