/* GUIBEGIN WINDOW , 33, 94, 216, 138, POPUP|CAPTION|SYSMENU|MINBOX|MAXBOX|THICK, , Editor FONT 8, 400, MS Shell Dlg MENU ENTRY 0, 0, 32, 12, MULTI|V_AUTO|H_AUTO|RETURN, , TEXT DEND MENU HEADING File ITEM New ITEM Open ITEM ITEM Save ITEM Save as ITEM ITEM Exit < HEADING Edit ITEM Cut, , CTRL "X" ITEM Copy, , CTRL "C" ITEM Paste, , CTRL "V" < HEADING REXX ITEM &Run as script, , CTRL "R" < DEND GUIEND */ /* An example of a simple text editor. * * We create a main window. In it, we place one ENTRY control. It has the * MULTI style so the user can enter numerous lines of text. * * We also have a menu. It has a File->Load item whereby we use GuiFile() * to pick out the name of the text file to load. (ASCII format only). * * We also have a "Rexx->Run as script" menu item to run the text as a script. */ OPTIONS "C_CALL LABELCHECK WINFUNC NOSOURCE" /* Load the REXX GUI functions. */ LIBRARY rexxgui /* Let REXX GUI raise SYNTAX for errors. */ GuiErr = "SYNTAX" GuiHeading = 1 /* Store the filename in the variable FN */ FN = '' /* Default contents is an empty file. If the user supplied a text file * name on the command line when running this script, let's load that * file into TEXT */ TEXT = '' /* Create our main window. */ GuiCreateWindow('NORMAL') /* Resize our ENTRY to fill the inner window. */ GuiGetCtlPlacement(, , , 'Width', 'Height') GuiSetCtlPlacement('TEXT', , , Width, Height) /* Main message loop */ Again: DO FOREVER GuiGetMsg() CATCH SYNTAX CONDITION('M') SIGNAL Again CATCH HALT FINALLY GuiDestroyWindow() END RETURN CheckIfSaved: /* See if the contents of the ENTRY were altered. */ GuiSendMsg('TEXT', 'GETMODIFY') IF GuiSignal == 1 THEN DO /* Contents were changed. Ask if he wants to save. */ err = GuiSay('Save the current changes?', 'YESCANCEL|INFO') IF err == 'CANCEL' THEN RETURN -1 IF err == 'YES' THEN RETURN FileSave() END RETURN 0 /* ================== "New" menu item ====================== */ FileNew: /* See if the contents need to be saved. */ IF CheckIfSaved() \== 0 THEN RETURN /* Blank the Window title bar */ GuiAddCtlText(GuiWindow) /* Empty the contents */ TEXT.0 = 0 GuiSetCtlValue('TEXT') /* Text is not modified yet. */ GuiSendMsg('TEXT', 'SETMODIFY', 0) RETURN /* ================== "Open" menu item ====================== */ FileOpen: /* See if the contents need to be saved. */ IF CheckIfSaved() \== 0 THEN RETURN DO /* Here are our file extensions that we filter -- .rex, .txt, and all files */ extensions = 'REXX scripts (*.rex) | *.rex | Text files (*.txt) | *.txt | All files (*.*) | *.*' /* Do the File Dialog */ GuiFile('FN', 'HIDEREADONLY|PATH|DIR', 'Pick out a text file', extensions) /* If he cancels or there is an error, we CATCH here. */ CATCH SYNTAX RETURN END DO /* Load the file into the 'TEXT.' stem variable */ LoadText('TEXT', FN) /* Put the file contents into our ENTRY */ GuiSetCtlValue('TEXT') DROP TEXT. /* Set the Window title bar with our filename. Replace \ chars with / because * REXX GUI uses these chars for \t (TAB) and \n (new line) */ GuiAddCtlText(GuiWindow, TRANSLATE(FN, '/', '\')) CATCH NOTREADY CONDITION('M') END /* Text is not modified yet. */ GuiSendMsg('TEXT', 'SETMODIFY', 0) /* Done */ RETURN /* ================== "Save As" menu item ====================== */ FileSaveAs: DO /* Here are our file extensions that we filter -- .rex, .txt, and all files */ extensions = 'REXX scripts (*.rex) | *.rex | Text files (*.txt) | *.txt | All files (*.*) | *.*' /* Do the File Dialog */ GuiFile('FN', 'HIDEREADONLY|OVERWRITE|SAVE|PATH|DIR', 'Save a text file', extensions) /* If he cancels or there is an error, we CATCH here. */ CATCH SYNTAX RETURN -1 END /* Drop down into the "Save" code */ /* ================== "Save" menu item ====================== */ FileSave: /* Make sure that we don't have an empty file name. If so, * force him to pick a name now. */ IF FN = "" THEN SIGNAL FileSaveAs /* Get the contents of our ENTRY into the variable 'GuiSignal' as one string. */ GuiSendMsg('TEXT', 'GETTEXT') DO /* Open the file, overwriting any previous contents. */ STREAM(FN, 'C', 'OPEN WRITE REPLACE') /* Write the contents out to the file. */ CHAROUT(FN, GuiSignal) CATCH NOTREADY CONDITION('M') FINALLY /* Close the file */ STREAM(FN, 'C', 'CLOSE') END /* Success. */ RETURN 0 /* ================== "Exit" menu item ====================== */ FileExit: /* Post a WM_CLOSE message to our main window. */ GuiSendMsg(, 'POST CLOSE') RETURN /* =================== "Cut" menu item ====================== */ EditCut: /* To cut an ENTRY's currently selected text to the clipboard, * we call GuiRemoveCtlText() and omit the second arg. */ GuiRemoveCtlText('TEXT') RETURN /* ================== "Copy" menu item ====================== */ EditCopy: /* To copy an ENTRY's currently selected text to the clipboard, * we send it a COPY message. */ GuiSendMsg('TEXT', 'COPY') RETURN /* ================== "Paste" menu item ===================== */ EditPaste: /* To paste the clipboard over an ENTRY's current selection, * we call GuiAddCtlText, and omit the second arg. */ GuiAddCtlText("TEXT") RETURN /* =================== "Run as script" menu item ====================== */ RexxRunAsScript: PROCEDURE /* Get whether the ENTRY's contents have been modified * without yet being returned to us (ie, without us * saving the modified contents to disk). */ GuiSendMsg('TEXT', 'GETMODIFY') flag = GuiSignal /* Get the contents of our ENTRY into the variable 'GuiSignal' as one string. */ GuiSendMsg('TEXT', 'GETTEXT') /* Run it as a REXX script, passing it no args. */ INTERPRET GuiSignal /* Reset the state prior to our fetching the contents */ GuiSendMsg('TEXT', 'SETMODIFY', flag) /* Return to main */ RETURN /* ====================== WM_SIZE ========================== * This is our window's SIZE event handler. It is called by * Reginald when the user finishes sizing the window. * * ARG(1) = The new inner width of the window (ie, the * client area -- not including borders, title * bar, and menu. * ARG(2) = The new inner height. */ WM_SIZE: /* The first time this event happens, our ENTRY has not * yet been created. So, GuiSetCtlPlacement will cause * a SYNTAX error. Let's trap that here, and just ignore * it. */ DO /* Resize our ENTRY to fill the inner window. */ GuiSetCtlPlacement('TEXT', , , ARG(3), ARG(4)) CATCH SYNTAX END /* Don't let REXX GUI handle this message. */ RETURN "" /* ====================== WM_CLOSE ========================== * This is our window's CLOSE event handler. It is called by * Reginald when the user wants to close the window, or * someone has sent our window a CLOSE message (like we do * when the user selects the File->Exit menu item). */ WM_CLOSE: /* See if the contents need to be saved. If a problem or he cancels, * then return 0 to prevent our window from closing. */ /* IF CheckIfSaved() \== 0 THEN RETURN 0 */ /* Don't return anything so that REXX GUI allows the window * to be closed. */ RETURN