hughes@ux.acs.umn.edu (Steve Hughes) (11/28/90)
There must be a way.... Man, all I want out of life is to check the function keys while I'm executing a repeat...until handler. I want it to work like this: put the ticks + 180 into endTick repeat until the ticks >= endTick if functionKey then if functionKey = 1 then doThis if functionKey = 2 then doThat if functionKey = 3 then doThatOtherThing else beep end if end repeat Now, I know that this is not how to use functionKey, and that what I probably really want to do is use some kind of XFCN, but given that this must run with HyperCard 2.0, I'm wondering if there are XFCNs out there to do this (or does HC 2.0 have this ability and I'm not reading the right documentation?) It doesn't seem like simply reading the @#%&! function keys from within a handler should be so difficult, yet I'm bashing my brains trying to make it work! Can onyone help? Thanks, ---Steve Hughes hughes@ux.acs.umn.edu
jk3t+@andrew.cmu.edu (Jonathan King) (11/28/90)
hughes@ux.acs.umn.edu (Steve Hughes) writes: > There must be a way.... > > Man, all I want out of life is to check the function keys while > I'm executing a repeat...until handler. It's good to see somebody with a clear and worthwhile goal... > I want it to work like this: > > put the ticks + 180 into endTick > repeat until the ticks >= endTick > if functionKey then > if functionKey = 1 then doThis > if functionKey = 2 then doThat > if functionKey = 3 then doThatOtherThing > else > beep > end if > end repeat > > Now, I know that this is not how to use functionKey, and that what > I probably really want to do is use some kind of XFCN, but given that > this must run with HyperCard 2.0, I'm wondering if there are XFCNs out there > to do this (or does HC 2.0 have this ability and I'm not reading the right > documentation?) Leaving XFCNs out of this for now, the short answer to what you are asking for seems to be "No, you can't test for a functionKey that way in a repeat loop". FunctionKey can be used either as a command or a message, but not as a function. Yes, it would have probably been nice if there were a function that would return whichKey if a function key was pressed, but there isn't. So, now let me persuade you that you really want to do something else which you *can* do :-). What your script fragment suggests you *really* want to do is allow a user to make some choice or other that can be signalled by pressing a function key, as long as that choice is made in some reasonable amount of time. So, I'm guessing that the handler surrounding your repeat loop looks (schematically) like this: on makeChoice preparestuff setTimeOut loopAroundUntilTimeIsOutOrFunctionKeyIsPressed end makeChoice (I'm ignoring the beeping for now since I don't understand why you would want to constantly beep at the user if the functionKey isn't down yet; that could be really, really annoying.) The simplest way to do this (without the beeping) is to set a global variable TimeOut (your EndTick) to the proper value, and set another global variable contextCommand to the name of the command you want executed when the event occurs. Then you can let other independent handlers do the dispatching for you. Note that this allows you to handle functionKeys (or other kinds of events) in multiple contexts. The finished functionKey handler might look something like this: on functionKey whichkey global timeOut, contextCommand if contextCommand is not empty then if the ticks < timeOut then put empty into timeOut --clean up your globals put contextCommand into doit --prepare to clean up your global put empty into contextCommand --otherwise your global survives do doit whichkey --check my syntax, but this is doable end if -- do your complaining in an idle handler (like below) end if else pass functionKey -- someone else might want this message end functionKey The "do" command here will dispatch an appropriate message (maybe "recordChoice") with the functionKey argument which you can handle in a separate handler. Now, you might also want to do something in case you time out, which you can handle in an idle handler like this: on idle global timeOut, contextComand if contextCommand is not empty then -- can't time out otherwise if the ticks > timeOut then put empty into timeOut -- more global scrubbing put contextCommand into doit -- same dance as before so that put empty into contextCommand -- we don't need to return do doit "timedout" --check my syntax, but this is doable end if else pass idle -- someone else might want this message end idle Now if you time out, the handler can do something appropriate like give feed back to the user, or do some default thing or whatever. It might seem like all this mucking around with functionKey and idle handlers is just an enormous hack, but I've been finding that it is sometimes really convenient to spread control around like this and worry more about trapping events flexibly than about maintaining rigid control at all times (unless you're writing stack that do things like take reaction times or something equally bizarre). A variation of this same technique can be used to do things like check for doubleclicks and put together escape sequences using the escape key. (The latter has been really useful to me recently, since I'm developing a stack that pretends it's EMACS--you just put it on the stacks-in-use list and voila! you can do emacs-style editing in any field you're in, including (really usefully) the message box. Right now I'm debugging keyboard macro creation...pretty tricky stuff. If anybody else out there is weird enough to be interested in this, you can drop me a line and I'll let you know when it's stable.) > It doesn't seem like simply reading the @#%&! function keys from within > a handler should be so difficult, yet I'm bashing my brains trying to make > it work! Can onyone help? Hope this helps some... > ---Steve Hughes > hughes@ux.acs.umn.edu jking