[comp.sys.mac.programmer] A replacement for MenuKey

tim@hoptoad.uucp (Tim Maroney) (01/17/90)

MenuKey has the irritating property of making assumptions about the
shift and option key which are hard to fathom.  Basically, it does some
sort of transformation on the menu shortcut or on the character you
pass it which converts lowercase keys to uppercase and sometimes
turns them into their "no option key" forms.

So I wrote a replacement which checks the menus itself in what should
be a compatible fashion.  Now you can put option-key shortcuts into
your menus, as well as differentiating between the shifted and
unshifted versions of punctuation keys.

MyMenuKey assumes the Script Manager is installed; if you want to run
it on pre-System-6.0 (you fool, why would you want do that?  Get some
new ROMs!) you will have to hack in some non-SM code.

The code also makes certain assumptions about your menus, which may
need modification for your own code.  My menus start at id 1 and go up
contiguously from there.  You may need to do some other form of
iteration for the main loop, but the inner loop and the preface should
still work fine.

Now, it someone would contribute an MDEF 0 replacement that will display
the shortcuts in a better form (they currently appear as the option-key
characters, not in the somewhat better MacroMaker format), we'd really
have something going.

(By the way, it looks as if I will have to be in Boston for a few days
almost immediately.  It is not a social occasion, but nevertheless, if
you have corresponded with me here and want to have a meal, and can put
up with what will probably not be one of my best moods, then leave me a
message and I hope I get it in time.  I only mention this because a
couple of you expressed regret that you missed me in Boston over Labor
Day weekend.)

long MyMenuKey(EventRecord *event)
{	MenuHandle menu; short i, j, code, limit, cmd, state, type;
	long trans, kstate = 0; Handle kchr; char c;
	if ((kchr = GetIndResource('KCHR', 1)) == 0)
		return MenuKey(event->message & 0xff);
	c = event->message & 0xff;
	type = CharType(&c, 0) & 7;
	code = (event->message & 0xff00) >> 8;
	if ((event->modifiers & optionKey) == 0 && type != smCharPunct)
		code |= shiftKey;
	else if ((event->modifiers & optionKey) == 0 && type == smCharPunct)
		code |= event->modifiers & shiftKey;
	else if (event->modifiers & optionKey)
		code |= optionKey;
	state = HGetState(kchr); HLock(kchr); HNoPurge(kchr);
	trans = KeyTrans(*kchr, code, &kstate);
	HSetState(kchr, state);
	c = trans & 0xff;
	for (i = 1, menu = GetMHandle(i); menu; i++, menu = GetMHandle(i)) {
		limit = CountMItems(menu);
		for (j = 1; j <= limit; j++) {
			GetItemCmd(menu, j, &cmd);
			if (cmd == c) {
				HiliteMenu(i);
				return ((long)i << 16) | j;
			}
		}
	}
	return MenuKey(event->message & 0xff);
}
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"I was bitter when I met you, I was eloquent with rage...." -- Annie Lennox

tim@hoptoad.uucp (Tim Maroney) (01/18/90)

In article <9715@hoptoad.uucp> tim@hoptoad.uucp (Tim Maroney) writes:
>you have corresponded with me here and want to have a meal, and can put

Never mind.  Stupid idea.  See you next week at the usual place (here).
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"God must be a Boogie Man." -- Joni Mitchell

ranson@cnetlu.UUCP (Ranson) (01/23/90)

In article <9715@hoptoad.uucp>, tim@hoptoad.uucp (Tim Maroney) writes:
> 	if ((kchr = GetIndResource('KCHR', 1)) == 0)

Tim, you missed an important point here: the System file may contain
several KCHR resources (Mine has 3, the US and French official versions,
and a custom version that makes the French keyboard much more compatible
with US apps). You can even change KCHR anytime using the Keyboard cdev.
The ID of the resource used at boot is stored in the itlb resource, but
you can easily get the current KCHR ID with a call to the Script Mgr.

     Daniel Ranson
     uucp: ...!mcvax!inria!cnetlu!ranson (or ranson@cnetlu.fr)
     X400: ranson@lannion.cnet.fr

d88-jwa@nada.kth.se (Jon Watte) (01/24/90)

In article <1364@cnetlu.UUCP> ranson@cnetlu.UUCP (Ranson) writes:

>several KCHR resources (Mine has 3, the US and French official versions,
>and a custom version that makes the French keyboard much more compatible
>with US apps). You can even change KCHR anytime using the Keyboard cdev.

And mine has five. And dragging the cdev to front is very annoying,
especially since HyperCard has modal edit (_WHY_ oh _WHY_ ? But it's
said to go away in 2.0...)

I posted a question about this a short while ago, but have as yet
not got an answer.

Q: I want to implement a FKEY / INIT pair to change KCHR
   My plan is to patch _KeyTrans at startup time to change the
   pointer on the stack at call time to a pointer to the KCHR
   I want to use. The FKEY toggles this.

A: This ?is? / ?is not? the right way to do it.

Happy hacking !
						h+@nada.kth.se
-- 
   ---  Stay alert !  -  Trust no one !  -  Keep your laser handy !  ---
             h+@nada.kth.se  ==  h+@proxxi.se  ==  Jon Watte
                    longer .sig available on request