[comp.sys.mac.programmer] Rewriting a Menu

barry@world.std.com (Barry L Wolman) (04/24/91)

I need to replace the contents of a menu with a new set of choices WITHOUT
changing either the ID or the handle of the menu.  The logical thing would
be to just use a new menu with a different ID and handle.  The problem is
that I'm using the menu with a CDEF that squirrels away the handle to the
menu and there doesn't seem to be a way to tell the CDEF to switch to a new
menu.

I wrote the following subroutine, but it doesn't work reliably.  For
example, when replacing a two-item menu by a one-item menu, sometimes
the altered menu has one item in it, and sometimes it has three items!

Is there a correct/better way to modify menus?

The flaky subroutine is ...
------------------------------------------------
typedef struct {			/* Structure description of STR# */
	int	numstrings;			/* resource. */
	unsigned char	thestrings[];
	} stringlist,**STRlist;

/* Load the strings contained in STR# with handle in sh into
   the menu whose handle is mh */
 
make_menu(MenuHandle mh,STRlist sh)
	{
	int i,n,oldsize,newsize;
	unsigned char *p;
 
	HLock(mh);
	HLock(sh);
 
	p = (*sh)->thestrings;
 
	oldsize = CountMItems(mh);
	newsize = (*sh)->numstrings;
	n = min(oldsize,newsize);
 
	for(i=1;i <= n;i++) {
		SetItem(mh,i,p);
		p += (*p)+1;
		}
 
	if (oldsize < newsize) {
 
		/* New menu is bigger, put remaining items at end */
 
		for(; i <= newsize; i++) {
			AppendMenu(mh,p);
			p += (*p)+1;
			}
		}
	else {
 
		/* New menu is same size or smaller */
		
		for (; i <= oldsize; i++) {
			DelMenuItem(mh,i);
			}
		}
 
	HUnlock(mh);
	HUnlock(sh);
	}
---------------------------------------------

Thanks,
Barry Wolman
-- 
Barry Wolman
159 Oxbow Road
Needham, MA 02192
617-449-3874