/* @(#)Z 1.13 nt/src/ui/MenuAdW.cpp, odui, od96nt, odnt9712d 97/03/21 17:37:23 (97/03/20 16:05:40) */
//====START_GENERATED_PROLOG======================================
//
//
//   COMPONENT_NAME: odui
//
//   CLASSES: none
//
//   ORIGINS: 82,27
//
//
//   (C) COPYRIGHT International Business Machines Corp. 1995,1996
//   All Rights Reserved
//   Licensed Materials - Property of IBM
//   US Government Users Restricted Rights - Use, duplication or
//   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//   	
//   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
//   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
//   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
//   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
//   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
//   OR PERFORMANCE OF THIS SOFTWARE.
//
//====END_GENERATED_PROLOG========================================
/* -------------------------------------------------------------------------
 *   File:	MenuAdW.cpp
 *   Contains:	implementation of ODWinMenuAdapter object
 *   $Author:	purple $
 *   $Date:	1996/07/23 14:22:26 $
 *   $Source:
 *   $Revision: 1.1 $
 * -------------------------------------------------------------------------
*/

/*
 *  This file was generated by the SOM Compiler and Emitter Framework.
 *  Generated using template emitter:
 *      SOM Emitter emitxtm: 2.23.1.9
 */

#ifndef SOM_Module_menuadw_Source
#define SOM_Module_menuadw_Source
#endif

#define ODWinMenuAdapter_Class_Source

#include <ODTypesF.h>
#include <ODTypesB.xh>
#include <GeoTypes.xh>
#include <ODTypesM.xh>
#include <Part.xh>

#include <ODUtils.h>
#include <OrdColl.h>

#define VARIABLE_MACROS

#include "MenuAdW.xih"

//=============================================================================
// local non-SOM methods
//=============================================================================

//-----------------------------------------------------------------------------
// FindIDInfo
//-----------------------------------------------------------------------------
ODMenuID FindIDInfo(HMENU subMenu, ODUShort IDcount, ODMenuIDInfo *IDinfo)
{

    for (ODUShort index = 0; index < IDcount; index++)
    {
	if (subMenu == IDinfo[index].hMenu)
	{
	    return (IDinfo[index].id);
	}
    }

    return 0xffffffff;

} /* FindIDInfo */

//-----------------------------------------------------------------------------
// HandleWinError
//-----------------------------------------------------------------------------
void HandleWinError()
{
    DWORD err;

    // Put this here, so we only have to set one breakpoint in debugger
    // TO DO: notify user of error code ?
    // ----------------------------------------------------------------
    err = GetLastError();

} /* end HandleWinError */

//-----------------------------------------------------------------------------
// copyMenuString
//-----------------------------------------------------------------------------
inline string copyMenuString(string inputString)
{
    if (inputString)
    {
        string s = (string) new char[strlen(inputString) + 1];
        return strcpy(s, inputString);
    }
    return kODNULL;

} /* end copyMenuString */

//=============================================================================
// ODWinMenuAdapter class methods
//=============================================================================

//-----------------------------------------------------------------------------
// somInit [OVERRIDE]
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdaptersomInit(ODWinMenuAdapter *somSelf)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdaptersomInit");

    ODWinMenuAdapter_parent_ODObject_somInit(somSelf);

} /* end somInit */

//-----------------------------------------------------------------------------
// somUninit [OVERRIDE]
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdaptersomUninit(ODWinMenuAdapter *somSelf)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdaptersomUninit");

    Environment* ev = somGetGlobalEnvironment();

    // Free up all menu items and item list
    // ------------------------------------
    while (_fMenuItems->Count() != 0)
    {
	ODWinMenuItemAdapter* itemAd = (ODWinMenuItemAdapter*) _fMenuItems->First();

	_fMenuItems->Remove((ElementType)itemAd);

	ODDeleteObject(itemAd->subMenuAdapter);

	ODDeleteObject(itemAd->text);

	ODDeleteObject(itemAd);
    }

//    if (_fPart)
//      _fPart->Release(ev);

    ODDeleteObject(_fMenuItems);

    ODDeleteObject(_fMenuLabel);

    ODWinMenuAdapter_parent_ODObject_somUninit(somSelf);

} /* end somUninit */

//-----------------------------------------------------------------------------
// Init
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdapterInit(ODWinMenuAdapter *somSelf, 
					     Environment *ev, 
					     ODMenuID id,
					     HMENU parentHMENU)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterInit");

    _fMenuID            = id;
    _fMenuIsEnabled     = kODTrue;
    _fMenuItems         = new OrderedCollection;

    // create empty menu window for self
    // ---------------------------------
    if (_fParentHMENU)
	_fMenuHMENU   = CreateMenu();
    else
	_fMenuHMENU   = CreatePopupMenu();

    if (! _fMenuHMENU)
	HandleWinError();

    if (! SetMenuContextHelpId(_fMenuHMENU, (DWORD) id))
	HandleWinError();

    _fParentHMENU = parentHMENU;

} /* end Init */

