[comp.sys.mac.hypercard] External Windows and Activate event

Andrew_Gilmartin@Brown.EDU (06/11/91)

I have been developing an external window for HyperCard 2.x over the last
several weeks. One of its features is to send to the card  "resumeWindow" and
"suspendWindow" messages when HyperCard sends it, respectively, activate and
deactivate events. However, if you call SendCardMessage() during an activate or
deactivate event HyperCard crashes. I have worked-around this problem by
delaying sending the resume- and suspendWindow messages until the next null
event.

The problem with this  work-around is that the resume- and suspendWindow
messages should act like resume- and suspendStack in that they don't get sent
when the lockmessages has been set to true. My work-around fails to act
correctly here because to determine the status of the lockmessages during an
activation event requires that I can EvalExpr() which, like SendCardMessage(),
causes HyperCard to crash. Unfortunately, I have not yet found a work-around.
(Note: HyperCard sets lockmessages to false when it is idle and it is only
after this occures that my external window gets a null event.)

Has anyone solved this problem? Is HyperCard's crashing the result of a bug?

-- Andrew Gilmartin
   Computing & Information Services
   Brown University
   Andrew_Gilmartin@Brown.Edu

Roger.W.Brown@dartmouth.edu (Roger W. Brown) (06/15/91)

In article <78140@brunix.UUCP>
Andrew_Gilmartin@Brown.EDU writes:

>  However, if you call SendCardMessage() during an activate or
> deactivate event HyperCard crashes.

I can't be real explicit about this without seeing the code, but it
sounds like a reentrancy problem. Have you enabled reentrancy? If so,
you need to be prepared for it whenever you do a call back that could
cause your XCMD code to be rentered. SendCardMessage and EvalExpression
are two to be careful of. 

The easiest way to handle renetrancy is to save a copy of the paramPtr
on the stack (ie. in  avariable local to the currently executing
procedure) before doing the callback and restore it afterwards. If you
keep a global copy of the paramPtr around, it is likely to be wrong
after the callback, so you have to restore it to what it was. 

It works like this: the XCMD gets called with an activate event and it
stores a copy of the paramPtr globally. The XCMD calls back to
HyperCard. HyperCard sends a null event or something else back to the
XCMD during the callback. The XCMD stores the paramPtr for that call
globally, in the same location that it used on the preceding call that
has not yet completed. Then the first call continues with the wrong
paramPtr.

That might not be the problem and it might not be clear, but it may
give you an idea of where to look.


Roger W. Brown
Courseware Development
Dartmouth College
Hanover, NH
Roger.W.Brown@dartmouth.edu