[comp.sys.mac.hypercard] windows for hypercard

duggie@jessica.Stanford.EDU (06/15/88)

I posted this on info-mac, where the original question appeared, but it
might be of interest to people here too.

Jeff Skastis <skaistis@SLEEPY.CC.UTEXAS.EDU> writes:

>I am trying to write an XCMD that will place a window (or dialog) on top
>of the regular Hypercard window.  I would like this XCMD to plop the
>window onto the screen and return some sort of ID to Hypercard.  The
>window needs to remain above the Hypercard window at all times, but still
>let action take place in Hypercard (just like the message box and tool
>palettes).  The window is removed by another XCMD that takes the ID passed
>from the first.

I've written a set of routines that does this.  It supports multiple,
resizable windows with color pictures, text, or dialogs in them.
However, it is rather large and complex, consisting of a large XCMD, a
special WDEF, and a system patch.  Depending on your needs you might
get by with less.

The problems I had were how to keep Hypercard active, how to draw
stuff in the window including scroll bars and the grow box), how to
detect events in the window and inform hypercard, how to move, show,
zoom windows etc, and how to handle hiding windows when multifinder
switched out hypercard.

I decided to use a patch to GetNextEvent.  In another version, I tried
using jGNEFilter, but multifinder ignores it (bug or feature?) and it
is considered bad form by Apple to use a low-memory global.  This took
care of most of my problems.  Most of the actual code, however,
resides in the WDEF, not the patch-- the patch just dispatches to it.

It turns out that Hypercard stops listening to the mouse when it gets
a deactivate event.  My hack for solving this problem was to not pass
deactivate events to windows that were not my windows or DA windows.
Hypercard then remains active all the time.  Occasionally there are
problems because highlighting in hypercard's message box remains even
though my window is getting keypress events, but basically this works.

To draw stuff in the window, I pass update events to the XCMD and let
the window determine what to draw.  The window draws structure-like
items (scroll bars and grow box) and then whatever other data it has.

To detect events, I take keypresses and mouse clicks and pass them to
the XCMD as well.  My XCMD has an 'event queue' for each window, plus
a mask to determine whether to queue the event.  The events are not
the same as toolbox events, but a bit more high-level-- window moved,
window resized, close or zoom box pressed, button pressed, etc.  If an
event is queued, I post the relevant data to the window's queue
(timestamp, mouse location, button id or whatever) then return a
function key event via the GNE patch.  Each window is assigned a
function key to use for reporting events, this makes it easier for a
script to determine which window has the event.  My scripts keep a
list of window addresses (returned by the XCMD when it creates the
window) and the function key is the index of the address in the list.
So to complete the reporting of the event, the script, on receipt of a
function key event, gets the window address from the list and makes
calls the XCMD asking for the next event for that window.  The XCMD
returns a string representing the 'event record.'  Since this is
mostly all compiled code, this process is quite fast.  Hypercard is by
far the slowest link.  I use this to put up confirmation dialogs
(using hypercard's answer command) when the user clicks in the close
box of a window.

The XCMD and WDEF work together to handle commanding the windows from
hypertalk scripts.  The XCMD parses a command string to determine the
data to pass to the WDEF, supplying defaults where appropriate (when
changing text parameters, for instance, any that are not provided
default to their existing values).  It builds a record and then calls
the WDEF proc passing a pointer to this record rather than an event,
and passing a special command code (not one of the existing WDEF
codes).  The WDEF then takes over, resizing or scrolling the window,
adding or removing gadgets like the zoom and close boxes, tracking the
grow box, or whatever.

Hiding windows is handled by the patch, since Hypercard 1.2 has no
script handlers for multifinder application switched events.  This is
currently a hack-- I get the head of the window list from a low memory
global, build an array of windows, then walk through it hiding all of
those that are of my type.  Since hidewindow changes the window list,
I can't just walk through the list.  Restoring windows is done in the
opposite way.  Unfortunately, I don't record the previous window
array, and hypercard shows and hides its own palette windows, so I
have no way to restore the exact order of windows that existed before
hypercard got switched out.

Anyway, this should be enough info.  Stanford owns my window XCMD or
I'd post it.  Perhaps they will release it eventually. By then,
probably Hypercard will support multiple windows.  That will obviate
most uses of my XCMD except for the color picture, scrolling, and
zooming support.  Creating windows for Hypercard was remarkably easy,
considering how much mucking around under Hypercard I had to do.

Doug Felt
AIR, Courseware Authoring Tools Project
Sweet Hall, 3rd floor
Stanford University, CA 94305
duggie@jessica.stanford.edu