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