//-----------------------------------------------------------------------------
// AddItemsFromPlatMenuEx
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdapterAddItemsFromPlatMenuEx(ODWinMenuAdapter *somSelf, 
								Environment *ev, 
								ODPlatformMenu platMenu,
								ODUShort      IDcount,
								ODMenuIDInfo *IDinfo)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterAddItemsFromPlatMenuEx");

    // add menu items copied from platform menu
    // ----------------------------------------

    ODUShort nItems = GetMenuItemCount(platMenu);

    if (nItems == -1)
	HandleWinError();

    for (ODUShort pos = 0; pos < nItems; pos++)
    {
	ODMenuItemID itemID  = GetMenuItemID(platMenu, pos);
	HMENU	     subMenu = NULL;

	if (itemID == 0xffffffff)
	{
	    subMenu = GetSubMenu(platMenu, pos);

	    if (! subMenu)
		HandleWinError();

	    itemID  = FindIDInfo(subMenu, IDcount, IDinfo);

	    if (itemID == 0xffffffff)
		return;
	}

	ODULong itemFlags = GetMenuState(platMenu, pos, MF_BYPOSITION);

	if (itemFlags == 0xffffffff)
	    HandleWinError();

	if (subMenu)
	{
	    somSelf->AddSubMenuLastEx(ev, itemID, subMenu, IDcount, IDinfo);

	    if ((HIBYTE(itemFlags) & MF_DISABLED) ||
		(HIBYTE(itemFlags) & MF_GRAYED))
		somSelf->EnableMenuItem(ev, itemID, kODFalse);
	}
	else
	{
	    ODPlatformMenuItem platItem;
	    platItem.iPosition   = 0;
	    platItem.afStyle     = itemFlags;
	    platItem.afAttribute = itemFlags;
	    platItem.id		 = itemID;
	    platItem.hwndSubMenu = kODNULL;
	    platItem.hItem	 = kODNULL;

	    somSelf->AddMenuItemLast(ev, itemID, &platItem);
	}

	// copy menu item text from platform menu item
	// -------------------------------------------
	char itemText[256];

	ODULong nLen = GetMenuString(platMenu, pos, itemText, 255, MF_BYPOSITION);

	if (nLen > 0)
	    somSelf->SetMenuItemText(ev, itemID, itemText);

    }
				
} /* end AddItemsFromPlatMenuEx */

//-----------------------------------------------------------------------------
// MenuID
//-----------------------------------------------------------------------------
SOM_Scope ODMenuID  SOMLINK ODWinMenuAdapterMenuID(ODWinMenuAdapter *somSelf, 
						   Environment *ev)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterMenuID");

    return _fMenuID;

} /* end MenuID */

//-----------------------------------------------------------------------------
// IsMenuEnabled
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterIsMenuEnabled(ODWinMenuAdapter *somSelf, 
							   Environment *ev)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterIsMenuEnabled");

    return _fMenuIsEnabled;

} /* end IsMenuEnabled */

//-----------------------------------------------------------------------------
// DisableMenu
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdapterDisableMenu(ODWinMenuAdapter *somSelf, 
						    Environment *ev)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterDisableMenu");

    if (! _fMenuIsEnabled) return;

    _fMenuIsEnabled = kODFalse;

    ODUShort pos = somSelf->GetPosInParentMenu(ev);
    BOOL     res = EnableMenuItem(_fParentHMENU, pos, (MF_BYPOSITION | MF_GRAYED));

    if (res == 0xffffffff)
	HandleWinError();

} /* end DisableMenu */

//-----------------------------------------------------------------------------
// EnableMenu
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdapterEnableMenu(ODWinMenuAdapter *somSelf, 
						   Environment *ev)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterEnableMenu");

    if (_fMenuIsEnabled) return;

    _fMenuIsEnabled = kODTrue;

    ODUShort pos = somSelf->GetPosInParentMenu(ev);
    BOOL     res = EnableMenuItem(_fParentHMENU, pos, (MF_BYPOSITION | MF_ENABLED));

    if (res == 0xffffffff)
	HandleWinError();

} /* end EnableMenu */

//-----------------------------------------------------------------------------
// GetMenuText
//-----------------------------------------------------------------------------
SOM_Scope ODUShort  SOMLINK ODWinMenuAdapterGetMenuText(ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							string* menuString)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetMenuText");

    ODUShort nCount   = 0;

    if (_fMenuLabel)
	nCount	    = strlen(_fMenuLabel);

    *menuString = copyMenuString(_fMenuLabel);

    return nCount;

} /* end GetMenuText */

//-----------------------------------------------------------------------------
// SetMenuText
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterSetMenuText(ODWinMenuAdapter *somSelf, 
							 Environment *ev, 
							 string menuString)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterSetMenuText");

    ODDeleteObject(_fMenuLabel);

    _fMenuLabel	= copyMenuString(menuString);

    UINT itemFlags = (MF_BYPOSITION | MF_STRING | MF_POPUP);

    if (_fMenuIsEnabled)
	itemFlags |= MF_ENABLED;
    else
	itemFlags |= MF_GRAYED;

    ODUShort pos = somSelf->GetPosInParentMenu(ev);
    BOOL     res = ModifyMenu( _fParentHMENU, pos, itemFlags,
				(UINT)(_fMenuHMENU), _fMenuLabel);
    if (res == FALSE)
	HandleWinError();

    return kODTrue;

} /* end SetMenuText */

