V. OS/2-es programok kiegészítése REXX programokkal

A REXX, mint makrónyelv

Mivel a REXX már nagyon régóta az OS/2 szerves része, ezért kézenfekvô dolog, hogy az alkalmazások felhasználói is ezt a nyelvet használják makrók programozására. A REXX ilyen célra való alkalmazása azonban lényegesen eltér az eddig tanult esetektôl, mivel ekkor a REXX programnak (makrónak) a grafikus környezetben (a grafikus alkalmazás részeként) kell futnia. Ez pedig azzal a következménnyel jár, hogy a makrók nem használhatják a standard kimenetet és bemenetet (pl. nem megy a SAY vagy a PULL), a TRACE parancs által közvetített információ és a hibaüzenetek elvesznek, valamint nem használhatjuk azokat a REXXUtil segédfüggvényeket, amelyek a billentyûzetet és a képernyôt kezelik.

Ezek a megszorítások azzal a következménnyel járnak, hogy a makrók tesztelése és javítása meglehetôsen nehéz. Nagyon sok fáradságtól kímélhetjük meg magunkat, ha a szintakszishibákat figyeljük a SIGNAL ON Syntax beiktatásával és a hibaüzeneteket magunk továbbítjuk. Grafikus környezetben az RxMessageBox segédfüggvénnyel jeleníthetünk meg üzeneteket:

rc = RxMessageBox(szöveg, [cím], [gomb], [ikon])

A szöveg paraméter szabja meg a megjelenítendô üzenetet. A '0A'x karakter közbeiktatásával a hosszabb üzeneteket több részre tördelhetjük. A többi paraméter opcionális. A cím beállításával szabhatjuk meg a megjelenített ablak címét, amelynek alapértelmezés szerinti értéke Error. A gomb értéke határozza meg, hogy milyen gombok szerepeljenek az ablakban. Az alábbi táblázatban összefoglaltuk a lehetséges értékeket. Az ikon paraméter adja meg az ablakban megjelenített ikon stílusát. Mai második táblázatunk mutatja ennek a paraméternek a lehetséges értékeit.

Gombstílus:Eredmény:
ABORTRETRYIGNOREAbort, Retry és Ignore gombok
CANCELCancel gomb
ENTEREnter gomb
ENTERCANCELEnter és Cancel gombok
OKOK gomb, default
OKCANCELOK és Cancel gomb
RETRYCANCELRetry és Cancel gombok
YESNOYes és No gombok
YESNOCANCELYes, No és Cancel gombok

Ikonstílus:Eredmény:
ASTERISKCsillag ikon
ERRORError ikon
EXCLAMATIONFelkiáltójel ikon
HANDKéz ikon
INFORMATIONInformáció ikon
NONENincs ikon, ez a default
QUERYKeresés ikon
QUESTIONKérdés ikon
WARNINGFigyelmeztetés ikon

A függvény visszatérési értékébôl megállapíthatjuk, hogy a felhasználó melyik gombot nyomta meg:

Visszatérési érték:A megnyomott gomb:
1OK
2Cancel
3Abort
4Retry
5Ignore
6Yes
7No
8Enter

Az alábbi kódrészlet azt mutatja, hogy hogyan lehet az RxMessageBox segítségével a szintakszishibákat jelezni:

Syntax:
	LF = '0A'x
	PARSE SOURCE . . progName
	msg = 'File:' FileSpec('Name', progName) || LF
	msg = msg || 'Line' sigl':' SourceLine(sigl) || LF
	msg = msg || ErrorText(rc)
	CALL RxMessageBox msg, 'Syntax Error', 'OK', 'Error'
	RETURN 3

Az RxMessageBoxon kívül természetesen más megoldás is létezik a hibaüzenetek közlésére. A LineOut és a CharOut függvények segítségével például fájlba írathatjuk a szükséges információt.

A fejlett szövegszerkesztô (Enhanced Editor) kiterjesztése

Az OS/2-vel szállított fejlett szövegszerkesztô (EPM) igen jó példa a REXX makrónyelvként történô használatára, mivel gyakorlatilag az alkalmazás teljes funkcionalitása elérhetô REXX-bôl. Ha elindítjuk az EPM-et és a Segítség menübôl kiválasztjuk a Gyors Segítség (Quick Reference) pontot, akkor a kapott információs anyagban felfedezhetünk egy rövid részletet, amely a REXX használatáról szól. Az itt közölt információ sajnos nem túl részletes, ezért a továbbiakban hosszabban elidézünk ezen a területen.

Az EPM REXX makrókat .ERX kiterjesztésû fájlokban tároljuk, amelyeket aztán az EPM parancssorából, az RX parancs paramétereként futtathatunk. A makrókat az EPM parancsértelmezôje hajtja végre, ezért a makrókba elvileg bármilyen olyan parancsot beírhatunk, amelyet az EPM parancssora képes értelmezni. Ezen felül használhatunk még jó néhány, az EPM által biztosított kiegészítô REXX függvényt is, amelyeket a továbbiakban részletesen bemutatunk.

Az EtkInsertText függvény segítségével például szöveget illeszthetünk be egy, az EPM által megnyitott fájlba:

CALL EtkInsertText szöveg [, sor [, fájl-ID]]

Értelemszerûen a szöveg változó tárolja a beillesztendô szöveget, amelyet aztán a fájl-ID által reprezentált fájlba illesztünk be, a sor által meghatározott sorba. Amennyiben a fájl-ID-t és a sort nem adjuk meg, akkor az éppen megnyitott fájl éppen kiválasztott sorába történik a beillesztés. A fájl-ID nem más, mint egy szám, amelyet az EPM rendel a fájlhoz a megnyitás alkalmával. A szám akkor sem változik, ha a fájlnak más nevet adunk a feldolgozás során. Az éppen szerkesztett fájl-ID-ját lekérdezhetjük az EtQueryFileID függvénnyel:

fájl-ID = EtkQueryFileID()

Az így eltárolt értéket aztán késôbb felhasználhatjuk, ha vissza akarunk váltani erre a fájlra az EPM-es activateFileID paranccsal:

'activateFileID' fájl-ID

Az EtkInsertText függvény párja az EtkDeleteText, amellyel szöveget törölhetünk a megadott fájl megadott sorából, vagy az éppen aktuális fájl kiválasztott sorából, ha nem adtuk meg az opcionális paramétereket:

CALL EtkDeleteText [sor [, fájl-ID]]

A Delete és Insert függvények egymás után történô meghívását helyettesíti az EtkReplaceText függvény, amellyel szöveget cserélhetünk a fájlban:

CALL EtkReplaceText szöveg [, sor [, fájl-ID]]

Az EPM minden fájl esetében környezeti változókat definiál, amelyekben a fájl tulajdonságait tárolja. A csak a REXX makrókban használható extract paranccsal lekérdezhetjük ezen változók értékét, amely a változó nevének megfelelô összetett változóban kerül eltárolásra. Az 'extract /line' paranccsal például lekérdezhetjük, hogy éppen melyik sorban van a kurzor. A visszaadott eredmények száma (ami ebben az esetben 1) a line.0, a pozíció pedig a line.1 változóban lesz megtalálható. Az EtkSetFileField paranccsal pedig megváltoztathatjuk a változók értékeit:

CALL EtkSetFileField változónév, érték [, fájl-ID]

A lekérdezhetô és beállítható változókat felsoroltuk alábbi táblázatunkban:

Változó:Leírás:
autosaveHány változtatás után mentse el az EPM automatikusan a fájlt. A 0 autosave érték kikapcsolja ezt a funkciót.
colA kurzornak a sor elejéhez viszonyított oszloppozíciója. Lehetséges értékek: 1-tôl 255-ig.
cursorxA kurzor ablakhoz viszonyított oszloppozíciója.
cursoryA kurzor ablakhoz viszonyított sorpozíciója.
dragcolorA mouse által kijelölt vontatási terület színe.
dragstyleA mouse által kijelölt vontatási terület stílusa. Lehetséges értékek: 0 - nem jelöli a vontatási területet, 1 - blokkjelölés, 2 - sorjelölés, 3 - karakterjelölés.
eaareaMutató, amely az EPM kiterjesztett attribútum területére mutat.
filenameAz éppen szerkesztett fájl neve a teljes elérési útvonallal.
fontAz alapértelmezett font száma.
fontheightA font magassága pixelben.
fontwidthA font szélessége pixelben.
getlineAz aktív sor tartalma.
getmarkA kijelölés kiegészítô tulajdonságai. Amennyiben a kijelölés létezik, öt értéket kapunk vissza: sor kezdet, sor vég, bal oszlop, jobb oszlop, fájl-ID.
getmarktypeA kijelölés típusa: LINE, CHAR, BLOCK, CHARG, BLOCKG, vagy üres sztring, amennyiben nincs kijelölve semmi.
lastA sorok száma.
lineAz éppen aktív sor száma.
lockhandleA fájl zárolt állapotát jelzi. 1-es érték esetén a fájl zárolt, más felhasználó nem férhet hozzá. A 0 jelzi a nem zárolt állapotot.
markcolorA kijelölt szöveg színe.
modifyA fájlon végzett változtatások száma.
mousexA mouse X koordinátája.
mouseyA mouse Y koordinátája.
textcolorA szöveg színe.
userstringA felhasználó által definiálható érték.
versionAz EPM verziószáma.
visibleJelzi, hogy a fájl éppen látható-e.
windowheightAz ablakban látható sorok száma.
windowwidthAz ablakban látható oszlopok száma.
windowxAz ablak X koordinátája (0 az újabb EPM-ekben).
windowyAz ablak Y koordinátája (0 az újabb EPM-ekben).

