Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!tut.cis.ohio-state.edu!ucbvax!hoptoad!tim From: tim@hoptoad.uucp (Tim Maroney) Newsgroups: comp.sys.mac.programmer Subject: Re: Dialog from a Trap Message-ID: <11282@hoptoad.uucp> Date: 2 May 90 07:43:31 GMT References: <21747@dartvax.Dartmouth.EDU> Reply-To: tim@hoptoad.UUCP (Tim Maroney) Organization: Eclectic Software, San Francisco Lines: 71 In article <21747@dartvax.Dartmouth.EDU> sean@eleazar.dartmouth.edu (Sean P. Nolan) writes: >Objective: to have a dialog pop up everytime an application is launched so > that the user can choose whether or not to install a small utility. >approach: patch _LoadSeg so that it watches for somebody loading code #1. > If they are, we know an application is being launched. We want to > wait until the app. has done it's initialization before popping > the dialog. So, we patch _GetNextEvent to (A) show the dialog > and (B) unpatch itself so that our dialog is only shown once per > application startup. Problem 1 -- application may never call GetNextEvent. Modern applications use WaitNextEvent if it's available. Problem 2 -- you are assuming the application will not itself patch GNE. If it does, your "unpatch" can't work. Problem 3 -- because of the strange way it works, LoadSeg is about the last trap you ever want to patch. Use an alternative, like InitDialogs. >To show the dialog, I do the following: at system startup, I GetResource the >itemlist, and detach and nopurge the handle. I then use NewDialog to bring >up the box. > >Problems: 1. The dialog never gets ahold of the itemlist. It puts up a box > with nothing in it at all. > 2. After dropping out of _ModalDialog, I call the normal _GNE > proc, which works for a second and then bombs. Which, to me, seems to imply you're not handling the item list correctly. Possible problems: You need not only to GetResource, detach, and unpurge the item list -- you also need to make sure it's in the system heap, or it will go away as soon as your INIT finishes running. Another: You can't just attach the item list to the DialogRecord; you also have to iterate over the items and initialize them, particularly controls. There's a tech note which has a detailed append routine you can use. (TN #95) Yet another: Don't attach the actual item list, or it will get freed when you close the dialog -- instead, build a copy in memory. Yet another: Don't *call* the old GetNextEvent -- that's a tail patch. Your routine should do something like returning to an outer shell of assembly language, popping the stack frame back to its state when you were called, and jumping to the old routine address. A popular way of doing this last part is to push the old address and then RTS, but I always put the old address into a scratch register and jump to it instead (if I can -- beware of register-based traps). Personally, if I were doing this, I'd go ahead and do a tail patch, but do it on InitDialog and forget the whole GNE/WNE charade: it's too complicated. How can I actually recommend a tail patch? Simple -- InitDialogs is called in one very well-defined place, from an application startup. The chance of it being called by any system software, and so the chance of acquiring a come-from check which would screw up a tail patch, is so slim as to be worth forgetting. So call the old InitDialogs first, forget about unpatching, and then go on and call your mysterious one-per-launch dialog before returning from your InitDialogs patch. >Any help? I'm about to kill myself. Thanks in advance... Don't jump off a bridge; it's not a reliable method. (That's a joke, son. I'll feel like a real cad if you really do it.) -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com FROM THE FOOL FILE: "In any religion or form of worship, followers should be allowed to think for themselves. In every religion that has a god other than Jesus Christ, adherents are not allowed to think for themselves." -- Lauren Stratford, "Satan's Underground"