//-----------------------------------------------------------------------------
// GetMenuItemText
//-----------------------------------------------------------------------------
SOM_Scope ODUShort  SOMLINK ODWinMenuAdapterGetMenuItemText(ODWinMenuAdapter *somSelf, 
							    Environment *ev, 
							    ODMenuItemID itemID, 
							    string* itemString)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetMenuItemText");

    if (! itemString)
	return 0;

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, itemID, &itemAd))
	return 0;

    ODUShort nCount = 0;

    if (itemAd->text)
	nCount = strlen(itemAd->text);

    *itemString = copyMenuString(itemAd->text);

    return nCount;

} /* end GetMenuItemText */

//-----------------------------------------------------------------------------
// SetMenuItemText
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK ODWinMenuAdapterSetMenuItemText(ODWinMenuAdapter *somSelf, 
							    Environment *ev, 
							    ODMenuItemID itemID, 
							    string itemString)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterSetMenuItemText");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, itemID, &itemAd))
	return kODFalse;

    if ((itemString) && (itemAd->separator))
    {
	// OK, now it's NOT a separator...
	// -------------------------------
	itemAd->separator = kODFalse;

	// TO DO: should we complain to caller?
	// ------------------------------------
    }

    ODDeleteObject(itemAd->text);

    itemAd->text = copyMenuString(itemString);

    ODUShort pos;
    BOOL     res;

    somSelf->GetMenuItemPosition(ev, itemID, &pos);

    UINT itemFlags = (MF_BYPOSITION | MF_STRING);

    if (itemAd->enabled)
	itemFlags |= MF_ENABLED;
    else
	itemFlags |= MF_GRAYED;


    if (itemAd->subMenuAdapter)
    {
	HMENU subMenu;
	(itemAd->subMenuAdapter)->GetPlatMenu(ev, &subMenu);

	itemFlags |= MF_POPUP;

	res = ModifyMenu( _fMenuHMENU, pos, itemFlags,
			 (UINT)(subMenu), itemAd->text );
    }
    else // ordinary item
    {
	res = ModifyMenu( _fMenuHMENU, pos, itemFlags,
			 (itemAd->id), (itemAd->text));
    }

    if (res == FALSE)
	HandleWinError();

    return kODTrue;

} /* SetMenuItemText */

//-----------------------------------------------------------------------------
// SetHideMenuItem
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK ODWinMenuAdapterSetHideMenuItem(ODWinMenuAdapter *somSelf, 
							    Environment *ev, 
							    ODMenuItemID menuItemID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterSetHideMenuItem");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    if (! itemAd->hidden)
    {
	itemAd->hidden = kODTrue;

	ODUShort  pos;
	somSelf->GetMenuItemPosition(ev, menuItemID, &pos);

	BOOL res = RemoveMenu(_fMenuHMENU, pos, MF_BYPOSITION);

	if (res == FALSE)
	    HandleWinError();
    }

    return kODTrue;

} /* end SetHideMenuItem */

//-----------------------------------------------------------------------------
// SetShowMenuItem
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK ODWinMenuAdapterSetShowMenuItem(ODWinMenuAdapter *somSelf, 
							    Environment *ev, 
							    ODMenuItemID menuItemID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterSetShowMenuItem");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    if (itemAd->hidden)
    {
	itemAd->hidden = kODFalse;

	ODPlatformMenuItem item;
	somSelf->GetPlatMenuItem(ev, itemAd, &item);

	ODUShort pos;
	BOOL     res;

	somSelf->GetMenuItemPosition(ev, menuItemID, &pos);

	if (item.hwndSubMenu)
	{
	    res = InsertMenu(_fMenuHMENU, pos, (MF_BYPOSITION | item.afStyle),
			     item.hwndSubMenu, (itemAd->text));
	}
	else
	{
	    res = InsertMenu(_fMenuHMENU, pos, (MF_BYPOSITION | item.afStyle),
			     item.id, (itemAd->text));
	}

	if (res == FALSE)
	    HandleWinError();
    }

    return kODTrue;

} /* end SetShowMenuItem */

//-----------------------------------------------------------------------------
// CheckMenuItem
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterCheckMenuItem(ODWinMenuAdapter *somSelf, 
							   Environment *ev, 
							   ODMenuItemID menuItemID, 
							   ODBoolean check)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterCheckMenuItem");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    if (itemAd->checked != check)
    {
	itemAd->checked = check;

	ODUShort pos;
	DWORD    res;
	somSelf->GetMenuItemPosition(ev, menuItemID, &pos);

	if (check)
	    res = CheckMenuItem(_fMenuHMENU, pos, (MF_BYPOSITION | MF_CHECKED));
	else
	    res = CheckMenuItem(_fMenuHMENU, pos, (MF_BYPOSITION | MF_UNCHECKED));

	if (res == 0xffffffff)
	    HandleWinError();
    }

    return kODTrue;

} /* end CheckMenuItem */

