home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
books
/
progem
/
resource.4
< prev
next >
Wrap
Text File
|
1986-11-01
|
33KB
|
725 lines
Permission to reprint or excerpt is granted only if the following line
appears at the top of the article:
ANTIC PUBLISHING INC., COPYRIGHT 1985. REPRINTED BY PERMISSION.
Professional GEM by Tim Oren
Column #4 - The Resource file
Welcome to the fourth installment of ST PRO GEM. We are about to
delve into the mysteries of GEM resource structure, and then use this
knowledge to create some useful utilities for handling dialogs. As
with the past columns, there is once again a download file. You will
find it under the name GEMCL4.C in the ATARI 16-bit Forum (GO PCS-58).
The first and largest part of the download contains a C image of a
sample resource file. To create this listing, I used the GEM Resource
Construction Set to create a dummy resource with three dialogs
including examples of all object types, then enabled the C output
option and saved the resource. If you have access to a copy of RCS, I
suggest that you create your own listing in order to get a feel for the
results. Then, using either listing as a roadmap to the resource, you
can follow along as we enter...
A MAZE OF TWISTY LITTLE PASSAGES
While a GEM resource is loaded as a block of binary information, it
is actually composed of a number of different data structures. These
structures are linked together in a rather tangled hierarchy. Our
first job is to map this linkage system.
The topmost structure in a resource file is the resource header.
This is an array of words containing the size and offset within the
resource of the other structures which follow. This information is
used by GEM during the resource load process, and you should never need
to access it. (The resource header does not appear in the C output
file; it is generated by the RSCREATE utility if the C file is used to
recreate the resource.)
The next structure of interest is the tree index. This is an array
of long pointers, each of which addresses the beginning of an object
tree. Again, you wouldn't normally access this structure directly. The
GEM rsrc_gaddr call uses it when finding trees' addresses. This
structure is called "rs_trindex" in the C output.
If you look at the contents of rs_trindex you will notice that the
values are integers, instead of the pointers I described. What has
happened is that RCS has converted the pointers to indices into the
object array. (If you actually used the C file to recreate the resource
file, then the pointers would be regenerated by RSCREATE.)
Now you can follow the link from rs_trindex to the objects stored in
rs_object. Take (for instance) the second entry in rs_trindex and
count down that many lines in rs_object. The following line (object)
should start with a -1. This indicates that it is the root object of a
tree. The following objects down to the next root belong to that tree.
We'll pass over the details of inter-object linkage for now, leaving it
for a later column.
There are a number of different fields in an object, but right now
we'll concentrate on two of them: OB_TYPE and OB_SPEC. The OB_TYPE is
the field which contains mnemonics like G_STRING and G_BOX indicating
the type of the object. The OB_SPEC is the only field in each object
which is a LONG - you can tell it by the L after the number.
What's in OB_SPEC depends on the object type, so we need to talk
about what kinds of objects are available, what you might use them for,
and finally how they use the OB_SPEC field.
The box type objects are G_BOX, G_IBOX, and G_BOXCHAR. A G_BOX is
an opaque rectangle, with an optional border. It's used to create a
solid patch of color or pattern on which to place other objects. For
instance, the background of a dialog is a G_BOX.
A G_IBOX is a hollow box which has only a border. (If the border
has no thickness, then the box is "invisible", hence the name.) The
favorite use for IBOXes is to hold radio buttons. There is also one
neat trick you can play with an IBOX. If you have more than one object
(say an image and a string) which you would like to have selected all
at once, you can insert them in a dialog, then cover them with an IBOX.
Since the box is transparent, they will show through. If you now make
the box selectable, clicking on it will highlight the whole area at
once!
The G_BOXCHAR is just like a G_BOX, except that a single character
is drawn in its center. They are mostly used as "control points": the
FULLER, CLOSER, SIZER, and arrows in GEM windows are BOXCHARs, as are
the components of the color selection gadgets in the RCS.
The OB_SPEC for box type objects is a packed bit array. Its various
fields contain the background color and pattern, the border thickness
and color, and the optional character and its color.
The string type objects are G_STRING, G_BUTTON, and G_TITLE.
G_STRINGs (in addition to being a bad pun) are for setting up static
explanatory text within dialogs. The characters are always written in
the "system font": full size, black, with no special effects.
We have already discussed many of the uses of G_BUTTONs. They add a
border around the text. The thickness of a G_BUTTON's border is
determined by what flags are set for the object. All buttons start out
with a border thickness of one pixel. One pixel is added if the EXIT
attribute is set, and one more is added if the DEFAULT attribute is
set.
The G_TITLE type is a specially formatted text string used only in
the title bar of menus. This type is needed to make sure that the
menus redraw correctly. The Resource Construction Set automatically
handles inserting G_TITLEs, so you will seldom use them directly.
In a resource, the OB_SPEC for all string objects is a long pointer
to a null terminated ASCII string. The string data in the C file is
shown in the BYTE array rs_strings. Again you will notice that the
OB_SPECs in the C file have been converted to indices into rs_string.
To find the string which matches the object, take the value of OB_SPEC
and count down that many lines in rs_strings. The next line is the
correct string.
The formatted text object types are G_TEXT, G_BOXTEXT, G_FTEXT, and
G_FBOXTEXT. G_TEXTs are a lot like strings, except that you can
specify a color, different sizes, and a positioning rule for the text.
Since they require more memory than G_STRINGs, G_TEXTs should be used
sparingly to draw attention to important information within a dialog.
G_TEXTs are also useful for automatic centering of dialog text which is
changed at run-time. I will describe this technique in detail later
on.
The G_BOXTEXT type adds a solid background and border to the G_TEXT
type. These objects are occasionally used in place of G_BUTTONs when
their color will draw attention to an important object.
The G_FTEXT object is an editable text field. You are able to
specify a constant "template" of characters, a validation field for
those characters which are to be typed in, and an initial value for the
input characters. You may also select color, size, and positioning
rule for G_FTEXTs. We'll discuss text editing at length below.
The G_FBOXTEXT object, as you might suspect, is the same as G_FTEXT
with the addition of background and border. This type is seldom used:
the extra appearance details distract attention from the text being
edited.
The OB_SPEC for a formatted text object is a pointer to yet another
type of structure: a TEDINFO. In the C file, you will find these in
rs_tedinfo. Take the OB_SPEC value from each text type object and
count down that many entries in rs_tedinfo, finding the matching
TEDINFO on the next line. Each contains pointers to ASCII strings for
the template, validation, and initialization. You can find these
strings in rs_strings, just as above.
There are also fields for the optional background and border
details, and for the length of the template and text. As we will see
when discussing editing, the most important TEDINFO fields are the
TE_PTEXT pointer to initialized text and the TE_TXTLEN field which
gives its length.
The G_IMAGE object type is the only one of its kind. A G_IMAGE is a
monochrome bit image. For examples, see the images within the various
GEM alert boxes. Note that monochrome does not necessarily mean black.
The image may be any color, but all parts of it are the SAME color.
G_IMAGEs are used as visual cues in dialogs. They are seldom used as
selectable items because their entire rectangle is inverted when they
are clicked. This effect is seldom visually pleasing, particularly if
the image is colored.
G_IMAGE objects have an OB_SPEC which is a pointer to a further
structure type: the BITBLK. By now, you should guess that you will
find it in the C file in the array rs_bitblk. The BITBLK contains
fields describing the height and width of the image in pixels, its
color,nd it also contains a long pointer to the actual bits which make
up the image. In the C file, the images are encoded as hexadecimal
words and stored in arrays named IMAG0, IMAG1, and so on.
The last type of object is the G_ICON. Like the G_IMAGE, the G_ICON
is a bit image, but it adds a mask array which selects what portions of
the image will be drawn, as well as an explanatory text field. A
G_ICON may also specify different colors for its "foreground" pixels
(the ones that are normally black), and its "background" pixels (which
are normally white).
The pictures which you see in Desktop windows are G_ICONs, and so
are the disks and trashcan on the desktop surface. With the latter you
will notice the effects of the mask. The desktop shows through right
up to the edge of the G_ICON, and only the icon itself (not a
rectangle) is inverted when a disk is selected.
The OB_SPEC of an icon points to another structure called an
ICONBLK. It is shown in the C file as rs_iconblk. The ICONBLK
contains long pointers to its foreground bit array, to the mask bit
array, and to the ASCII string of explanatory text. It also has the
foreground and background colors as well as the location of the text
area from the upper left of the icon. The most common use of G_ICONs
and ICONBLKs is not in dialogs, instead they are used frequently in
trees which are built at run-time, such as Desktop windows. In a
future article, we will return to a discussion of building such
"on-the-fly" trees with G_ICONs.
Now, let's recap the hierarchy of resource structures: The highest
level structures are the resource header, and then the tree index. The
tree index points to the beginning of each object tree. The objects
making up the tree are of several types, and depending on that type,
they may contain pointers to ASCII strings, or to TEDINFO, ICONBLK, or
BITBLK structures. TEDINFOs contain further pointers to strings;
BITBLKs have pointers to bit images; and ICONBLKs have both.
PUTTING IT TO WORK
The most common situations requiring you to understand resource
structures involve the use of text and editable text objects in
dialogs. We'll look at two such techniques.
Often an application requires two or more dialogs which are very
similar except for one or two title lines. In this circumstance, you
can save a good deal of resource space by building only one dialog, and
changing the title at run time.
It is easy to go wrong with this practice, however, because the
obvious tactic of using a G_STRING and writing over its text at run
time can go wrong. The first problem is that you must know in advance
the longest title to be used, and put a string that long into the
resource. If you don't you will damage other objects in the resource
as you copy in characters. The other problem is that a G_STRING is
always drawn at the same place in a dialog. If the length of the title
changes from time to time, the dialog will have an unbalanced and
sloppy appearance.
A better way to do this is to exploit the G_TEXT object type, and
the TEDINFO structure. The set_text() routine in the download shows
how. The parameters provided are the tree address, the object number,
and the 32-bit address of the string to be substituted. For this to
work, the object referenced should be defined as a G_TEXT type object.
Additionally, the Centered text type should be chosen, and the object
should have been "stretched" so that it fills the dialog box from side
to side.
In the code, the first action is to get the OB_SPEC from the object
which was referenced. Since we know that the object is a G_TEXT, the
OB_SPEC must point to a TEDINFO. We need to change two fields in the
TEDINFO. The TE_PTEXT field is the pointer to the actual string to be
displayed; we replace it with the address of our new string. The
TE_TXTLEN field is loaded with the new string's length. Since the
Centered attribute was specified for the object, changing the TE_TXTLEN
will cause the string to be correctly positioned in the middle of the
dialog!
Editing text also requires working with the TEDINFO structure. One
way of doing this is shown in the download. The object to be used
(EDITOBJ) is assumed to be a G_FTEXT or G_FBOXTEXT. Since we will
replace the initialized text at run time, that field may be left empty
when building the object in the RCS.
The basic trick of this code is to point the TEDINFO's TE_PTEXT at a
string which is defined in your code's local stack. The advantages of
this technique are that you save resource space, save static data by
putting the string in reusable stack memory, and automatically create a
scratch string which may be discarded if the dialog is cancelled.
The text string shown is arbitrarily 41 characters long. You should
give yours a length equal to the number of blanks in the object's
template field plus one. Note that the code is shown as a segment,
rather than a subroutine. This is required because the text string
must be allocated within the context of the dialog handling routine
itself, rather than a routine which it calls!
After the tree address is found, the code proceeds to find the
TEDINFO and modify its TE_PTEXT as described above. However, the
length which is inserted into TE_TXTLEN must be the maximum string
length, including the null!
The final line of code inserts a null into the first character of
the uninitialized string. This will produce an empty editing field
when the dialog is displayed. If there is an existing value for the
object, you should instead use strcpy() to move it into text[]. Once
the dialog is complete, you should check its final status as described
in the last article. If an "OK" button was clicked, you will then use
strcpy() to move the value in text[] back to its static location.
Although I prefer this method of handling editable text, another
method deserves mention also. This procedure allocates a full length
text string of blanks when creating the editable object in the RCS. At
run-time, the TE_PTEXT link is followed to find this string's location
in the resource, and any pre-existing value is copied in. After the
dialog is run, the resulting value is copied back out if the dialog
completed successfully.
Note that in both editing techniques a copy of the current string
value is kept within the application's data area. Threading the
resource whenever you need to check a string's value is extremely
wasteful.
One final note on editable text objects: GEM's editor uses the
commercial at sign '@' as a "meta-character". If it is the first byte
of the initialized text, then the field is displayed blank no matter
what follows. This can be useful, but is sometimes confusing when a
user in all innocence enters an @ and has his text disappear the next
time the dialog is drawn!
LETTERS, WE GET LETTERS
The Feedback section on ANTIC ST ONLINE is now functional and is
producing a gratifying volume of response. A number of requests were
made for topics such as ST hardware and ST BASIC which are beyond the
intended scope of this column. These have been referred to ANTIC's
editorial staff for action.
So many good GEM questions were received that I will devote part of
the next column to answering several of general interest. Also, your
requests have resulted in scheduling future columns on VDI text output
and on the principles (or mythology) of designing GEM application
interfaces. Finally, a tip of the hat to the anonymous reader who
suggested including the actual definitions of all macro symbols, so
that those without the appropriate H files can follow along. As a
result of this suggestion, the definitions for this column and the
previous three are included at the end of the download. Future
articles will continue this practice.
STRAW POLL!
I'd like to make a practice of using the Feedback to get your
opinions on the column's format. As a first trial, I'd like to know
your feelings about my use of "portability macros" in the sample code.
These macros, LLGET for example, are used for compatibility between 68K
GEM systems like the ST, and Intel based systems like the IBM PC. This
may be important to many developers. On the other hand, omitting them
results in more natural looking C code. For instance, in the download
you will find a second version of set_text() as described above, but
without the portability macros. So, I would like to know if you think
we should (A) Keep the macros - portability is important to serious
developers, (B) Get rid of them - who cares about Intel chips anyway,
or (C) Who cares? I'll tally the votes in two weeks and announce the
results here.
STAY TUNED!
As well as answers to feedback questions, the next column will
discuss how GEM objects are linked to form trees, and how to use AES
calls and your own code to manipulate them for fun and profit. In the
following installment, we'll look at the VDI raster operations (also
known as "blit" functions).
>>>>>>>>>>>>>>>>>>>>>>>>>> Sample C output file from RCS <<<<<<<<<<<<<<<<<<<<
/* (Comments added) */
BYTE *rs_strings[] = { /* ASCII data */
"Title String",
"Exit",
"Centered Text",
"",
"",
"Tokyo",
"",
"Time: __:__:__",
"999999",
"",
"Time: __:__:__ ",
"999999",
"New York"};
WORD IMAG0[] = { /* Bitmap for G_IMAGE */
0x7FF, 0xFFFF, 0xFF80, 0xC00,
0x0, 0xC0, 0x183F, 0xF03F,
0xF060, 0x187F, 0xF860, 0x1860,
0x187F, 0xF860, 0x1860, 0x187F,
0xF860, 0x1860, 0x187F, 0xF860,
0x1860, 0x187F, 0xF860, 0x1860,
0x187F, 0xF860, 0x1860, 0x187F,
0xF860, 0x1860, 0x187F, 0xF860,
0x1860, 0x187F, 0xF860, 0x1860,
0x187F, 0xF860, 0x1860, 0x187F,
0xF860, 0x1860, 0x183F, 0xF03F,
0xF060, 0xC00, 0x0, 0xC0,
0x7FF, 0xFFFF, 0xFF80, 0x0,
0x0, 0x0, 0x3F30, 0xC787,
0x8FE0, 0xC39, 0xCCCC, 0xCC00,
0xC36, 0xCFCC, 0xF80, 0xC30,
0xCCCD, 0xCC00, 0x3F30, 0xCCC7,
0xCFE0, 0x0, 0x0, 0x0};
WORD IMAG1[] = { /* Mask for first icon */
0x0, 0x0, 0x0, 0x0,
0x7FFE, 0x0, 0x1F, 0xFFFF,
0xFC00, 0xFF, 0xFFFF, 0xFF00,
0x3FF, 0xFFFF, 0xFFC0, 0xFFF,
0xFFFF, 0xFFF0, 0x3FFF, 0xFFFF,
0xFFFC, 0x7FFF, 0xFFFF, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0x7FFF,
0xFFFF, 0xFFFE, 0x3FFF, 0xFFFF,
0xFFFC, 0xFFF, 0xFFFF, 0xFFF0,
0x3FF, 0xFFFF, 0xFFC0, 0xFF,
0xFFFF, 0xFF00, 0x1F, 0xFFFF,
0xF800, 0x0, 0x7FFE, 0x0};
WORD IMAG2[] = { /* Data for first icon */
0x0, 0x0, 0x0, 0x0,
0x3FFC, 0x0, 0xF, 0xC003,
0xF000, 0x78, 0x180, 0x1E00,
0x180, 0x180, 0x180, 0x603,
0x180, 0xC060, 0x1C00, 0x6,
0x38, 0x3000, 0x18C, 0xC,
0x60C0, 0x198, 0x306, 0x6000,
0x1B0, 0x6, 0x4000, 0x1E0,
0x2, 0xC000, 0x1C0, 0x3,
0xCFC0, 0x180, 0x3F3, 0xC000,
0x0, 0x3, 0x4000, 0x0,
0x2, 0x6000, 0x0, 0x6,
0x60C0, 0x0, 0x306, 0x3000,
0x0, 0xC, 0x1C00, 0x0,
0x38, 0x603, 0x180, 0xC060,
0x180, 0x180, 0x180, 0x78,
0x180, 0x1E00, 0xF, 0xC003,
0xF000, 0x0, 0x3FFC, 0x0};
WORD IMAG3[] = { /* Mask for second icon */
0x0, 0x0, 0x0, 0x0,
0x7FFE, 0x0, 0x1F, 0xFFFF,
0xFC00, 0xFF, 0xFFFF, 0xFF00,
0x3FF, 0xFFFF, 0xFFC0, 0xFFF,
0xFFFF, 0xFFF0, 0x3FFF, 0xFFFF,
0xFFFC, 0x7FFF, 0xFFFF, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0x7FFF,
0xFFFF, 0xFFFE, 0x3FFF, 0xFFFF,
0xFFFC, 0xFFF, 0xFFFF, 0xFFF0,
0x3FF, 0xFFFF, 0xFFC0, 0xFF,
0xFFFF, 0xFF00, 0x1F, 0xFFFF,
0xF800, 0x0, 0x7FFE, 0x0};
WORD IMAG4[] = { /* Data for second icon */
0x0, 0x0, 0x0, 0x0,
0x3FFC, 0x0, 0xF, 0xC003,
0xF000, 0x78, 0x180, 0x1E00,
0x180, 0x180, 0x180, 0x603,
0x180, 0xC060, 0x1C00, 0x6,
0x38, 0x3000, 0x18C, 0xC,
0x60C0, 0x198, 0x306, 0x6000,
0x1B0, 0x6, 0x4000, 0x1E0,
0x2, 0xC000, 0x1C0, 0x3,
0xCFC0, 0x180, 0x3F3, 0xC000,
0x0, 0x3, 0x4000, 0x0,
0x2, 0x6000, 0x0, 0x6,
0x60C0, 0x0, 0x306, 0x3000,
0x0, 0xC, 0x1C00, 0x0,
0x38, 0x603, 0x180, 0xC060,
0x180, 0x180, 0x180, 0x78,
0x180, 0x1E00, 0xF, 0xC003,
0xF000, 0x0, 0x3FFC, 0x0};
LONG rs_frstr[] = { /* Free string index - unused */
0};
BITBLK rs_bitblk[] = { /* First entry is index to image data */
0L, 6, 24, 0, 0, 0};
LONG rs_frimg[] = { /* Free image index - unused */
0};
ICONBLK rs_iconblk[] = {
1L, 2L, 10L, 4096,0,0, 0,0,48,24, 9,24,30,8, /* First pointer is mask */
3L, 4L, 17L, 4864,0,0, 0,0,48,24, 0,24,48,8}; /* Second is data, third */
/* is to title string */
TEDINFO rs_tedinfo[] = {
2L, 3L, 4L, 3, 6, 2, 0x1180, 0x0, -1, 14,1, /* First pointer is text */
7L, 8L, 9L, 3, 6, 2, 0x2072, 0x0, -3, 11,1, /* Second is template */
11L, 12L, 13L, 3, 6, 0, 0x1180, 0x0, -1, 1,15, /* Third is validation */
14L, 15L, 16L, 3, 6, 1, 0x1173, 0x0, 0, 1,17};
OBJECT rs_object[] = {
-1, 1, 3, G_BOX, NONE, OUTLINED, 0x21100L, 0,0, 18,12, /* Pointers are to: */
2, -1, -1, G_STRING, NONE, NORMAL, 0x0L, 3,1, 12,1, /* rs_strings */
3, -1, -1, G_BUTTON, 0x7, NORMAL, 0x1L, 5,9, 8,1, /* rs_strings */
0, 4, 4, G_BOX, NONE, NORMAL, 0xFF1172L, 3,3, 12,5,
3, -1, -1, G_IMAGE, LASTOB, NORMAL, 0x0L, 3,1, 6,3, /* rs_bitblk */
-1, 1, 6, G_BOX, NONE, OUTLINED, 0x21100L, 0,0, 23,12,
2, -1, -1, G_TEXT, NONE, NORMAL, 0x0L, 0,1, 23,1, /* rs_tedinfo */
6, 3, 5, G_IBOX, NONE, NORMAL, 0x1100L, 6,3, 11,5,
4, -1, -1, G_BUTTON, 0x11, NORMAL, 0x5L, 0,0, 11,1, /* rs_strings */
5, -1, -1, G_BUTTON, 0x11, NORMAL, 0x6L, 0,2, 11,1, /* rs_strings */
2, -1, -1, G_BOXCHAR, 0x11, NORMAL, 0x43FF1400L, 0,4, 11,1,
0, -1, -1, G_BOXTEXT, 0x27, NORMAL, 0x1L, 5,9, 13,1, /* rs_tedinfo */
-1, 1, 3, G_BOX, NONE, OUTLINED, 0x21100L, 0,0, 32,11,
2, -1, -1, G_ICON, NONE, NORMAL, 0x0L, 4,1, 6,4, /* rs_iconblk */
3, -1, -1, G_FTEXT, EDITABLE, NORMAL, 0x2L, 12,2, 14,1, /* rs_tedinfo */
0, 4, 4, G_FBOXTEXT, 0xE, NORMAL, 0x3L, 3,5, 25,4, /* rs_tedinfo */
3, -1, -1, G_ICON, LASTOB, NORMAL, 0x1L, 1,0, 6,4}; /* rs_iconblk */
LONG rs_trindex[] = { /* Points to start of trees in */
0L, /* rs_object */
5L,
12L};
struct foobar { /* Temporary structure used by */
WORD dummy; /* RSCREATE when setting up image */
WORD *image; /* pointers. */
} rs_imdope[] = {
0, &IMAG0[0],
0, &IMAG1[0],
0, &IMAG2[0],
0, &IMAG3[0],
0, &IMAG4[0]};
/* Counts of structures defined */
#define NUM_STRINGS 18
#define NUM_FRSTR 0
#define NUM_IMAGES 5
#define NUM_BB 1
#define NUM_FRIMG 0
#define NUM_IB 2
#define NUM_TI 4
#define NUM_OBS 17
#define NUM_TREE 3
BYTE pname[] = "DEMO.RSC";
>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Title change utility <<<<<<<<<<<<<<<<<<<<<
VOID
set_text(tree, obj, str)
LONG tree, str;
WORD obj;
{
LONG obspec;
obspec = LLGET(OB_SPEC(obj)); /* Get TEDINFO address */
LLSET(TE_PTEXT(obspec), str); /* Set new text pointer */
LWSET(TE_TXTLEN(obspec), LSTRLEN(str)); /* Set new length */
}
>>>>>>>>>>>>>>>>>>>>>> Text edit code segment <<<<<<<<<<<<<<<<<<<<<<<<<<
LONG tree, obspec;
BYTE text[41];
rsrc_gaddr(R_TREE, DIALOG, &tree); /* Get tree address */
obspec = LLGET(OB_SPEC(EDITOBJ)); /* Get TEDINFO address */
LLSET(TE_PTEXT(obspec), ADDR(str)); /* Set new text pointer */
LWSET(TE_TXTLEN(obspec), 41); /* Set max length */
text[0] = '\0'; /* Make empty string */
>>>>>>>>>>>>>>>>>>>> Sample 68K only source code <<<<<<<<<<<<<<<<<<<<<<
VOID
set_text(tree, obj, str)
OBJECT *tree;
WORD obj;
BYTE *str;
{
TEDINFO *obspec;
obspec = (TEDINFO *) (tree + obj)->ob_spec;
/* Get TEDINFO address */
obspec->te_ptext = str; /* Set new text pointer */
obspec->te_txtlen = strlen(str); /* Set new length */
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>> Symbol definitions <<<<<<<<<<<<<<<<<<<<<<<<<
/* Window parts */
#define NAME 0x0001
#define CLOSER 0x0002
#define FULLER 0x0004
#define MOVER 0x0008
#define INFO 0x0010
#define SIZER 0x0020
#define UPARROW 0x0040
#define DNARROW 0x0080
#define VSLIDE 0x0100
#define LFARROW 0x0200
#define RTARROW 0x0400
#define HSLIDE 0x0800
#define WF_KIND 1 /* wind_get/set parameters */
#define WF_NAME 2
#define WF_INFO 3
#define WF_WXYWH 4
#define WF_CXYWH 5
#define WF_PXYWH 6
#define WF_FXYWH 7
#define WF_HSLIDE 8
#define WF_VSLIDE 9
#define WF_TOP 10
#define WF_FIRSTXYWH 11
#define WF_NEXTXYWH 12
#define WF_NEWDESK 14
#define WF_HSLSIZ 15
#define WF_VSLSIZ 16
/* window messages */
#define WM_REDRAW 20
#define WM_TOPPED 21
#define WM_CLOSED 22
#define WM_FULLED 23
#define WM_ARROWED 24
#define WM_HSLID 25
#define WM_VSLID 26
#define WM_SIZED 27
#define WM_MOVED 28
#define WM_NEWTOP 29
/* arrow messages */
#define WA_UPPAGE 0
#define WA_DNPAGE 1
#define WA_UPLINE 2
#define WA_DNLINE 3
#define WA_LFPAGE 4
#define WA_RTPAGE 5
#define WA_LFLINE 6
#define WA_RTLINE 7
#define R_TREE 0 /* Redraw definitions */
#define ROOT 0
#define MAX_DEPTH 8
/* update flags */
#define END_UPDATE 0
#define BEG_UPDATE 1
#define END_MCTRL 2
#define BEG_MCTRL 3
/* Mouse state changes */
#define M_OFF 256
#define M_ON 257
/* Object flags */
#define NONE 0x0
#define SELECTABLE 0x1
#define DEFAULT 0x2
#define EXIT 0x4
#define EDITABLE 0x8
#define RBUTTON 0x10
/* Object states */
#define SELECTED 0x1
#define CROSSED 0x2
#define CHECKED 0x4
#define DISABLED 0x8
#define OUTLINED 0x10
#define SHADOWED 0x20
#define G_BOX 20
#define G_TEXT 21
#define G_BOXTEXT 22
#define G_IMAGE 23
#define G_IBOX 25
#define G_BUTTON 26
#define G_BOXCHAR 27
#define G_STRING 28
#define G_FTEXT 29
#define G_FBOXTEXT 30
#define G_ICON 31
#define G_TITLE 32
/* Data structures */
typedef struct grect
{
int g_x;
int g_y;
int g_w;
int g_h;
} GRECT;
typedef struct object
{
int ob_next; /* -> object's next sibling */
int ob_head; /* -> head of object's children */
int ob_tail; /* -> tail of object's children */
unsigned int ob_type; /* type of object- BOX, CHAR,... */
unsigned int ob_flags; /* flags */
unsigned int ob_state; /* state- SELECTED, OPEN, ... */
long ob_spec; /* "out"- -> anything else */
int ob_x; /* upper left corner of object */
int ob_y; /* upper left corner of object */
int ob_width; /* width of obj */
int ob_height; /* height of obj */
} OBJECT;
typedef struct text_edinfo
{
long te_ptext; /* ptr to text (must be 1st) */
long te_ptmplt; /* ptr to template */
long te_pvalid; /* ptr to validation chrs. */
int te_font; /* font */
int te_junk1; /* junk word */
int te_just; /* justification- left, right... */
int te_color; /* color information word */
int te_junk2; /* junk word */
int te_thickness; /* border thickness */
int te_txtlen; /* length of text string */
int te_tmplen; /* length of template string */
} TEDINFO;
/* "Portable" data definitions */
#define OB_NEXT(x) (tree + (x) * sizeof(OBJECT) + 0)
#define OB_HEAD(x) (tree + (x) * sizeof(OBJECT) + 2)
#define OB_TAIL(x) (tree + (x) * sizeof(OBJECT) + 4)
#define OB_TYPE(x) (tree + (x) * sizeof(OBJECT) + 6)
#define OB_FLAGS(x) (tree + (x) * sizeof(OBJECT) + 8)
#define OB_STATE(x) (tree + (x) * sizeof(OBJECT) + 10)
#define OB_SPEC(x) (tree + (x) * sizeof(OBJECT) + 12)
#define OB_X(x) (tree + (x) * sizeof(OBJECT) + 16)
#define OB_Y(x) (tree + (x) * sizeof(OBJECT) + 18)
#define OB_WIDTH(x) (tree + (x) * sizeof(OBJECT) + 20)
#define OB_HEIGHT(x) (tree + (x) * sizeof(OBJECT) + 22)
#define TE_PTEXT(x) (x)
#define TE_TXTLEN(x) (x + 24)