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: |
| ABORTRETRYIGNORE | Abort, Retry és Ignore gombok |
| CANCEL | Cancel gomb |
| ENTER | Enter gomb |
| ENTERCANCEL | Enter és Cancel gombok |
| OK | OK gomb, default |
| OKCANCEL | OK és Cancel gomb |
| RETRYCANCEL | Retry és Cancel gombok |
| YESNO | Yes és No gombok |
| YESNOCANCEL | Yes, No és Cancel gombok |
| Ikonstílus: | Eredmény: |
| ASTERISK | Csillag ikon |
| ERROR | Error ikon |
| EXCLAMATION | Felkiáltójel ikon |
| HAND | Kéz ikon |
| INFORMATION | Információ ikon |
| NONE | Nincs ikon, ez a default |
| QUERY | Keresés ikon |
| QUESTION | Kérdés ikon |
| WARNING | Figyelmezteté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: |
| 1 | OK |
| 2 | Cancel |
| 3 | Abort |
| 4 | Retry |
| 5 | Ignore |
| 6 | Yes |
| 7 | No |
| 8 | Enter |
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: |
| autosave | Hány változtatás után mentse el az EPM automatikusan a fájlt. A 0 autosave érték kikapcsolja ezt a funkciót. |
| col | A kurzornak a sor elejéhez viszonyított oszloppozíciója. Lehetséges értékek: 1-tôl 255-ig. |
| cursorx | A kurzor ablakhoz viszonyított oszloppozíciója. |
| cursory | A kurzor ablakhoz viszonyított sorpozíciója. |
| dragcolor | A mouse által kijelölt vontatási terület színe. |
| dragstyle | A 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. |
| eaarea | Mutató, amely az EPM kiterjesztett attribútum területére mutat. |
| filename | Az éppen szerkesztett fájl neve a teljes elérési útvonallal. |
| font | Az alapértelmezett font száma. |
| fontheight | A font magassága pixelben. |
| fontwidth | A font szélessége pixelben. |
| getline | Az aktív sor tartalma. |
| getmark | A 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. |
| getmarktype | A kijelölés típusa: LINE, CHAR, BLOCK, CHARG, BLOCKG, vagy üres sztring, amennyiben nincs kijelölve semmi. |
| last | A sorok száma. |
| line | Az éppen aktív sor száma. |
| lockhandle | A 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. |
| markcolor | A kijelölt szöveg színe. |
| modify | A fájlon végzett változtatások száma. |
| mousex | A mouse X koordinátája. |
| mousey | A mouse Y koordinátája. |
| textcolor | A szöveg színe. |
| userstring | A felhasználó által definiálható érték. |
| version | Az EPM verziószáma. |
| visible | Jelzi, hogy a fájl éppen látható-e. |
| windowheight | Az ablakban látható sorok száma. |
| windowwidth | Az ablakban látható oszlopok száma. |
| windowx | Az ablak X koordinátája (0 az újabb EPM-ekben). |
| windowy | Az 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]](lecke05a.gif)
Ha a makró sikeresen lefutott, akkor az alábbihoz hasonló fájl kell, hogy megjelenjen az EPM-ben:
![[lecke05b.gif]](lecke05b.gif)
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_BLOCK | ALT+A | A kijelölt szöveget szóközökre cseréli. |
| BACKTAB | SHIFT+TAB | Visszaviszi a kurzort egy TAB-bal. |
| BACKTAB_WORD | CTRL+LEFT | Visszaviszi a kurzort az elôzô szó elsô karakterére. |
| BEGIN_LINE | HOME | Visszaviszi a kurzort a sor elejére. |
| BOTTOM | CTRL+END | A kurzort az utolsó sorra pozícionálja. |
| CENTER | ??? | Középre állítja a szöveget. |
| COPY_MARK | ALT+C | A jelenlegi pozícióba másolja a kijelölt szöveget. |
| DELETE_CHAR | DELETE | Kitörli az aktuális pozíción található karaktert. |
| DELETE_LINE | CTRL+BACKSPACE | Kitörli az aktuális sort. |
| DELETE_MARK | ALT+D | Kitörli a kijelölt szöveget. |
| ERASE_END_LINE | CTRL+E | Törli a kurzortól a sor végéig terjedô szöveget. |
| INSERT_TOGGLE | INSERT | Váltogat az insert és replace (betoldás és felülírás) módok között. |
| JOIN | ALT+J | Összetoldja a következô sort a jelenlegivel. |
| MARK_BLOCK | ALT+B | Szövegkijelölés. |
| MARK_BLOCKG | Szövegkijelölés, amely a kurzortól balra történik. | |
| MARK_CHAR | ALT+Z | Karakterkijelölés. |
| MARK_CHARG | Kijelöli a kurzortól balra álló karaktert. | |
| MARK_LINE | ALT+L | Sorkijelölés. |
| MARK_LINEG | Ugyanaz, mint a MARK_LINE. | |
| MOVE_MARK | ALT+M | A kijelölt szöveget átteszi a kurzor pozíciójába. |
| NEXT_FILE | F12 | Átvált a következô fájlra. |
| OVERLAY_BLOCK | ALT+O | Átmásolja a kurzortól balra esô kijelölt szöveget a kurzor jobb oldalára. |
| PREVFILE | F11 | Visszavált az elôzô fájlra. |
| REFLOW | ALT+P | Átformázza a kijelölt szöveget. |
| REFRESH | Frissíti az EPM ablakokat. | |
| REPEAT_FIND | CTRL+F | Megismétli a legutolsó keresést. |
| RUBOUT | BACKSPACE | Destruktív backspace. |
| SHIFT_LEFT | CTRL+F7 | Balra lépteti a kijelölt szöveget. |
| SHIFT_RIGHT | CTRL+F8 | Jobbra lépteti a kijelölt szöveget. |
| SPLIT | ALT+S | Kettéosztja az aktuális sort a kurzor pozíciójánál. |
| TAB_WORD | CTRL+RIGHT | A kurzort a következô szó elsô karakterére pozícionálja. |
| TOP | CTRL+HOME | A kurzort az elsô sorra pozícionálja. |
| UNDO | F9 vagy ALT+BACKSPACE | Visszacsinálja az aktuális sorban végzett legutolsó változtatást. |
| UNDOACTION | ||
| UNMARK | ALT+U | Eltá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: |
| CLICK | Klikkantás az egérrel. |
| SECONDCLK | Dupla klikkantás. |
| BEGINDRAG | Vontatás. |
| ENDDRAG | Ledobás. |
| CANCELDRAG | A 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 ] |