//-----------------------------------------------------------------------------
// EnableMenuItem
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterEnableMenuItem(ODWinMenuAdapter *somSelf, 
							    Environment *ev, 
							    ODMenuItemID menuItemID, 
							    ODBoolean enable)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterEnableMenuItem");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    if (itemAd->enabled != enable)
    {
	itemAd->enabled = enable;

	ODUShort pos;
	BOOL     res;
	somSelf->GetMenuItemPosition(ev, menuItemID, &pos);

	if (enable)
	    res = EnableMenuItem(_fMenuHMENU, pos, (MF_BYPOSITION | MF_ENABLED));
	else
	    res = EnableMenuItem(_fMenuHMENU, pos, (MF_BYPOSITION | MF_GRAYED));

	if (res == 0xffffffff)
	    HandleWinError();

    }

    // If item contains a submenu, enable/disable submenu adapter too
    // --------------------------------------------------------------
    if (itemAd->subMenuAdapter)
    {
        if (enable)
           (itemAd->subMenuAdapter)->EnableMenu(ev);
        else
           (itemAd->subMenuAdapter)->DisableMenu(ev);
    }

    return kODTrue;

} /* end EnableMenuItem */

//-----------------------------------------------------------------------------
// AddMenuItemBefore
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterAddMenuItemBefore(
							ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							ODMenuItemID itemID, 
							ODPlatformMenuItem* item, 
							ODMenuItemID beforeID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterAddMenuItemBefore");

    if (! item)
	return kODFalse;

    // TO DO: warn callers not to do this!
    // -----------------------------------
    if (itemID == kODNULL)
	itemID = item->id;

    if (somSelf->ItemExists(ev, itemID))
	return kODFalse;

    // Create a new menu item adapter from the platform menu item
    // ----------------------------------------------------------
    ODWinMenuItemAdapter* itemAd = new ODWinMenuItemAdapter;

    itemAd->id		   = itemID;
    itemAd->parentAdapter  = somSelf;
    itemAd->subMenuAdapter = kODNULL;
    itemAd->enabled	   = kODTrue;
    itemAd->hidden	   = kODFalse;
    itemAd->checked	   = kODFalse;
    itemAd->separator	   = kODFalse;
    itemAd->text	   = kODNULL;

    UINT itemFlags = (item->afStyle | item->afAttribute);

    if ( (itemFlags & MF_POPUP)	&&
	 (item->hwndSubMenu)	&&
	 (IsMenu((HMENU)item->hwndSubMenu) == TRUE) )
    {
	// TO DO: warn callers not to do this! The submenus won't have ID's 
	// ----------------------------------------------------------------
	itemAd->subMenuAdapter = new ODWinMenuAdapter;
	(itemAd->subMenuAdapter)->Init(ev, itemID, _fMenuHMENU);
	(itemAd->subMenuAdapter)->SetParentAdapter(ev, somSelf);
	(itemAd->subMenuAdapter)->AddItemsFromPlatMenuEx(ev,
					(ODPlatformMenu)item->hwndSubMenu, 0, NULL);
	
    }

    if ((itemFlags & MF_DISABLED) ||
        (itemFlags & MF_GRAYED))
	itemAd->enabled = kODFalse;

    if (itemFlags & MF_CHECKED)
	itemAd->checked = kODTrue;

    if (itemFlags & MF_SEPARATOR)
	itemAd->separator = kODTrue;

    // Add it to this menu adapter's collection
    // ----------------------------------------
    ODBoolean added = kODFalse;

    OrderedCollectionIterator iter(_fMenuItems);
    ODWinMenuItemAdapter* nextAd = (ODWinMenuItemAdapter*) iter.First();
    while( (nextAd) && (! added) && (iter.IsNotComplete()) )
    {
        if (nextAd->id == beforeID)
        {
	    _fMenuItems->AddBefore((ElementType) nextAd, (ElementType) itemAd);
            added = kODTrue;
        }
	else
	    nextAd = (ODWinMenuItemAdapter*) iter.Next();
    }

    if (! added)
	_fMenuItems->AddLast((ElementType) itemAd);

    // Insert it into this menu adapter's platform menu
    // (Don't use passed-in item; may have wrong position)
    // ---------------------------------------------------
    ODPlatformMenuItem newPlatItem;
    somSelf->GetPlatMenuItem(ev, itemAd, &newPlatItem);

    ODUShort pos;
    BOOL     res;

    somSelf->GetMenuItemPosition(ev, itemID, &pos);

    if (newPlatItem.hwndSubMenu)
    {
	res = InsertMenu(_fMenuHMENU, pos,
			 (MF_BYPOSITION | newPlatItem.afStyle),
			 newPlatItem.hwndSubMenu, NULL);
    }
    else
    {
	res = InsertMenu(_fMenuHMENU, pos,
			 (MF_BYPOSITION | newPlatItem.afStyle),
			 newPlatItem.id, NULL);
    }

    if (res == FALSE)
	HandleWinError();

    return kODTrue;

} /* end AddMenuItemBefore */

