Window & Popupmenu

Posted on 2000-02-12
Medium Priority
Last Modified: 2013-12-26
I have a program that creates multiple windows using the same DLOG resource. My problem is that this window has a popupmenu CNTL resource that I append  menu items to depending on a certain criteria. But when I go to open another window using the same DLOG resource I end up with the same menu items in the new window but I don't want the same menu items, I want diferent items depending on criteria. Also If I close one of the windows the popupmenu disappears in the other windows. Obviously this is because the menu is disposed of (I think). How can I create a NewMenu( baseID +1, "\pOptions); for each window and install this dynamically created menu to the popupcontrol of the window. I am using a  CNTL resource, the control type is System 7 Popup, fixed width, window font.
Question by:dwp090598
  • 4
  • 3
  • 2

Expert Comment

ID: 2522201
I think I answered something similar to this in <http://www.experts-exchange.com/jsp/qShow.jsp?ta=macprog&qid=10110269 >

You need to clone the popup for each window.

/* assume CNTL 128 is the popup control you want to clone */
/* 301, 3001, 302, 3002 are arbitrary, but they must be different for each window and unique from other CNTL and MENU
items in your resource file */

#define kControlID 128

/* create dialog 1*/
      dlg = CreateModelessDialog();

      GetDialogItem(dlg, kThePopupMenu, &tempType, (Handle *)&dummyHdl, &tempRect);
      controlHdl = DupPopUpControl(kControlID,301,3001,dlg);
      SetDialogItem(dlg, kThePopupMenu, tempType, (Handle)controlHdl, &tempRect);

      mHandle = (**((PopupPrivateData **)((**controlHdl).contrlData))).mHandle;
      AppendMenu(mHandle,"\pAdded Item 1");
/* create dialog 2*/
      dlg = CreateModelessDialog();
      GetDialogItem(dlg, kThePopupMenu, &tempType, (Handle *)&dummyHdl, &tempRect);
      controlHdl = DupPopUpControl(kControlID,302,3002,dlg);
      SetDialogItem(dlg, kThePopupMenu, tempType, (Handle)controlHdl, &tempRect);

      mHandle = (**((PopupPrivateData **)((**controlHdl).contrlData))).mHandle;
      AppendMenu(mHandle,"\pAdded Item 2");


static ControlHandle DupPopUpControl(short controlID,
    short newControlID, short newMenuID, DialogPtr dlg) {
  ControlHandle newControlHdl;
  Handle oldControlHdl;
  MenuHandle mHandle;
  short mID;

  /* get control resource */
  oldControlHdl = GetResource('CNTL',controlID);
  /* extract menu ID from control resource */
  mID = *(short *)(*oldControlHdl+14);

  /* copy MENU resource */
  mHandle = (MenuHandle)GetResource('MENU',mID);
  (**mHandle).menuID = newMenuID;
  /* copy CNTL resource with new MENU ID */
  *(short *)(*oldControlHdl+14) = newMenuID;
  /* finally, attached the cloned control to the window */
  newControlHdl = GetNewControl(newControlID,dlg);
  return newControlHdl;

Author Comment

ID: 2524896
I am not trying to duplicate a control but change a popup menu control's menuhandle to a diferent menuHandle that I created using NewMenu(); This way I can have a diferent menu for each window opened.

Expert Comment

ID: 2525052
If you want to create an entirely new menu from scratch, then it would be best to create a new control from scratch and add it to each dialog.

But your original question said that you wanted to _append_ menu items to an original control.  So this solution has the base items in a popupmenu control, and then clones the menu so you can add items to each copy separately.

The reason it clones the control (and the associated menu) is that the menu identity is embedded in the control.  As long as the controls are the same, they point to the same menu.  To point to different menus, the controls need to be different.

I'll email you separately a test program that shows how the whole thing works.  Try it, I think it does what you want.
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.


Expert Comment

ID: 2525054
Meant the above to be another attempt at an answer.

Expert Comment

ID: 2539656
boonstra changed the proposed answer to a comment

Expert Comment

by:Alex Curylo
ID: 2551577
Well, I see one bug right off in boonstra's code; after the AppendMenu(), he didn't call SetControlMaximum(). Not doing this will confuse the Control Manager, because *it* doesn't know what the hell you just did to the menu :)

I think NewMenu is the right tack to be taking, but not with setting the popup control to the new menu; subtleties like the SetControlMaximum() thing just mentioned are far too likely to trip you up. Far far better to just create the new control on the fly once you have your menu in its final form, methinks.

First off, you need to have a way to pick an unused menu id:

short GetNextFreeMenuID(void)
      short newID = 666;     // whatever's got lots of room following in your program

      while (::GetMenuHandle(newID))

      return newID;

and then every time you open the duplicated dialog, do something like this:

void CreateDynamicMenu(DialogPtr inDialog)
      // put a new empty menu in the menu list
      short menuID = GetNextMenuID();
      MenuHandle menu = ::NewMenu(menuID, "\p");
      ::InsertMenu(menu, -1);   ctrl;

      // Now, add all the items to the menu.
      // I would suggest putting all possible text items in an STR# resource
      // and copying applicable ones with GetIndString and AppendMenu.
      // Unless there's Menu Manager metachars in your text in which case
      // AppendMenu() dummy text and SetMenuItemText() the real text.

      Rect menuRect;
      // I would recommend using a userItem in the DLOG as a layout placeholder,
      // and then calling GetDialogItem on it here to fill in menuRect.

      // Now that we have a finished menu and know where it goes,
      // it's time to let the Control Manager in on the action :)
      ControlHandle ctrl = ::NewControl(inDialog, &menuRect, "\pPopup Menu", popupTitleJustLeft, menuID, 0, popupMenuProc, 0);

Author Comment

ID: 2576352
I tried this code and I ended up with a new popupmenu but there doesn't seem to be a menu attached to the control. Is NewControl(inDialog, &menuRect, "\pPopup Menu", popupTitleJustLeft, menuID, 0, popupMenuProc, 0);  looking for a resource in the menuID paramater. Have you tried this code, maybe I am doing something wrong. Thanks for your help.

Accepted Solution

Alex Curylo earned 400 total points
ID: 2578428
Well, I haven't run this exactly, but it's abstracted from code which does work :) The principles are explained in Technical Q&A TB42, at


If reading that over doesn't make whatever's wrong jump out as obvious, just stuff your project up and send it to alex@witty.com and I'll fix it then :)

Author Comment

ID: 2638377
Finally figured out how to create the menu.

Thanks - now I need more help.

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Ready to get certified? Check out some courses that help you prepare for third-party exams.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Stellar Phoenix SQL Database Repair software easily fixes the suspect mode issue of SQL Server database. It is a simple process to bring the database from suspect mode to normal mode. Check out the video and fix the SQL database suspect mode problem.
Suggested Courses
Course of the Month5 days, 10 hours left to enroll

588 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question