ZBasic TextEdit
Volume Number: 3
Issue Number: 11
Column Tag: Basic School
TextEdit Records from ZBasic 
By Dave Kelly, MacTutor Editorial Board
How NOT to Do TextEdit
In past months I promised you some more on text editing. I really intended to
give you a text processor written completely in ZBasic. Well, this article is dedicated
to the time that it took to find out what not to do if you plan on creating a full blown
text processor. This column may not be all that was promised, but it should provide
some help to those of you that don’t know what to do with text edit routines.
Basic or Toolbox?
We have talked about text editing in some of the past issues (see June, 1987 and
August, 1987). I’ll try to pick up where we left off wherever that might be. There
are two varieties of Basic programming. The soft approach uses only the enhanced
Basic language provided by the language developer. These high level routines are short
cuts that should save you time and increase your chances of getting your program to
work quickly and efficiently. The other approach is the ROM calls approach.
Effectively, the ROM approach is what C and Pascal programmers have to do every time
they write a program unless they have some preprogrammed “libraries” to set up
scroll bars, windows, text edit fields etc. for you. (Maybe that’s the best approach).
Ideally speaking, I think we want the best of both worlds. We want to be able to set up
the basic functions with high level routines, but be able to have the capability (power)
to call low level (ROM) routines when the capabilities of the high level routines are
not sufficient.
Basic Flunks Text Editing
Why am I telling you all this? Well, I tell you this so you can be warned in
advance of the limitations of thinking that the enhanced BASIC routines will always be
good enough to do the job. Text Editing is one of these cases. The present capabilities of
ALL Basic languages enhanced Basic commands are not enough to do text editing without
relying on calls to the ROM routines. I am referring to the use of the EDIT FIELD
statements in either MS Basic or ZBasic. In MS Basic you are limited to 8 types of edit
fields with no way to access the Text Edit record or to scroll the text in the edit field.
The ScrollText Library call will allow you to do some limited scrolling, however, does
not provide a way to cut and paste easily. (see The Complete MacTutor, Vol. 2, pg. 345
for examples of scrolling with MS Basic.) Since there has been no word from Microsoft
in about a year (and no updates of MS Basic), Microsoft Basic is pretty much out of the
running at the present time.
Text editing in ZBasic is much more useful. ZBasic has 4 types of Edit Fields (the
text is always selected when default text is used). The best addition is the TEHANDLE
function. TEHANDLE gives you the capability to get to the Edit Field’s text record. It
sounds simple, but there are some other limitations that I might classify as bugs. Yes,
I’ve found a bug, but don’t misunderstand me. ZBasic is a very sound product these
days. The problems have resulted in my spending a lot of time searching out the best
way not to do text editing.
TEHandle Function in ZBasic
First I will try to explain the usefulness of the TEHANDLE function. The example
in the ZBasic manual, pg. E-141 demonstrates TEHANDLE, but the example is more
useful for what it does than it is as an example of how to use TEHANDLE. In fact, the
functions defined in the example can be cut and pasted into your own program to allow
you to pass EDIT FIELD strings longer than 255 characters (ZBasic’s limit). I
recommend that you use these routines if you have a need to handle long strings. The
definition of how TEHANDLE works is conspicuously missing. The top of the page says
the format is just TEHANDLE with no parameters. In fact, TEHANDLE by itself gives a
syntax error. A close look at the functions defined in the example show that the format
should be: TEHANDLE (field ) where field is the field number. Here is what is
confusing: The definition in the manual says that TEHANDLE “Returns the handle to the
current EDIT FIELD” and that the purpose is to be able to handle fields larger than
255 characters. Well, I guess they didn’t think that anyone would want to do more
than that.
The problem I have encountered is that TEHANDLE only works if the value of field
is 1. That is, it only works for the first EDIT FIELD of a window. For instance, if you
change the EDIT FIELD number of the example on page E-141 to 2 and adjust all the
function calls such that they will also refer to field 2, the example program will
gracefully bomb. Zedcor tells me they think there is a problem with some changes that
were made with system version 4.1 and ZBasic 4.0. ZBasic 4.01 should soon be out.
[Where have we heard that before? -Ed]
For me, the importance of getting at the text edit record is to be able to add
power to my program to control where the text is located, where it is viewed, what
part of the text is selected, and even change fonts and size information (among other
things). A text edit record is created for each EDIT FIELD you create. The record,
shown on pg. E-183 of the ZBasic manual, is stored in the heap with other resources.
It turns out however that it was not intended that the user have this kind of capability
with ZBasic EDIT FIELDS. For example, if you have several EDIT FIELDS on your
screen, you will have trouble changing fonts or font sizes in one field (by poking the
font id into the edit record) without affecting the other fields or even the printing on
the screen. It appears that the built-in automatic EDIT FIELD update routines won’t
let the text font or style change after it has been created. Another disappointment is
that the EDIT FIELD automatic routines reset the text to the beginning of the window so
that text scrolling is impossible (or very cumbersome). The bottom line is that the
ROM routines will need to be used in full to really have control over what the EDIT
FIELD does.
Complications Set In
This leads us to another problem. If you use the TENEW function (ROM) to create
the Text Edit Field the ZBasic DIALOG statement will not know how to tell the Dialog
Event routine that a text edit event has occurred. Then how do you process the events?
Well, how about GETNEXTEVENT ? (discussed in Sept. 1987 MacTutor). Hmm but if
I’ve got to go to all that trouble why not just use Pascal and not have all the
limitations that Basic leaves us with. Not only that but the Pascal routines have been
used hundreds of times before and there are a lot of examples available. Doesn’t sound
too promising for BASIC. I think that is why so many serious developers only use
Basic occasionally for easy, short, quick routines. Take a look at the Mousehole Basic
Only board and compare it with the Pascal or C board and you’ll see what I mean. In the
August 1987 APDA catalog there is a graph on page 11 showing the results of a survey
done in 1985. The results are that 30% prefer C, 28% prefer Pascal, 20% prefer
assembler, 6% prefer Basic, 4% Forth, 4% Modula-2, 4% LISP, 4% Other. These
results were before TML and Lightspeed Pascal became popular so there might be some
changes to the high end of the scale. (See figure 1)
Fig. 1 1985 APDA Survey of Preferred Languages
So what do we do about it? Sit back and wait for Zedcor to improve their product.
In this case, the limitations are created only because Zedcor has not provided access to
all routines via the high level enhanced BASIC routines. Fortunately, they did provide
the ROM routine capability to do the job. The problem is that it will be just as much
work to write a ROM program in BASIC as it would be in PASCAL. Zedcor still has the
finest Basic available and they have thus far provided excellent support of the
language. I realize that some of you have been upset that you have been the guinea pigs
while the bugs were worked on. For those of you that have lost hope, you can be
assured that ZBasic is now a solid product.
The program I’ve provided here is the results of my attempts to take the EDIT
FIELD to its maximum capability. I refer to it as a tour of the Edit Field because it
gives you an overview of Edit Fields and Text Edit Records. The program is set up in a
similar manner to the TEHANDLE example in the ZBasic manual pg. E-141 except that
I have added the capability to view the entire text edit record and attempt to change the
values of the edit record. If you type in the byte offset of the edit record (found on
E-183) you can see which of the parameters of the record can be changed and which
ones change back when the EDIT FIELD is updated. Figure 2 shows the text edit record
and is displayed as a menu function by the program. Figure 3 shows the program in
action. A text edit window is put up, with the text edit fields displayed below. The
program is supposed to work correctly on a large screen (Mac II), but the default
window size comes up and obscures some of the field information.
Fig. 2 The Text Edit Record
Fig. 3 Our Demo Program in Action
Program Details
First a window is opened to full screen size (same as your monitor). By calling
GETWMGRPORT as Dave Smith suggested I’ve modified the routine from what was in the
Sept. 1987 MacTutor. Three EDIT FIELDS are opened. The first is the main text edit
field the other two are for convenience in entering data to change the text edit record.
The SCROLL BUTTON statement was intended to be used, but has not been
implemented. It appears that since the canned EDIT FIELD seems to reset itself to the
first line of the text, TESCROLL cannot be used with EDIT FIELDs. You would have to
create your own TE field with ROM calls.
Generally speaking, the “MenuEvent” and “DialogEvent” routines don’t change a
whole lot from program to program. Since the EDIT FIELD is a canned function
(preprogrammed, automatic function), it is not necessary to call any ROM routines to
handle the basic functions of the EDIT FIELD. ZBasic handles calls like TEIDLE for you.
The user defined function teWordPeek% helps to shorten the typing involved in the text
edit record list.
There is a problem that I discovered in my early version of the program before I
removed the growbox from the window. It seems that if you resize the window, the text
that was printed with PRINT @(x,y) does not print at x,y when the point x,y is outside
the visible range of the window. The same can be said for the LOCATE statement. The
solution would be to use the DRAWSTRING ROM call to draw the text at a specific
location.
The buttonevent routine is supposed to handle the reading of the byte to be
changed and the new value. The problem here was that the TEHANDLE function would
not work for a 2nd or 3rd EDIT FIELD.
As you can see, there is still a bit of work to be done here, if possible. From what
I can tell here, I recommend that ROM calls be used for any major text editing. This
will have to be followed up on in future issues of MacTutor.
{1}
‘Edit Field Tour
‘A software explanation of the Text Edit Record
‘WARNING: Some portions of this program do not
‘function properly. USE AT YOUR OWN RISK!
‘the ZBasic way.
‘©MacTutor, 1987
‘By Dave Kelly
WINDOW OFF
COORDINATE WINDOW
DEF MOUSE =-1
DIM DestRect%(3)
CALL GETWMGRPORT(WMgrPort&)
‘Figure out the size of monitor used
PortRecttop=PEEK WORD(WMgrPort&+8)
PortRectleft=PEEK WORD(WMgrPort&+10)
PortRectbottom=PEEK WORD(WMgrPort&+12)
PortRectright=PEEK WORD(WMgrPort&+14)
WINDOW 1,”TEdit Tour”,(PortRectleft+4,PortRecttop+42)-
(PortRectright-6,PortRectbottom-6),5
TEXT ,,,0
EDIT FIELD 1,defaulttext$,(4,4)-(WINDOW(2)-16,
WINDOW(3)/2), 2
SCROLL BUTTON 1,0,0,10,10,(WINDOW(2)-16,3)-
(WINDOW(2),WINDOW(3)/2+1),0
CALL MOVETO(4,(WINDOW(3)/2)+22)
CALL DRAWSTRING(“Change Byte:”)
EDIT FIELD 2,,(90,(WINDOW(3)/2)+13)-(105,
(WINDOW(3)/2)+25)
EFHndl2&=TEHANDLE(2)
CALL MOVETO(111,(WINDOW(3)/2)+22)
CALL DRAWSTRING(“TO”)
EDIT FIELD 3,,(140,(WINDOW(3)/2)+13)-(155,
(WINDOW(3)/2)+25)
EFHndl3&=TEHANDLE(3)
BUTTON 3,1,”Enter”,(170,(WINDOW(3)/2)+11)-(240,
(WINDOW(3)/2)+27)
APPLE MENU “TEdit Tour”
MENU 1,0,1,”File”
MENU 1,1,1,”View Text Edit Record”
MENU 1,2,0,”-”
MENU 1,3,1,”Quit/Q”
EDIT MENU 2
DEF FN teWordPeek%(n)=PEEK WORD(PEEK LONG(TEHANDLE(1))+n)
DEF FN teLongPeek&(n)=PEEK LONG(PEEK LONG(TEHANDLE(1))+n)
EDIT FIELD 1:CurrentField=1
ON DIALOG GOSUB “DialogEvent”
ON MENU GOSUB “MenuEvent”
FLUSHEVENTS
MENU ON:DIALOG ON
“Loop”
GOSUB “Info”
GOTO “Loop”
MENU OFF:DIALOG OFF
“DialogEvent”
D=DIALOG(0)
SELECT D
CASE 1
GOSUB “ButtonEvent”