//-----------------------------------------------------------------------------
// AddMenuItemLast
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterAddMenuItemLast(
							ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							ODMenuItemID itemID, 
							ODPlatformMenuItem* item)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterAddMenuItemLast");

    if (! item)
	return kODFalse;

    // TO DO: warn callers not to do this!
    // -----------------------------------
    if (itemID == kODNULL)
	itemID = item->id;

    if (somSelf->ItemExists(ev, itemID))
	return kODFalse;

    // Create a new menu item adapter from the platform menu item
    // ----------------------------------------------------------
    ODWinMenuItemAdapter* itemAd = new ODWinMenuItemAdapter;

    itemAd->id		   = itemID;
    itemAd->parentAdapter  = somSelf;
    itemAd->subMenuAdapter = kODNULL;
    itemAd->enabled	   = kODTrue;
    itemAd->hidden	   = kODFalse;
    itemAd->checked	   = kODFalse;
    itemAd->separator	   = kODFalse;
    itemAd->text	   = kODNULL;

    UINT itemFlags = (item->afStyle | item->afAttribute);

    if ( (itemFlags & MF_POPUP)	&&
	 (item->hwndSubMenu)	&&
	 (IsMenu((HMENU)item->hwndSubMenu) == TRUE) )
    {
	// TO DO: warn callers not to do this! The submenus won't have ID's 
	// ----------------------------------------------------------------
	itemAd->subMenuAdapter = new ODWinMenuAdapter;
	(itemAd->subMenuAdapter)->Init(ev, itemID, _fMenuHMENU);
	(itemAd->subMenuAdapter)->SetParentAdapter(ev, somSelf);
	(itemAd->subMenuAdapter)->AddItemsFromPlatMenuEx(ev,
					(ODPlatformMenu)item->hwndSubMenu, 0, NULL);
    }

    if ((itemFlags & MF_DISABLED) ||
	(itemFlags & MF_GRAYED))
	itemAd->enabled = kODFalse;

    if (itemFlags & MF_CHECKED)
	itemAd->checked = kODTrue;

    if (itemFlags & MF_SEPARATOR)
	itemAd->separator = kODTrue;

    // Add it to this menu adapter's collection
    // ----------------------------------------
    _fMenuItems->AddLast((ElementType) itemAd);

    // Insert it into this menu adapter's platform menu
    // (Don't use passed-in item; may have wrong position)
    // ---------------------------------------------------
    ODPlatformMenuItem newPlatItem;
    somSelf->GetPlatMenuItem(ev, itemAd, &newPlatItem);

    BOOL     res;

    if (newPlatItem.hwndSubMenu)
    {
	res = AppendMenu(_fMenuHMENU, newPlatItem.afStyle,
			 newPlatItem.hwndSubMenu, NULL);
    }
    else
    {
	res = AppendMenu(_fMenuHMENU, newPlatItem.afStyle,
			 newPlatItem.id, NULL);
    }

    if (res == FALSE)
	HandleWinError();

    return kODTrue;

} /* end AddMenuItemLast */


//-----------------------------------------------------------------------------
// AddSubMenuBefore
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterAddSubMenuBeforeEx(
							ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							ODMenuID subMenuID, 
							ODPlatformMenu subMenu,
							ODMenuItemID   beforeID,
							ODUShort       IDcount,
							ODMenuIDInfo  *IDinfo)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterAddSubMenuBeforeEx");

    if (somSelf->GetSubMenu(ev, subMenuID))
	return kODFalse;

    // Create a menu adapter from the platform menu
    // --------------------------------------------
    ODWinMenuAdapter* subMenuAd = new ODWinMenuAdapter;
    subMenuAd->Init(ev, subMenuID, _fMenuHMENU);
    subMenuAd->SetParentAdapter(ev, somSelf);
    subMenuAd->AddItemsFromPlatMenuEx(ev, subMenu, IDcount, IDinfo);

    // Create a menu item adapter
    // --------------------------
    ODWinMenuItemAdapter *subMenuItemAd = new ODWinMenuItemAdapter;

    subMenuItemAd->id		  = subMenuID;
    subMenuItemAd->parentAdapter  = somSelf;
    subMenuItemAd->subMenuAdapter = subMenuAd;
    subMenuItemAd->enabled	  = subMenuAd->IsMenuEnabled(ev);
    subMenuItemAd->hidden	  = kODFalse;
    subMenuItemAd->checked	  = kODFalse;
    subMenuItemAd->separator	  = kODFalse;
    subMenuItemAd->text		  = kODNULL;

    // Add it to this menu adapter's collection
    // ----------------------------------------
    ODBoolean added = kODFalse;

    OrderedCollectionIterator iter(_fMenuItems);
    ODWinMenuItemAdapter* nextAd = (ODWinMenuItemAdapter*) iter.First();
    while( (nextAd) && (! added) && (iter.IsNotComplete()) )
    {
        if (nextAd->id == beforeID)
        {
	    _fMenuItems->AddBefore((ElementType) nextAd, (ElementType) subMenuItemAd);
            added = kODTrue;
        }
	else
            nextAd = (ODWinMenuItemAdapter*) iter.Next();
    }

    if (! added)
	_fMenuItems->AddLast((ElementType) subMenuItemAd);

    // Insert it into this menu adapter's platform menu
    // ------------------------------------------------
    ODPlatformMenuItem newPlatSubMenuItem;
    somSelf->GetPlatMenuItem(ev, subMenuItemAd, &newPlatSubMenuItem);

    ODUShort pos;
    somSelf->GetMenuItemPosition(ev, subMenuID, &pos);
    newPlatSubMenuItem.iPosition = pos;

    BOOL res = InsertMenu(_fMenuHMENU, pos,
			  (MF_BYPOSITION | newPlatSubMenuItem.afStyle),
			  newPlatSubMenuItem.hwndSubMenu, NULL);

    if (res == FALSE)
	HandleWinError();

    return kODTrue;

} /* end AddSubMenuBeforeEx */

