{17}
PROCEDURE wInsertMenu (theMenuBar: wMenuBarHandle; theMenu:
MenuHandle; beforeID: INTEGER);
{ Insert a Menu into a defined wMenuBar: }
VAR
hierID, index, i, j: INTEGER;
found, enabled: BOOLEAN;
parentMenuHdl: MenuHandle;
oldPort: GrafPtr;
cmdChar, parentMark: char;
parentItemRect, parentFrameRect: Rect;
currentHeight, prevHeight, sizeIcon: INTEGER;
BEGIN
IF beforeID = atEnd THEN
BEGIN
i := 0;
WHILE (i < theMenuBar^^.numMenus) &
(theMenuBar^^.wMenus[i].menuType = regMenu) DO
i := i + 1;
IF i < theMenuBar^^.numMenus THEN
{ Insert after end of regular portion of Window Menu Bar, }
{ which occurs just prior to the Hierarchical portion. }
BEGIN
wInsertMenu(theMenuBar, theMenu,
theMenuBar^^.wMenus[i].mh^^.menuID);
EXIT(wInsertMenu);
END
ELSE
BEGIN
IF IncreaseSize(theMenuBar) <> noErr THEN
EXIT(wInsertMenu);
titleWidth := GetTitleWidth(theMenu);
END; { ELSE: i = numMenus }
END { beforeID = atEnd }
ELSE IF beforeID = hierMenu THEN
BEGIN
hierID := theMenu^^.menuID;
i := 0;
found := false;
;
{ Scan entire wMenuBar. }
WHILE (i < theMenuBar^^.numMenus) & NOT found DO
BEGIN
parentMenuHdl := theMenuBar^^.wMenus[i].mh;
{ Scan each menu. }
FOR j := 1 TO CountMItems(parentMenuHdl) DO
BEGIN
GetItemCmd(parentMenuHdl, j, cmdChar);
IF cmdChar = char(hMenuCmd) THEN
BEGIN
GetItemMark(parentMenuHdl, j, parentMark);
IF ord(parentMark) = hierID THEN
BEGIN
found := true;
Leave; { FOR loop }
END; { IF ord() }
END; { Hierarchical Menu }
END; { FOR }
i := i + 1; { IF found, i = correct # plus 1. }
END; { WHILE }
IF found THEN { ... is it enabled ??? }
IF j < 32 THEN
enabled := BitTst(@theMenuBar^^.wMenus[i - 1].mh^^.enableFlags,
menuTitleBit - j)
ELSE
enabled := true; { Items 32 & beyond. }
IF found & enabled & (IncreaseSize(theMenuBar) = noErr) THEN
BEGIN
{ 'tis re-locked by IncreaseSize PROC. }
WITH theMenuBar^^, wMenus[numMenus] DO
BEGIN
mh := theMenu; { Place at end = Hierarchical portion. }
menuType := hierMenu;
parentID := parentMenuHdl^^.menuID;
{ These fields are filled-in later by wMenuSelect }
{ for both Hierarchical and Regular menus: }
{ }
{ menuParentRgn, cumParentRgn and MenuDownOSHdl }
{ }
{ You'll notice that I ignore these fields when }
{ inserting and deleting a Regular menu because }
{ Hierarchical menus are inserted AFTER all Regular }
{ menus and are deleted immediately after use. }
END; { WITH theMenuBar^^, wMenus[numMenus] }
{ titleRect = parent item's rect. }
{ }
{ For starters, setup left & right coordinates: }
WITH parentItemRect DO
BEGIN
{ [i-1] belongs to parentMenuHdl. }
WITH theMenuBar^^.wMenus[i - 1] DO
IF menuType = regMenu THEN
left := titleRect.left + menuFrame
ELSE
left := titleRect.right - 4 * menuFrame + menuFrame;
CalcMenuSize(parentMenuHdl);
right := left + parentMenuHdl^^.menuWidth;
END; { WITH parentItemRect }
WITH theMenuBar^^.wMenus[i - 1] DO
IF menuType = regMenu THEN
currentHeight := titleRect.bottom + menuFrame
ELSE
currentHeight := titleRect.top + menuFrame;
FOR index := 1 TO j DO
BEGIN
prevHeight := currentHeight;
sizeIcon := GetItemIconSize(parentMenuHdl, index);
currentHeight := currentHeight + aboveBelowItem + Max(sizeFont,
sizeIcon) + aboveBelowItem;
END; { FOR }
{ Complete the other two dimensions. }
WITH parentItemRect DO
BEGIN
top := prevHeight;
bottom := currentHeight;
END; { WITH parentItemRect }
WITH theMenuBar^^, wMenus[i - 1] DO
BEGIN
{ Change ONLY right & left coords ... }
parentFrameRect := parentItemRect;
WITH parentFrameRect DO
BEGIN
left := left - menuFrame;
right := right + menuFrame + menuShadow;
END; { WITH parentFrameRect }
GetPort(oldPort);
{ ---- }
SetPort(wp);
LocalGlobal(parentFrameRect);
{ WMgrPort's portBits.bounds in global coordinates: }
WITH gScreen DO
BEGIN
IF parentFrameRect.right > right - 2 * menuFrame THEN {
Shift left. }
IF menuType = regMenu THEN
OffsetRect(parentFrameRect, right - 2 * menuFrame -
parentFrameRect.right, 0)
ELSE
OffsetRect(parentFrameRect, -(titleRect.right -
titleRect.left - 8 * menuFrame + (parentFrameRect.right -
parentFrameRect.left)), 0);
;
IF parentFrameRect.left < left + 2 * menuFrame THEN {
Shift right. }
OffsetRect(parentFrameRect, left + 2 * menuFrame -
parentFrameRect.left, 0);
END; { WITH gScreen }
{ Back to local window coordinates. }
GlobalLocal(parentFrameRect);
{ ---- }
SetPort(oldPort);
parentItemRect := parentFrameRect;
WITH parentItemRect DO
BEGIN
left := left + menuFrame;
right := right - menuFrame - menuShadow;
END;
;
{ [numMenus] belongs to inserted sub-Menu: }
wMenus[numMenus].titleRect := parentItemRect;
numMenus := numMenus + 1;
END; { WITH theMenuBar^^, wMenus[i - 1] }
END; { IF found & enabled & IncreaseSize }
EXIT(wInsertMenu);
END { beforeID = hierMenu }
ELSE { Smack in the middle somewhere !! }
BEGIN