static void DeleteSubMenus(SubSysMenuHandle subSysMenus) // Remove any sub-menus that we added to the menu bar. // Basically this just walks subSysMenus (backwards, which // isn't strictly necessary, but reassures me that the menu // bar is somewhat consistent at each step), deleting each // menu from the menu bar and reseting its parent to reference // menu ID 0. { ItemCount entryCount; ItemCount entryIndex; SubSysMenuEntry thisEntry; // Have to handle both NULL and non-NULL case. // This expression always evaluates to true, // but it captures the semantics of what this // routine must do. assert(subSysMenus != NULL || subSysMenus == NULL); entryCount = CountSubSysMenus(subSysMenus); for (entryIndex = 0; entryIndex < entryCount; entryIndex++) { thisEntry = (*subSysMenus)[entryCount - entryIndex - 1]; DeleteMenu( (**(thisEntry.childMenu)).menuID ); SetItemMark( thisEntry.parentMenu, thisEntry.itemInParent, 0); // Recalculate the parent menu size, for consistency with // the similar code in InsertSystemSubMenu. CalcMenuSize(thisEntry.parentMenu); } }
EXPORT(sqInt) primitiveSetItemMark(void) { CharParameter aCharacter; MenuHandle menuHandle; sqInt menuHandleOop; sqInt anInteger; sqInt aMarkChar; sqInt _return_value; menuHandleOop = interpreterProxy->stackValue(2); anInteger = interpreterProxy->stackIntegerValue(1); aMarkChar = interpreterProxy->stackIntegerValue(0); if (interpreterProxy->failed()) { return null; } menuHandle = ((MenuHandle) (interpreterProxy->positive64BitValueOf(menuHandleOop))); if (!(ioCheckMenuHandle(menuHandle))) { _return_value = interpreterProxy->success(0); if (interpreterProxy->failed()) { return null; } interpreterProxy->popthenPush(4, _return_value); return null; } aCharacter = aMarkChar; SetItemMark(menuHandle,anInteger,aCharacter); return null; }
// add some interesting sample items static void AddSampleItems( MenuRef menu ) { MenuItemIndex item; AppendMenuItemTextWithCFString( menu, CFSTR("Checkmark"), 0, 0, &item ); CheckMenuItem( menu, item, true ); AppendMenuItemTextWithCFString( menu, CFSTR("Dash"), 0, 0, &item ); SetItemMark( menu, item, '-' ); AppendMenuItemTextWithCFString( menu, CFSTR("Diamond"), 0, 0, &item ); SetItemMark( menu, item, kDiamondCharCode ); AppendMenuItemTextWithCFString( menu, CFSTR("Bullet"), 0, 0, &item ); SetItemMark( menu, item, kBulletCharCode ); AppendMenuItemTextWithCFString( menu, NULL, kMenuItemAttrSeparator, 0, NULL ); AppendMenuItemTextWithCFString( menu, CFSTR("Section Header"), kMenuItemAttrSectionHeader, 0, NULL ); AppendMenuItemTextWithCFString( menu, CFSTR("Indented item 1"), 0, 0, &item ); SetMenuItemIndent( menu, item, 1 ); AppendMenuItemTextWithCFString( menu, CFSTR("Indented item 2"), 0, 0, &item ); SetMenuItemIndent( menu, item, 1 ); }
/**************************************************************** SetPopSelection() sets the lastItemSelected for the given popup. ****************************************************************/ void SetPopSelection(DialogPtr theDialog, short item, short selection) { short i; #ifndef IBM short j, c; #endif for ( i = 0 ; i < sa_numPopUps ; i++ ) if ( (sa_popTable[i].dialogPtr == theDialog) && (sa_popTable[i].popupItemNum == item) ) break; if (i < sa_numPopUps) { #ifndef IBM MenuHandle theMenu; theMenu = GetMenuHandle(sa_popTable[i].menuID); for (j = 1, c = CountMenuItems(theMenu); j <= c ; j++) SetItemMark(theMenu, j, noMark); SetItemMark(theMenu, selection, kCheckMark); #endif //IBM sa_popTable[i].lastItemSelected = selection; #ifdef IBM //{///////// // This forces an update of the 'combo box' so that it displays the // currently selected menu item. PopDraw( theDialog, item ); #endif // IBM //}///////// } }
/**************************************************************** PopClick() gets called when there is a click in a dialog item that might be a popup item. It determines if the click is in a popup and if so handles the click. It brings up the popup on the item that was last selected for this menu. It returns true if the item was a popup item and the mouse was released on a valid item. In that case, it also stores the value returned by PopUpMenuSelect in *result (a long containing the menu and item ID selected). If the item selected was in this menu (as opposed to one of its submenus), that item is stored in the lastItemSelected field for this popup in the popTable. In that case, the item is also checked, and the previously selected item is unchecked. For a click on a static popup item, PopClick returns false, returns 0 in *result and doesn't call PopUpMenuSelect. -- On the IBM, this simply gets the index value of the selected item. ****************************************************************/ Boolean PopClick(DialogPtr theDialog, short itemHit, LONGPTR result) { #ifndef IBM GrafPtr savePort; short theType; Rect popBox; Rect titleBox; MenuHandle theMenu; long res; short count; char name[256]; Handle itemHandle; #else HANDLE itemHandle; #endif short i; #ifndef IBM if (OverridePopClick(theDialog, itemHit, result)) return true; #endif for ( i = 0 ; i < sa_numPopUps ; i++ ) if ( (sa_popTable[i].dialogPtr == theDialog) && (sa_popTable[i].popupItemNum == itemHit) ) break; if (i == sa_numPopUps || sa_popTable[i].bStatic) { *result = 0; return false; } #ifdef IBM itemHandle = GetDlgItem (theDialog, itemHit); sa_popTable[i].lastItemSelected = // (SendMessage (itemHandle, CB_GETCURSEL, 0, 0L)+1); //Combo box item ID's begin at 0 (SendMessage ((HWND)itemHandle, CB_GETCURSEL, 0, 0L)+1); //Combo box item ID's begin at 0 return FALSE; #else GetPortGrafPtr(&savePort); SetPortDialogPort(theDialog); theMenu = GetMenuHandle(sa_popTable[i].menuID); if (sa_popTable[i].drawProc == nil) // grow items to match size of pop-box for ( count = CountMenuItems(theMenu) ; count >= 1 ; count-- ) { GetMenuItemText(theMenu, count, (StringPtr)name); my_p2cstr((StringPtr)name); strcat(name, " "); my_c2pstr(name); SetMenuItemText(theMenu, count, (StringPtr)name); my_p2cstr((StringPtr)name); } if (sa_popTable[i].titleItemNum) { GetDialogItem(theDialog,sa_popTable[i].titleItemNum,&theType,&itemHandle,&titleBox); InvertRect(&titleBox); } GetDialogItem(theDialog,sa_popTable[i].popupItemNum,&theType,&itemHandle,&popBox); LocalToGlobal((Point *)(&popBox.top)); LocalToGlobal((Point *)(&popBox.bottom)); res = PopUpMenuSelect( theMenu, popBox.top + 1, popBox.left + 1, sa_popTable[i].lastItemSelected ); if (sa_popTable[i].titleItemNum) InvertRect(&titleBox); if (LoWord(res) && (HiWord(res) == sa_popTable[i].menuID)) { SetItemMark(theMenu, sa_popTable[i].lastItemSelected, noMark); sa_popTable[i].lastItemSelected = LoWord(res); SetItemMark(theMenu, sa_popTable[i].lastItemSelected, kCheckMark); } if (sa_popTable[i].drawProc == nil) // shrink items back to normal for ( count = CountMenuItems(theMenu) ; count >= 1 ; count-- ) { GetMenuItemText(theMenu, count, (StringPtr)name); my_p2cstr((StringPtr)name); name[strlen(name) - 5] = 0; my_c2pstr(name); SetMenuItemText(theMenu, count, (StringPtr)name); my_p2cstr((StringPtr)name); } *result = res; SetPortGrafPort(savePort); if (LoWord(res)) { PopDraw(sa_popTable[i].dialogPtr, sa_popTable[i].popupItemNum); return true; } return false; #endif //IBM }
Boolean OverridePopClick(DialogPtr theDialog, short itemHit, long *result) { GrafPtr savePort; MenuHandle theMenu; short count; char name[256],str[256]; short i; if(gVUTrick == gVUTrick2) return false; // we will not override PopClick for ( i = 0 ; i < sa_numPopUps ; i++ ) if ( sa_popTable[i].dialogPtr == theDialog && sa_popTable[i].popupItemNum == itemHit ) break; if (i == sa_numPopUps || sa_popTable[i].bStatic) { *result = 0; return false; // we will not override PopClick } // else we have found the i value theMenu = GetMenuHandle(sa_popTable[i].menuID); GetMenuItemText(theMenu, sa_popTable[i].lastItemSelected, (StringPtr)str); my_p2cstr((StringPtr)str); GetPortGrafPtr(&savePort); if(REQUEST("enter value to select",str,str) == ok) { short numItems = CountMenuItems(theMenu); UpperText(str,strlen(str)); //UppercaseText(str,strlen(str),smSystemScript); //smCurrentScript // find the string for ( count = numItems ; count >= 1 ; count-- ) { GetMenuItemText(theMenu, count, (StringPtr)name); my_p2cstr((StringPtr)name); UpperText(name,strlen(name)); //UppercaseText(name,strlen(name),smSystemScript); //smCurrentScript if (strcmp(str,name) == 0) { if (!MenuItemEnabled(theMenu, count)) { REQUEST("Item found but disabled",str,str); *result = 0; SetPortGrafPort(savePort); return false; } else break; // we found it } } if(count == 0) { // we did not find the string REQUEST("Could not find string in Menu",str,str); *result = 0; SetPortGrafPort(savePort); return false; } else { // count holds the menuItem Num we want SetItemMark(theMenu, sa_popTable[i].lastItemSelected, noMark); sa_popTable[i].lastItemSelected = count; SetItemMark(theMenu, sa_popTable[i].lastItemSelected, kCheckMark); *result = sa_popTable[i].menuID*0x10000 + sa_popTable[i].lastItemSelected; } } SetPortGrafPort(savePort); PopDraw(sa_popTable[i].dialogPtr, sa_popTable[i].popupItemNum); return(true); //we have overriden PopClick }
extern pascal OSStatus InsertSystemSubMenu(MenuRef rootMenu, MenuRef parentMenu, UInt16 itemInParent, MenuRef childMenu) // See comment in interface part. { long oldA4; OSStatus err; SubSysMenuEntry newEntry; SInt16 newIDForChildMenu; oldA4 = SetUpA4(); assert(ValidateSystemMenuRef(rootMenu )); assert(ValidateSystemMenuRef(parentMenu)); assert(ValidateSystemMenuRef(childMenu )); assert(gMenuSelectState = kMenuSelectStatePre); // Validate parameters err = noErr; if ((rootMenu == NULL) || (parentMenu == NULL) || (childMenu == NULL)) { err = paramErr; } if (err == noErr && ((itemInParent == 0) || (itemInParent > CountMenuItems(parentMenu)))) { err = paramErr; } // Make sure rootMenu references a current system menu. // If it does, record the index of the root menu for // later use by HandleMenuSelect. Also fill out the rest // of the fields of the sub-menu entry. if (err == noErr) { newEntry.rootMenuIndex = FindRootMenuByRef(rootMenu); newEntry.parentMenu = parentMenu; newEntry.itemInParent = itemInParent; newEntry.childMenu = childMenu; if (newEntry.rootMenuIndex == kRootMenuNotFound) { err = paramErr; } } // Add newEntry to the sub-menu list, creating the sub-menu list if necessary. if (err == noErr) { if (gSubSysMenus == NULL) { gSubSysMenus = (SubSysMenuHandle) NewHandleSys(0); err = MemError(); } } if (err == noErr) { err = PtrAndHand(&newEntry, (Handle) gSubSysMenus, sizeof(newEntry)); } // Finally, insert the menu with a unique ID into the menu bar, // and set the parent item to reference its ID. if (err == noErr) { newIDForChildMenu = FindUniqueSubMenuID(); (**childMenu).menuID = newIDForChildMenu; InsertMenu(childMenu, hierMenu); SetItemCmd(parentMenu, itemInParent, hMenuCmd); SetItemMark(parentMenu, itemInParent, newIDForChildMenu); // I added this after testing revealed that adding a sub-menu didn't // force the menu size to be recalculated, so the item text of the // hierarchical item in the sub-menu was being truncated. This // only appears to happen on Mac OS 8.5, but the fix is sufficiently // benign to be employed on all systems. CalcMenuSize(parentMenu); } (void) SetA4(oldA4); return err; }