//-----------------------------------------------------------------------------
// AddSubMenuLast
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterAddSubMenuLastEx(
							ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							ODMenuID subMenuID, 
							ODPlatformMenu subMenu,
							ODUShort       IDcount,
							ODMenuIDInfo  *IDinfo)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterAddSubMenuLastEx");

    if (somSelf->GetSubMenu(ev, subMenuID))
	return kODFalse;

    // Create a menu adapter from the platform menu
    // --------------------------------------------
    ODWinMenuAdapter* subMenuAd = new ODWinMenuAdapter;
    subMenuAd->Init(ev, subMenuID, _fMenuHMENU);
    subMenuAd->SetParentAdapter(ev, somSelf);
    subMenuAd->AddItemsFromPlatMenuEx(ev, subMenu, IDcount, IDinfo);

    // Create a menu item adapter
    // --------------------------
    ODWinMenuItemAdapter *subMenuItemAd = new ODWinMenuItemAdapter;

    subMenuItemAd->id		  = subMenuID;
    subMenuItemAd->parentAdapter  = somSelf;
    subMenuItemAd->subMenuAdapter = subMenuAd;
    subMenuItemAd->enabled	  = subMenuAd->IsMenuEnabled(ev);
    subMenuItemAd->hidden	  = kODFalse;
    subMenuItemAd->checked	  = kODFalse;
    subMenuItemAd->separator	  = kODFalse;
    subMenuItemAd->text		  = kODNULL;

    // Add it to this menu adapter's collection
    // ----------------------------------------
    _fMenuItems->AddLast((ElementType) subMenuItemAd);

    // Insert it into this menu adapter's platform menu
    // ------------------------------------------------
    ODPlatformMenuItem newPlatSubMenuItem;
    somSelf->GetPlatMenuItem(ev, subMenuItemAd, &newPlatSubMenuItem);

    BOOL     res = AppendMenu(_fMenuHMENU, newPlatSubMenuItem.afStyle,
			      newPlatSubMenuItem.hwndSubMenu, NULL);

    if (res == FALSE)
	HandleWinError();

    return kODTrue;

} /* end AddSubMenuLastEx */

//-----------------------------------------------------------------------------
// GetSubMenu
//-----------------------------------------------------------------------------
SOM_Scope ODPlatformMenu  SOMLINK ODWinMenuAdapterGetSubMenu(
							ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							ODMenuID subMenuID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetSubMenu");

    ODPlatformMenu platSubMenu = kODNULL;

    if (_fMenuID == subMenuID)
	return _fMenuHMENU;

    OrderedCollectionIterator iter(_fMenuItems);
    for (ODWinMenuItemAdapter* nextItemAd = (ODWinMenuItemAdapter*) iter.First();
         ((! platSubMenu) && (iter.IsNotComplete()));
         nextItemAd = (ODWinMenuItemAdapter*) iter.Next())
    {
	ODWinMenuAdapter* nextSubMenuAd = nextItemAd->subMenuAdapter;

	if (nextSubMenuAd)
	{
	    platSubMenu = nextSubMenuAd->GetSubMenu(ev, subMenuID);
	}
    }

    return platSubMenu;
    
} /* end GetSubMenu */

//-----------------------------------------------------------------------------
// ItemExists
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterItemExists(ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							ODMenuItemID menuItemID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterItemExists");

    ODWinMenuItemAdapter* existing;

    return (somSelf->GetMenuItemAdapter(ev, menuItemID, &existing));

} /* end ItemExists */

//-----------------------------------------------------------------------------
// IsItemEnabled
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterIsItemEnabled(ODWinMenuAdapter *somSelf, 
							   Environment *ev, 
							   ODMenuItemID menuItemID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterIsItemEnabled");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    return (itemAd->enabled);

} /* end IsItemEnabled */

//-----------------------------------------------------------------------------
// IsItemChecked
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterIsItemChecked(ODWinMenuAdapter *somSelf, 
							   Environment *ev, 
							   ODMenuItemID menuItemID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterIsItemChecked");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    return (itemAd->checked);

} /* end IsItemChecked */

//-----------------------------------------------------------------------------
// IsItemHidden
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterIsItemHidden(ODWinMenuAdapter *somSelf, 
							  Environment *ev, 
							  ODMenuItemID menuItemID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterIsItemHidden");

    ODWinMenuItemAdapter* itemAd;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    return (itemAd->hidden);

} /* end IsItemHidden */

