[comp.sys.amiga.tech] Accessing NewMenu UserData

dlarson@blake.u.washington.edu (Dale Larson) (10/15/90)

I want to use the UserData field of the NewMenu struct to hold a pointer
to a function to be called when a particular item is selected.  I am a little
dense and/or the documentation on GTMENUITEM_GETUSERDATA() is a little scant.
Likely a little of both.  Could someone please provide an example of what the 
fuction call would look like?  

(*GTMENUITEM_GETUSERDATA(ItemAddress(Menu, (long)selection)))();
just doesn't seem to cut it with my compiler, and since cdecl doesn't
understand the cast in the GTMENUITEM_GETUSERDATA macro, I don't either.

Thanks for any help!
  
--
-Dale Larson  (dlarson@blake.u.washington.edu)

peter@cbmvax.commodore.com (Peter Cherna) (10/15/90)

In article <9194@milton.u.washington.edu> dlarson@blake.u.washington.edu (Dale Larson) writes:
>
>I want to use the UserData field of the NewMenu struct to hold a pointer
>to a function to be called when a particular item is selected.  I am a little
>dense and/or the documentation on GTMENUITEM_GETUSERDATA() is a little scant.
>Likely a little of both.  Could someone please provide an example of what the 
>fuction call would look like?  

Let's say your function returned a BOOL and took a UWORD as its parameter:

	BOOL (*fcn)(UWORD);

	fcn = GTMENUITEM_USERDATA( ItemAddress( menu, selection ) );

	return = (*fcn)(code);

(Note that its' GTMENUITEM_USERDATA, not GTMENUITEM_GETUSERDATA.)

>(*GTMENUITEM_GETUSERDATA(ItemAddress(Menu, (long)selection)))();
>just doesn't seem to cut it with my compiler, and since cdecl doesn't
>understand the cast in the GTMENUITEM_GETUSERDATA macro, I don't either.

Your problem is that GTMENUITEM_USERDATA() returns an APTR (which
is really a void* ).  You'd have to cast that into a pointer-to-function
before you can invoke it as a function. 
>
>Thanks for any help!
>  
>--
>-Dale Larson  (dlarson@blake.u.washington.edu)


     Peter
--
     Peter Cherna, Software Engineer, Commodore-Amiga, Inc.
     {uunet|rutgers}!cbmvax!peter    peter@cbmvax.cbm.commodore.com
My opinions do not necessarily represent the opinions of my employer.
"Television is a medium because it is neither rare nor well-done."

dlarson@blake.u.washington.edu (Dale Larson) (10/16/90)

In article <15157@cbmvax.commodore.com> peter@cbmvax.commodore.com 
(Peter Cherna) writes:
>Let's say your function returned a BOOL and took a UWORD as its parameter:
>
>	BOOL (*fcn)(UWORD);
>
>	fcn = GTMENUITEM_USERDATA( ItemAddress( menu, selection ) );
>
>	return = (*fcn)(code);
>
>Your problem is that GTMENUITEM_USERDATA() returns an APTR (which
>is really a void* ).  You'd have to cast that into a pointer-to-function
>before you can invoke it as a function. 

Thank you very much for your reply.  I guessed that GTMENUITEM_USERDATA()
was returning an APTR, but wasn't very sure, so I didn't try very hard to
get the cast into a pointer-to-function right.  With your little nudge
my menus are now screaming.  Instead of adding a new variable as you did
above, I call the function with a cast. 
 
I really really really really love gadtools!!!

(Sure, there's a lot more to be done, but gadtools is such an improvement
over 1.3 intuition!)  Setting up the menus took me all of 120 _seconds_!
Attaching the menus to windows has always been cake.  Since none of my 
menu-handling functions have any inputs or outputs, dealing with MENUPICKS 
is now as simple for me as:

USHORT selection;
struct MenuItem item;

selection = code;  /*  code = IntuiMessage->Code  */
while(selection!=MENUNULL)
	{
	item = ItemAddress(Menu, (LONG)selection);
	(* (void (*)void))GTMENUITEM_USERDATA(item))();
	selection = item->NextSelect;
	}

>     Peter Cherna, Software Engineer, Commodore-Amiga, Inc.
>     {uunet|rutgers}!cbmvax!peter    peter@cbmvax.cbm.commodore.com
>My opinions do not necessarily represent the opinions of my employer.
>"Television is a medium because it is neither rare nor well-done."


--
-Dale Larson  (dlarson@blake.u.washington.edu)