Egy példa EPM makró

Példaképpen tekintsünk meg egy EPM makrót, amelyet REXX programjaink vázának automatikus elkészítésére használhatunk.

/* EPM macro */

SIGNAL ON Syntax

PARSE ARG author

'extract /filename'
filename.1 = FileSpec('N', filename.1)

text.   = ''
text.0  = 20
text.1  = '/*' || Copies('*', 70)             || '*/'
text.2  = '/*'    Left(filename.1, 68)           '*/'
text.3  = '/*'    Left('Készült:' date(), 68)    '*/'
text.4  = '/*'    Left('Szerzô:' author,  68)    '*/'
text.5  = text.1
text.6  = 'SIGNAL ON Syntax'
text.7  = 'SIGNAL ON Halt'
text.10 = 'EXIT'
text.12 = 'Syntax:'
text.13 = ' Say SourceLine(sigl)'
text.14 = ' Say "Szintakszishiba a(z) "sigl". sorban!'
text.15 = ' Say ErrorText(rc)'
text.16 = ' Trace ?R; NOP; EXIT'
text.18 = 'Halt:'
test.19 = ' Say "User break. Exiting..."'
text.20 = ' EXIT'

DO i = 1 TO text.0
	CALL EtkInsertText text.i
END
CALL EtkDeleteText
CALL EtkSetFileField 'line', 9

RETURN 0

Syntax:
	err = rc
	'e ".Macro error" /C'
	CALL EtkSetFileField 'autosave', 0
	CALL EtkSetFileField 'filename', '.Macro Error'
	PARSE SOURCE . . program
	CALL EtkInsertText 'Szintakszis hiba a 'program'ban'
	CALL EtkInsertText ' 'sigl':' SourceLine(sigl)
	CALL EtkInsertText ' Szintakszis hiba ('err'):' ErrorText(err)
	CALL EtkSetFileField 'modify', 0
	RETURN 1

A példamakró elsô részében feltöltjük a text. összetett változót, majd pedig végrehajtjuk egy hurok segítségével az EPM-be történô kiíratást. Amennyiben szintakszishiba történik, a hibaüzenet tartalma is az EPM-ben jelenik meg. A makrót az EPM parancssorában (CTRL-I) kell elindítani. Megadhatjuk a szerzô nevét is, ha kedvünk tartja, s a makró ekkor beteszi ezt is a fájlba.

[lecke05a.gif]
Az EPM parancssora

Ha a makró sikeresen lefutott, akkor az alábbihoz hasonló fájl kell, hogy megjelenjen az EPM-ben:

[lecke05b.gif]
A makró futtatásának eredménye

Billentyûk definiálása és végrehajtása

Az EPM lehetôvé teszi, hogy gyorsítóbillentyûket definiáljunk a buildaccel paranccsal:

bldaccel tábla flagek billentyû index parancs

A gyorsítóbillentyûk táblákban vannak eltárolva, így több készlet elôállítására is van lehetôség. A táblák között az activateaccel tábla paranccsal válthatunk. Amennyiben a bldaccel parancsnak a tábla paraméter helyén *-ot adunk meg, akkor az azt jelenti, hogy az éppen aktív táblába akarjuk az új definíciót felvenni. Az új definíció azonban csak akkor lép életbe, ha a táblát újratöltjük az activateaccel paranccsal. A következô paraméter, a flagek határozza meg a billentyûkombináció típusát a PMWIN.H fájlban elôre definiált AF_ konstansokkal. A billentyû paraméter a definiálni kívánt billentyû ASCII kódját, vagy a szintén a PMWIN.H-ban rögzített virtuális konstansok valamelyikét írja le. Az index lesz a gyorsbillentyû azonosítókódja, ezért az itt megadott számnak egyedinek kell lennie. Legjobb, ha valamilyen 1000 és 9000 közötti értéket választunk. Az utolsó paraméter, a parancs határozza meg a billentyû megnyomásakor végrehajtandó mûveletet. Természetesen a definiálás REXX makróval is elvégezhetô. Erre mutat példát az alábbi kódrészlet:

/* Gyorsbillentyûk definiálása */
AF_CHAR        = 1   /* a billentyûtípust jellemzô konstansok */
AF_VIRTUALKEY  = 2
AF_SCANCODE    = 4
AF_SHIFT       = 8
AF_CONTROL     = 16
AF_ALT         = 32
AF_LONEKEY     = 64

VK_F1          = 32 /* Virtuális billentyû-konstansok */
VK_ALT         = 11
 
'buildaccel *' (AF_CHAR + AF_CONTROL) 122 9300 'sayerror Megnyomták a CTRL-z-t!'
'buildaccel *' (AF_CHAR + AF_CONTROL) 90  9301 'sayerror Megnyomták a CTRL-Z-t!'
'buildaccel *' (AF_VIRTUALKEY + AF_ALT) VK_F1 9302 'qtime'    /* ALT-F1: idô */
'buildaccel *' (AF_VIRTUALKEY + AF_LONEKEY) VK_ALT 9303 'sayerror F10 = action bar'
/* Az utóbbi definíció miatt a menüt az ALT helyett az F10 gombbal lehet elôhívni. */
'activateaccel'  /* Aktiválja a változtatásokat */

Az EPM rendelkezik elôre definiált billentyûkombinációkkal is. Ezeket is végre lehet hajtani REXX-bôl az EtkProcessEditKey utasítással:

CALL EtkProcessEditKey billentyû

Csalafinta módon a billentyû paraméter helyén nem a funkcióhoz hozzárendelt billentyûkombinációt kell megadni, hanem a funkciót definiáló függvény nevét. A lehetséges értékeket alábbi táblázatunk mutatja:

Függvény:Billentyûkombináció:Billentyûfunkció:
ADJUST_BLOCKALT+AA kijelölt szöveget szóközökre cseréli.
BACKTABSHIFT+TABVisszaviszi a kurzort egy TAB-bal.
BACKTAB_WORDCTRL+LEFTVisszaviszi a kurzort az elôzô szó elsô karakterére.
BEGIN_LINEHOMEVisszaviszi a kurzort a sor elejére.
BOTTOMCTRL+ENDA kurzort az utolsó sorra pozícionálja.
CENTER???Középre állítja a szöveget.
COPY_MARKALT+CA jelenlegi pozícióba másolja a kijelölt szöveget.
DELETE_CHARDELETEKitörli az aktuális pozíción található karaktert.
DELETE_LINECTRL+BACKSPACEKitörli az aktuális sort.
DELETE_MARKALT+DKitörli a kijelölt szöveget.
ERASE_END_LINECTRL+ETörli a kurzortól a sor végéig terjedô szöveget.
INSERT_TOGGLEINSERTVáltogat az insert és replace (betoldás és felülírás) módok között.
JOINALT+JÖsszetoldja a következô sort a jelenlegivel.
MARK_BLOCKALT+BSzövegkijelölés.
MARK_BLOCKG Szövegkijelölés, amely a kurzortól balra történik.
MARK_CHARALT+ZKarakterkijelölés.
MARK_CHARG Kijelöli a kurzortól balra álló karaktert.
MARK_LINEALT+LSorkijelölés.
MARK_LINEG Ugyanaz, mint a MARK_LINE.
MOVE_MARKALT+MA kijelölt szöveget átteszi a kurzor pozíciójába.
NEXT_FILEF12Átvált a következô fájlra.
OVERLAY_BLOCKALT+OÁtmásolja a kurzortól balra esô kijelölt szöveget a kurzor jobb oldalára.
PREVFILEF11Visszavált az elôzô fájlra.
REFLOWALT+PÁtformázza a kijelölt szöveget.
REFRESH Frissíti az EPM ablakokat.
REPEAT_FINDCTRL+FMegismétli a legutolsó keresést.
RUBOUTBACKSPACEDestruktív backspace.
SHIFT_LEFTCTRL+F7Balra lépteti a kijelölt szöveget.
SHIFT_RIGHTCTRL+F8Jobbra lépteti a kijelölt szöveget.
SPLITALT+SKettéosztja az aktuális sort a kurzor pozíciójánál.
TAB_WORDCTRL+RIGHTA kurzort a következô szó elsô karakterére pozícionálja.
TOPCTRL+HOMEA kurzort az elsô sorra pozícionálja.
UNDOF9 vagy ALT+BACKSPACEVisszacsinálja az aktuális sorban végzett legutolsó változtatást.
UNDOACTION
UNMARKALT+UEltávolítja a kijelöléseket.

Menük készítése

Az EPM menüi szintén konfigurálhatók REXX-bôl, a buildsubmenu és buildmenuitem parancsok segítségével:

buildsubmenu menünév almenü-ID menüszöveg attribútum help [parancs]
buildmenuitem menünév almenü-ID menü-ID menüszöveg attribútum help parancs

A menünév paraméter adja meg az EPM menü nevét. Az alapértelmezett menü neve default. Az almenü-ID egy olyan egyedi szám, amely az almenüt azonosítja. A menü-ID szintén egyedi kell, hogy legyen, ez azonban az almenü egyes elemeit azonosítja. A menüszöveg értéke fog megjelenni az EPM menüsorában. A help paraméterrel a help panel számára lehet hivatkozni; ha nincs segítség, akkor 0-ra kell állítani. Az attrib paraméterrel a menüpont tulajdonságait lehet beállítani, többnyire ezt is 0-ra állítjuk. A legutolsó paraméter adja meg a végrehajtandó parancsot, amely természetesen lehet egy REXX makró is.

Egérmûveletek definiálása

Az elôzôek után talán már nem lep meg bennünket az sem, hogy az EPM-ben az egérmûveletek is átdefiniálhatók REXX makrókkal. Az erre a célra használható parancs szintakszisa a következô:

register_mouse globál gomb esemény extra parancs

Az elsô paraméter határozza meg, hogy a definiált mûvelet az összes fájlra (1), vagy pedig csak az aktuális fájlra (0) érvényes. A gomb értéke 1, 2 vagy 3 lehet. Ez a paraméter szolgál a használni kívánt egérgomb azonosítására. A esemény lehetséges értéke az alábbi táblázatban összegyûjtött értékek valamelyike lehet. Az extra paraméter definiálja, hogy a figyeljük-e a speciális billentyûk megnyomását is (SHIFT=1, CTRL=2, ALT=4, nincs extra billentyû figyelés=0). Az esemény bekövetkezésekor végrehajtandó parancsot az utolsó paraméter adja meg.

Esemény:Leírás:
CLICKKlikkantás az egérrel.
SECONDCLKDupla klikkantás.
BEGINDRAGVontatás.
ENDDRAGLedobás.
CANCELDRAGA vontatás törlése.

Az EPM profil átalakítása

Az EPM lehetôvé teszi, hogy az editor elindításakor lefuttassunk egy makrót (a'la startup.cmd). A makró neve PROFILE.ERX. Amennyiben kedvünk tartja, kedvenc beállításainkat belerakhatjuk ebbe a makróba, így azok minden indításkor automatikusan be fognak töltôdni. Amennyiben létezik a PROFILE.EXE, akkor az EPM parancssorában csak ki kell adni a profile on parancsot, majd az Option menüben vegyük fel a változtatásokat.

Egyéb, REXX-et használó alkalmazások

Jó néhány OS/2-es alkalmazás támogatja a REXX használatát. A LiveWire shareware kommunikációs alkalmazás például lehetôvé teszi REXX makrók számára az alkalmazás által nyújtott teljes funkcionalitás használatát. A bemeneti és kimeneti üzenetek a terminálablakban jelennek meg. Egy másik példa a DeScribe szövegszerkesztô. Amennyiben REXX makrókat akarunk ebben az alkalmazásban használni, akkor írni kell egy DeScribe makrót, amelybôl a RunREXXFile paranccsal hívhatjuk meg a REXX programokat. Egy másik sokak által használt szövegszerkesztô, amely szintén használ REXX scripteket, az AmiPro. Ebben a programban lehetôség van a REXX makrók közvetlen futtatására is.


REXX GYÍK:

K1. Milyen információforrások vannak, amelyekbôl bôvebb EPM ismereteket szerezhetek?
V1. A http://hobbes.nmsu.edu-n több olyan dokumentum is található, amelyekbôl további információkhoz juthatunk. Ugyanezen a site-on sok hasznos EPM kiegészítô programot is találhatunk.


Gyakorlatok:

1. Nevezzen meg olyan OS/2 alkalmazásokat, amelyek szintén használnak REXX makrókat!

2. Készítsen egy REXX makrót az EPM-hez, amely nagybetûsre alakítja azt a szót, amely fölött az egérmutató áll, ha megnyomjuk a CTRL billentyût és az egér bal gombját!

Kádár Zsolt
1998. 10. 31.
[ Elôzô lecke | Következô lecke | Tartalom ]