//-----------------------------------------------------------------------------
// RemoveMenuItem
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterRemoveMenuItem(ODWinMenuAdapter *somSelf, 
							    Environment *ev, 
							    ODMenuItemID menuItemID)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterRemoveMenuItem");

    ODWinMenuItemAdapter* itemAd;
    ODUShort  pos;

    if (! somSelf->GetMenuItemAdapter(ev, menuItemID, &itemAd))
	return kODFalse;

    somSelf->GetMenuItemPosition(ev, menuItemID, &pos);

    BOOL res = RemoveMenu(_fMenuHMENU, pos, MF_BYPOSITION);

    if (res == FALSE)
	HandleWinError();

    _fMenuItems->Remove((ElementType) itemAd);

    ODDeleteObject(itemAd->subMenuAdapter);

    ODDeleteObject(itemAd->text);

    ODDeleteObject(itemAd);

    return kODTrue;

} /* end RemoveMenuItem */

//-----------------------------------------------------------------------------
// GetPlatMenuItem
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean SOMLINK ODWinMenuAdapterGetPlatMenuItem(ODWinMenuAdapter *somSelf, 
							 Environment *ev, 
							 ODWinMenuItemAdapter* itemAd,
							 ODPlatformMenuItem* platMenuItem)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetPlatMenuItem");

    if (! platMenuItem)
	return kODFalse;

    // caller must set position, if needed
    // -----------------------------------
    platMenuItem->iPosition   = -1;

    if (itemAd->subMenuAdapter)
	platMenuItem->afStyle = (MF_POPUP | MF_STRING);
    else if (itemAd->separator)
	platMenuItem->afStyle = MF_SEPARATOR;
    else
	platMenuItem->afStyle = MF_STRING;

    if ((! itemAd->separator)	   &&
        (! itemAd->subMenuAdapter) &&
	(itemAd->checked))
    {
	platMenuItem->afStyle |= MF_CHECKED;
    }

    if (itemAd->enabled)
	platMenuItem->afStyle |= MF_ENABLED;
    else
	platMenuItem->afStyle |= MF_GRAYED;

    platMenuItem->afAttribute = platMenuItem->afStyle;

    platMenuItem->id = itemAd->id;

    if (itemAd->subMenuAdapter)
    {
	ODPlatformMenu platSubMenu;
	(itemAd->subMenuAdapter)->GetPlatMenu(ev, &platSubMenu);
	platMenuItem->hwndSubMenu = (unsigned long) platSubMenu;
    }
    else
	platMenuItem->hwndSubMenu = NULL;

    platMenuItem->hItem = NULL;

    return kODTrue;

} /* end GetPlatMenuItem */

//-----------------------------------------------------------------------------
// GetPlatMenu
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterGetPlatMenu(ODWinMenuAdapter *somSelf, 
                                                         Environment *ev, 
                                                         ODPlatformMenu* platMenu)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetPlatMenu");

    if (! platMenu)
	return kODFalse;

    *platMenu = (ODPlatformMenu) _fMenuHMENU;

    return kODTrue;
} /* end GetPlatMenu */

//-----------------------------------------------------------------------------
// GetPart
//-----------------------------------------------------------------------------
SOM_Scope ODPart*  SOMLINK ODWinMenuAdapterGetPart(ODWinMenuAdapter *somSelf, 
                                                    Environment *ev)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetPart");

    return _fPart;

} /* end GetPart */

//-----------------------------------------------------------------------------
// SetPart
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdapterSetPart(ODWinMenuAdapter *somSelf, 
                                                 Environment *ev, 
                                                ODPart* part)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterSetPart");

//    if (part)
//      part->Acquire(ev);

//    if (_fPart)
//      _fPart->Release(ev);

    _fPart = part;

} /* end SetPart */

//-----------------------------------------------------------------------------
// GetMenuItemAdapter
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterGetMenuItemAdapter(ODWinMenuAdapter *somSelf, 
                                                 Environment *ev, 
                                                ODMenuItemID id,
                                                ODWinMenuItemAdapter** itemAd)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetMenuItemAdapter");

    ODBoolean found = kODFalse;

    OrderedCollectionIterator iter(_fMenuItems);
    for (ODWinMenuItemAdapter* nextAd = (ODWinMenuItemAdapter*) iter.First();
         ((! found) && (iter.IsNotComplete()));
         nextAd = (ODWinMenuItemAdapter*) iter.Next())
    {
         if (nextAd->id == id)
	 {
	     *itemAd = nextAd;
             found   = kODTrue;
	 }
         else if ( nextAd->subMenuAdapter )
         {
             found = (nextAd->subMenuAdapter)->GetMenuItemAdapter( ev, id, itemAd );
         }
    }

    return found;

} /* end GetMenuItemAdapter */

//-----------------------------------------------------------------------------
// GetMenuItemPosition
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterGetMenuItemPosition(ODWinMenuAdapter *somSelf, 
								 Environment *ev, 
								 ODMenuItemID id,
								 ODUShort* pos)
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetMenuItemPosition");

    ODBoolean foundIt = kODFalse;
    ODUShort  currPos = 0;

    OrderedCollectionIterator iter(_fMenuItems);
    for (ODWinMenuItemAdapter* nextAd = (ODWinMenuItemAdapter*) iter.First();
         ((! foundIt) && (iter.IsNotComplete()));
         nextAd = (ODWinMenuItemAdapter*) iter.Next())
    {
	if (nextAd->id == id)
	{
	     *pos    = currPos;
	     foundIt = kODTrue;
	}

	currPos++;
    }

    return foundIt;

} /* end GetMenuItemPosition */

//-----------------------------------------------------------------------------
// GetSubMenuAdapter
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterGetSubMenuAdapter(
							ODWinMenuAdapter *somSelf, 
							Environment *ev, 
							ODMenuID subMenuID,
							ODWinMenuAdapter **subMenuAd) 
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetSubMenuAdapter");

    if (! subMenuAd)
	return kODFalse;

    if (_fMenuID == subMenuID)
    {
	*subMenuAd = somSelf;
	return kODTrue;
    }

    ODBoolean foundIt = kODFalse;

    OrderedCollectionIterator iter(_fMenuItems);
    for (ODWinMenuItemAdapter* nextItemAd = (ODWinMenuItemAdapter*) iter.First();
         ((! foundIt) && (iter.IsNotComplete()));
         nextItemAd = (ODWinMenuItemAdapter*) iter.Next())
    {
	ODWinMenuAdapter* nextSubMenuAd = nextItemAd->subMenuAdapter;

	if (nextSubMenuAd)
	{
	    foundIt = nextSubMenuAd->GetSubMenuAdapter(ev, subMenuID, subMenuAd);
	}
    }

    return foundIt;
    
} /* end GetSubMenuAdapter */

//-----------------------------------------------------------------------------
// GetParentAdapter
//-----------------------------------------------------------------------------

SOM_Scope void  SOMLINK ODWinMenuAdapterGetParentAdapter(ODWinMenuAdapter *somSelf, 
							  Environment *ev, 
							 ODWinMenuAdapter **parentAd) 
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetParentAdapter");

    *parentAd = _fParentAdapter;

} /* end GetParentAdapter */

//-----------------------------------------------------------------------------
// SetParentAdapter
//-----------------------------------------------------------------------------
SOM_Scope void  SOMLINK ODWinMenuAdapterSetParentAdapter(ODWinMenuAdapter *somSelf, 
							  Environment *ev, 
							 ODWinMenuAdapter *parentAd) 
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterSetParentAdapter");

    _fParentAdapter = parentAd;

} /* end SetParentAdapter */

//-----------------------------------------------------------------------------
// GetPosInParentMenu
//-----------------------------------------------------------------------------
SOM_Scope ODUShort  SOMLINK ODWinMenuAdapterGetPosInParentMenu(
							ODWinMenuAdapter *somSelf, 
							Environment *ev) 
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetPosInParentMenu");

    ODUShort nItems = GetMenuItemCount(_fParentHMENU);

    if (nItems == -1)
	HandleWinError();

    for (ODUShort pos = 0; pos < nItems; pos++)
    {
	ODMenuItemID itemID  = GetMenuItemID(_fParentHMENU, pos);
	HMENU subMenu;

	if (itemID  == 0xffffffff)
	{

	    subMenu = GetSubMenu(_fParentHMENU, pos);

	    if (! subMenu)
		HandleWinError();

	    if (subMenu == _fMenuHMENU)
		return pos;
	}
    }

    return nItems;

} /* GetPosInParentMenu */

//-----------------------------------------------------------------------------
// GetSubMenuIDInfo
//-----------------------------------------------------------------------------
SOM_Scope ODBoolean  SOMLINK ODWinMenuAdapterGetSubMenuIDInfo(
							ODWinMenuAdapter *somSelf, 
							Environment *ev,
							OrderedCollection *IDinfo) 
{
    ODWinMenuAdapterData *somThis = ODWinMenuAdapterGetData(somSelf);
    ODWinMenuAdapterMethodDebug("ODWinMenuAdapter","ODWinMenuAdapterGetSubMenuIDInfo");

    ODBoolean bResult = kODTrue;

    OrderedCollectionIterator iter(_fMenuItems);
    for (ODWinMenuItemAdapter* nextItemAd = (ODWinMenuItemAdapter*) iter.First();
         ((bResult == kODTrue) && (iter.IsNotComplete()));
         nextItemAd = (ODWinMenuItemAdapter*) iter.Next())
    {
	if (nextItemAd->subMenuAdapter)
	    bResult = (nextItemAd->subMenuAdapter)->GetSubMenuIDInfo(ev, IDinfo);
    }

    ODMenuIDInfo* my_info = new ODMenuIDInfo;

    my_info->hMenu = _fMenuHMENU;
    my_info->id    = _fMenuID;

    IDinfo->AddLast((ElementType) my_info);

    return bResult;
    
} /* end GetSubMenuIDInfo */
