[comp.sys.mac.programmer] Help!! ?Changed Menu Made Permanent?

cpyang@ccnysci.UUCP (Chao Ping Yang) (01/04/89)

I need to make changes in the Menus of my program and
I want to keep the changes the next time I run the
program, but I found I could not do it in a simple way.
I tried ChangedResource(MyMenuHandle) or even Rmv and
AddResource, but I still have problem, sometimes the
Menu Resource is not saved properly while most of the
times the program will not run the next time, while
doing ResEdit shows the MenuResource is properly saved.
On the other hand, I have no problem with other resource
being changed, like the STR#.

Can somebody help me out on this?

You help would be mostly appreciated.

==Chaoping Desperate Yang
cpyang@ccnysci.bitnet
cy03@andrew.cmu.edu

oster@dewey.soe.berkeley.edu (David Phillip Oster) (01/04/89)

In article <1115@ccnysci.UUCP> cpyang@ccnysci.UUCP (Chao Ping Yang) writes:
>doing ResEdit shows the MenuResource is properly saved.
>On the other hand, I have no problem with other resource
>being changed, like the STR#.
>
>Can somebody help me out on this?

The problem has to do with punning that occurs with menu resources and not
with other resources. There is a LongInt field of the resoure that holds,
on disk, the resource id of the MDEF that runs this menu, and, in memory,
a handle to the actual MDEF. What this means is, if you write the in
memory copy to disk, the disk version will have a garbage MDEF field. If
you set up the in memory version, then write it out, if you don't restore
the in memory value, the in memory version will crash.

1.) You can detach the in memory version, copy it, fix the copy and do an
AddResource.
2.) You can build your menus at run time from strings. Then just modify
the constructor string.
3.) You can change the in-memory copy, write it out, then change it back.

The MenuManager was first written a very long time ago, at that time it
wasn't quite clear how resources should be used. as a result, this
the-field-has-different-meanings-on-disk-versus-in-memory got in. A more
modern system would have added an extra Integer field for the MDEF id, and
had a 4-byte filler, that would be filled in when the structure got read
into memory.  Too late to change it now, it would break too many programs
that depend on the current structure of a menu.

--- David Phillip Oster            --"When we replace the mouse with a pen,
Arpa: oster@dewey.soe.berkeley.edu --3 button mouse fans will need saxophone
Uucp: {uwvax,decvax}!ucbvax!oster%dewey.soe.berkeley.edu --lessons." - Gasee

lsr@Apple.COM (Larry Rosenstein) (01/05/89)

In article <1115@ccnysci.UUCP> cpyang@ccnysci.UUCP (Chao Ping Yang) writes:
>I need to make changes in the Menus of my program and
>I want to keep the changes the next time I run the

The problem is that when you read in a menu, the data is changed.
Specifically, the field of the menu that contains the menu proc ID is
replaced with a handle to the menu defproc.

When you rewrite the menu resource (with your changes) you write out the
version that has the defproc installed, and not the defproc ID.

One solution would be to store the menu item strings in a different
resource, and reconstruct the menu each time.  Then you only have to change
the resource containing the items.  The problem with this is that it takes
more work, and people who want to use ResEdit can't easily customize the
menus.

A better solution would be to call DetachResource on each of your menus
after they have been read in.  This dissociates them from the resource file.
Then you can change the original version of the MENU resource without
affecting the in memory copy (and vice versa).

One way to make the change is to call GetResource to read the original MENU
resource, and save the defproc ID.  Then get the equivalent in memory
handle, and copy the data into the resource, and replace the defproc ID with
its original value.  Then you can call ChangedResource and write the MENU
resource back out.

A more efficient solution would be to change the defproc handle back to its
ID, before doing the ChangedResource.  This would eliminate the need to
re-read the resource from disk.  You have to be careful about restoring the
handle, before trying to use the menu again.  

		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 46-B  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr