lipsett@inmet.UUCP (10/09/87)
I am writing an application that requires/allows multiple windows with similar contents. While a window is active, I want to maintain the contents of the window in a data structure that is appropriate for various data manipulations. However, that form takes a lot of space, so when the window is inactive, I want to compress the data structure until the window is reactivated. So, I use the refcon field in each window to hold its compressed data. Activate events extract and uncompress the data; deactivate events compress the data and save it in the refcon field. This works fine in general. However, when I throw an alert box up on the screen, deactivate events either are not generated for the windows covered by the alert box or else the alert box toolbox routine eats them. As a result, when the alert box is dismissed, the resulting activate and update events lose badly, and either the windows are displayed wrong or I get a bomb of one kind or another. Either I am missing something obvious, or I have to call my deactivate routine explicitly before calling NoteAlert, or I am just trying to be too fancy with my refcon's, or...??? Thanks, Roger Lipsett {ihnp4,mirror}!inmet!lipsett
lippin@spam (tom lippincott) (10/12/87)
In article <127200007@inmet> lipsett@inmet.UUCP writes: >However, when I throw an alert box up on >the screen, deactivate events either are not generated for the windows >covered by the alert box or else the alert box toolbox routine eats >them. As a result, when the alert box is dismissed, the resulting >activate and update events lose badly, and either the windows are >displayed wrong or I get a bomb of one kind or another. I don't know what happens to those events, but it doesn't really matter -- they're not going to show up. Even if they did show up, they would be worthless because they couldn't be processed until the alert (actually any modal dialog) went away, and they'd be just before the activate event. The simple solution is to hang a flag off the refcon which tells whether the window is active. If it is, don't activate it again. May the Source be with you, --Tom Lippincott ..ucbvax!bosco!lippin "Mr. Spock does NOT say `eat hot plasma death, klingon scumbags!'" --Berke Breathed
lsr@apple.UUCP (Larry Rosenstein) (10/12/87)
In article <127200007@inmet> lipsett@inmet.UUCP writes: > >This works fine in general. However, when I throw an alert box up on >the screen, deactivate events either are not generated for the windows >covered by the alert box or else the alert box toolbox routine eats >them. As a result, when the alert box is dismissed, the resulting >activate and update events lose badly, and either the windows are >displayed wrong or I get a bomb of one kind or another. The problem will appear with any modal dialog. In a modal dialog, the Dialog Manager is in control and receives the events. If an event is intended for a dialog window it can do something with it. If the event is for a non-dialog window, then it throws it away. The deactivate event for your window is such an event. There's really not much else it can do with such an event. When the modal dialog goes away, your application starts receiving events again, and one of the first it will get is an activate event for its window In MacApp, we took the approach someone else suggested, which is to keep track of whether your application's window is already activated, and ignore the "extra" activate. If you want, you can catch the deactivate event by passing a filter proc to the Alert or Modal Dialog call. In the filter proc, you can call IsDialogEvent, and if it returns FALSE (not a dialog event) pass the event to your normal event handling code. The only problem is that some calls to Alert/Modal Dialog don't come from your application, which means you can't pass a filter proc. You can, however, create a global patch for the Modal Dialog trap which always passes your filter proc in as a parameter. (You will have to call the original filter proc, if it exists.) I did this once (a while ago), and it seemed to work. I will try to dig up the code, but I am not sure if it is around any longer. -- Larry Rosenstein Object Specialist Apple Computer AppleLink: Rosenstein1 UUCP: {sun, voder, nsc, mtxinu, dual}!apple!lsr CSNET: lsr@Apple.com
brian@ut-sally.UUCP (Brian H. Powell) (10/13/87)
In article <127200007@inmet>, lipsett@inmet.UUCP writes: > Either I am missing something obvious, or I have to call my deactivate > routine explicitly before calling NoteAlert, or I am just trying to be > too fancy with my refcon's, or...??? The various Alerts (and ModalDialog, by the way) swallow all the events that occur while the Alert window is brought up. That's why you're missing the deactivate events. They call HiliteWindow (indirectly) themselves, and your code for deactivation never gets called. For your code, just do a deactivate (really a fake deactivate, see below) before you call an Alert. Dialogs don't cause this problem because the activate/deactivate events are generated by [Get]NewDialog and not by ModalDialog. There are exceptions to this, such as SFGetFile and SFPutFile. Those guys handle their "own" events, so you need to do a fake deactivate before calling them. You also run into this problem with desk accessories. Some DAs may choose to put up an Alert or a standard file dialog. DAs cause other problems as well; you can't do a real deactivate because a DA might not bring up a window. (It might just install a menu item, for instance.) This is why I said you should do a "fake" deactivate. I had this problem with a TextEdit-based application where I had globals that pertained to the frontmost (i.e., active) window. When I got a deactivate, I stored them in a record pointed to by the refCon field in the window record. I couldn't call TEDeactivate for these fake deactivates since a DA without a window would leave one of my windows in front that was Hilited, but without an active TE record, so I didn't have an insertion point or selection range. Depending on what you're doing, you might not have to do a so-called "fake" deactivate. I had to fake it because I didn't want to call TEDeactivate unnecessarily. You might be able to call your real deactivate routine. This leads to your next problem... One of the features of my TE application was that it didn't hurt to copy those globals to the refCon record twice (once for a fake deactivate and once for a real deactivate, in case I got a real one in the case of a DA.) In your case, you can only compress once, so you have to be careful about not recompressing compressed data. With your code, you know exactly when you won't be getting the deactivates. With DAs, you won't know and you can't find out. Either don't allow DAs (a travesty in some peoples' minds) or leave a flag around telling you whether the data has been compressed or not. I think you should do the latter. Perhaps there are other solutions besides the two that I have mentioned. Good luck. Brian H. Powell UUCP: ...!uunet!ut-sally!brian ARPA: brian@sally.UTEXAS.EDU _Work_ _Not Work_ Department of Computer Sciences P.O. Box 5899 Taylor Hall 2.124 Austin, TX 78763-5899 The University of Texas at Austin (512) 346-0835 Austin, TX 78712-1188 (512) 471-9536
denbeste@bgsuvax.UUCP (William C. DenBesten) (10/13/87)
How about setting the refcon to NILL (NUL) when ever you don't have compressed data hooked to it. Then when you go to decompress, check to make sure that it is non-NILL and then do the decompression. If it was NILL, the stuff is allready compressed. -bill
lsr@apple.UUCP (Larry Rosenstein) (10/15/87)
In article <9262@ut-sally.UUCP> brian@ut-sally.UUCP (Brian H. Powell) writes: > > For your code, just do a deactivate (really a fake deactivate, see below) >before you call an Alert. Dialogs don't cause this problem because the >activate/deactivate events are generated by [Get]NewDialog and not by >ModalDialog. There are exceptions to this, such as SFGetFile and SFPutFile. >Those guys handle their "own" events, so you need to do a fake deactivate >before calling them. Dialogs are not completely immune from this problem. The action of making a new window (dialog or not) frontmost will schedule a pair of deactivate and activate events. The next call to GetNextEvent will return a deactivate event, and the following one an activate event. If ModalDialog makes the first call to GetNextEvent, it will throw away the deactive, since it won't be directed to a dialog window. If your code makes the call, you can process the event normally. In the case of alerts or Std File, it is not possible to run any of your code between bringing up the dialog and calling ModalDialog. In these cases, you can use an event filter proc to catch the event. -- Larry Rosenstein Object Specialist Apple Computer AppleLink: Rosenstein1 UUCP: {sun, voder, nsc, mtxinu, dual}!apple!lsr CSNET: lsr@Apple.com