Menu.java in  » Script » java2script » org » eclipse » swt » widgets » Java Source Code / Java Documentation 2Java Source Code and Java Documentation

Home
Java Source Code / Java Documentation 2
1.2D
2.3D
3.Ajax
4.Algebra
5.App Engine
6.Aspect
7.Assemble
8.Cache
9.Cassandra
10.Chat
11.Cloud
12.CMS
13.CouchDB
14.Crypt
15.Database
16.Distributed
17.Eclipse
18.Facebook
19.File
20.Forum
21.GAE
22.Game
23.Google tech
24.Graph
25.Graphic
26.GWT
27.Hibernate
28.HTML
29.HTTP
30.Image
31.IntelliJ
32.IRC
33.J2EE
34.J2ME
35.JDBC
36.JPA
37.JSON
38.JSR
39.JUnit
40.JVM
41.Language
42.Linux
43.Math
44.Maven
45.Media
46.Messenger
47.MiddleWare
48.Mobile
49.Mock
50.MongoDB
51.Mp3
52.Music
53.MVC
54.Network
55.OpenID
56.OSGi
57.Parse
58.Persist
59.Petri
60.Phone
61.Physics
62.REST
63.Robot
64.RPC
65.RSS
66.Ruby
67.Script
68.Search
69.Spring
70.SQL
71.SSH
72.Sudoku
73.Swing
74.Tapestry
75.Test
76.Text
77.Torrent
78.Twitter
79.UML
80.UnTagged
81.Utilities
82.Web
83.Wiki
84.XML
Java Source Code / Java Documentation 2 » Script » java2script » org.eclipse.swt.widgets 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


/*******************************************************************************
 * 
 *******************************************************************************/
package org.eclipse.swt.widgets;

 
import java.util.Date;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.events.MenuListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.RunnableCompatibility;
import org.eclipse.swt.internal.browser.OS;
import org.eclipse.swt.internal.xhtml.CSSStyle;
import org.eclipse.swt.internal.xhtml.Clazz;
import org.eclipse.swt.internal.xhtml.Element;
import org.eclipse.swt.internal.xhtml.HTMLEvent;
import org.eclipse.swt.internal.xhtml.document;
import org.eclipse.swt.internal.xhtml.window;

/**
 * Instances of this class are user interface objects that contain
 * menu items.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>BAR, DROP_DOWN, POP_UP, NO_RADIO_GROUP</dd>
 * <dd>LEFT_TO_RIGHT, RIGHT_TO_LEFT</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Help, Hide, Show </dd>
 * </dl>
 * <p>
 * Note: Only one of BAR, DROP_DOWN and POP_UP may be specified.
 * Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
 * </p><p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 * 
 * @j2sPrefix
 * $WTC$$.registerCSS ("$wt.widgets.Menu");
 */

public class Menu extends Widget {
	/**
	 * the handle to the OS resource 
	 * (Warning: This field is platform dependent)
	 * <p>
	 * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
	 * public API. It is marked public only so that it can be shared
	 * within the packages provided by SWT. It is not available on all
	 * platforms and should never be accessed from application code.
	 * </p>
	 */
	//public Element handle;
	
	int x, y, hwndCB, id0, id1;
	boolean hasLocation;
	MenuItem cascade;
	Decorations parent;
	ImageList imageList;
	
	MenuItem[] items;
	MenuItem defaultItem;
	Element btnFocus;
	int currentIndex;
	
	long lastFocusdTime;
	
	Object[] acceleratorTable;
	
	/* Resource ID for SHMENUBARINFO */
	static final int ID_PPC = 100;
	
	/* SmartPhone SoftKeyBar resource ids */
	static final int ID_SPMM = 102;
	static final int ID_SPBM = 103;
	static final int ID_SPMB = 104;
	static final int ID_SPBB = 105;
	static final int ID_SPSOFTKEY0 = 106; 
	static final int ID_SPSOFTKEY1 = 107;
	static final int GROWTH_RATE = 5;

	private Object hMenuKeyDown;
	Object hMenuBlur;
	private Object hMenuFocus;
	private Object hMenuMouseDown;
/**
 * Constructs a new instance of this class given its parent,
 * and sets the style for the instance so that the instance
 * will be a popup menu on the given parent's shell.
 *
 * @param parent a control which will be the parent of the new instance (cannot be null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#POP_UP
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Menu (Control parent) {
	this  (checkNull (parent).menuShell (), SWT.POP_UP);
}

/**
 * Constructs a new instance of this class given its parent
 * (which must be a <code>Decorations</code>) and a style value
 * describing its behavior and appearance.
 * <p>
 * The style value is either one of the style constants defined in
 * class <code>SWT</code> which is applicable to instances of this
 * class, or must be built by <em>bitwise OR</em>'ing together 
 * (that is, using the <code>int</code> "|" operator) two or more
 * of those <code>SWT</code> style constants. The class description
 * lists the style constants that are applicable to the class.
 * Style bits are also inherited from superclasses.
 * </p>
 *
 * @param parent a decorations control which will be the parent of the new instance (cannot be null)
 * @param style the style of menu to construct
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#BAR
 * @see SWT#DROP_DOWN
 * @see SWT#POP_UP
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Menu (Decorations parent, int style) {
	this  (parent, checkStyle (style), null);
}

/**
 * Constructs a new instance of this class given its parent
 * (which must be a <code>Menu</code>) and sets the style
 * for the instance so that the instance will be a drop-down
 * menu on the given parent's parent.
 *
 * @param parentMenu a menu which will be the parent of the new instance (cannot be null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#DROP_DOWN
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Menu (Menu parentMenu) {
	this  (checkNull (parentMenu).parent, SWT.DROP_DOWN);
}

/**
 * Constructs a new instance of this class given its parent
 * (which must be a <code>MenuItem</code>) and sets the style
 * for the instance so that the instance will be a drop-down
 * menu on the given parent's parent menu.
 *
 * @param parentItem a menu item which will be the parent of the new instance (cannot be null)
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
 *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
 * </ul>
 *
 * @see SWT#DROP_DOWN
 * @see Widget#checkSubclass
 * @see Widget#getStyle
 */
public Menu (MenuItem parentItem) {
	this  (checkNull (parentItem).parent);
}

Menu (Decorations parent, int style, Element handle) {
	super  (parent, checkStyle (style));
	this .parent = parent;
	this .handle = handle;
	/*
	* Bug in IBM JVM 1.3.1.  For some reason, when the checkOrientation() is
	* called from createWidget(), the JVM issues this error:
	*
	* JVM Exception 0x2 (subcode 0x0) occurred in thread "main" (TID:0x9F19D8)
	* 
	* In addition, on Windows XP, a dialog appears with following error message,
	* indicating that the problem may be in the JIT:
	* 
	* AppName: java.exe	 AppVer: 0.0.0.0	 ModName: jitc.dll
	* ModVer: 0.0.0.0	 Offset: 000b6912
	* 
	* The fix is to call checkOrientation() from here.
	*/
	checkOrientation (parent);
	createWidget ();
}

void _setVisible (boolean visible) {
	if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
	CSSStyle style = handle.style;
	if (visible) {
		//style.width = "200px";
		Rectangle clientArea = getDisplay().getPrimaryMonitor().getClientArea();
		style.zIndex = window.currentTopZIndex + 1000;
		style.display = "block";
		handle.style.height = "";
		int height = OS.getContainerHeight(handle);
		if (OS.isIE || OS.isOpera) {
			int maxWidth = 0;
			boolean hasImage = false;
			boolean hasSelection = false;
			MenuItem[] children = getItems();
			for (int i = 0; i < children.length; i++) {
				MenuItem item = children[i];
				int width = OS.getStringStyledWidth(item.getText(), "menu-item-text", null);
				if (item.getImage() != null) {
					hasImage = true;
				}
				if ((item.getStyle() & (SWT.CHECK | SWT.RADIO)) != 0) {
					hasImage = true;
				}
				maxWidth = Math.max(maxWidth, width);
			}
			handle.style.width = (maxWidth + (hasImage ? 18 : 0) + (hasSelection ? 18 : 0) + 32) + "px";
		} else {
			handle.style.width = "";
			int width = OS.getContainerWidth(handle);
			handle.style.width = (width + 32) + "px";
		}
		handle.style.height = height + "px";
		int width = OS.getContainerWidth(handle);
		int left = x, top = y;
		if (y + height > clientArea.y + clientArea.height) {
			if (y + height - clientArea.y - clientArea.height > height - y) {
				top = y - height;
			}
		}
		if (x + width > clientArea.x + clientArea.width) {
			if (x + width - clientArea.x - clientArea.width > width - x) {
				left = x - width;
			}
		}
		style.left = left + "px";
		style.top = top + "px";
		OS.SetFocus(btnFocus); //btnFocus.focus();
		if (hooks(SWT.Show)) sendEvent(SWT.Show);
	} else {
		style.display = "none";
		style.width = "";
		if (hooks(SWT.Hide)) sendEvent(SWT.Hide);
	}
	/*
	int hwndParent = parent.handle;
	if (visible) {
		int flags = OS.TPM_LEFTBUTTON;
		if (OS.GetKeyState (OS.VK_LBUTTON) >= 0) flags |= OS.TPM_RIGHTBUTTON;
		if ((style & SWT.RIGHT_TO_LEFT) != 0) flags |= OS.TPM_RIGHTALIGN;
		if ((parent.style & SWT.MIRRORED) != 0) {
			flags &= ~OS.TPM_RIGHTALIGN;
			if ((style & SWT.LEFT_TO_RIGHT) != 0) flags |= OS.TPM_RIGHTALIGN;
		}
		int nX = x, nY = y;
		if (!hasLocation) {
			int pos = OS.GetMessagePos ();
			nX = (short) (pos & 0xFFFF);
			nY = (short) (pos >> 16);
		}
		/*
		* Feature in Windows.  It is legal use TrackPopupMenu()
		* to display an empty menu as long as menu items are added
		* inside of WM_INITPOPUPMENU.  If no items are added, then
		* TrackPopupMenu() fails and does not send an indication
		* that the menu has been closed.  This is not strictly a
		* bug but leads to unwanted behavior when application code
		* assumes that every WM_INITPOPUPMENU will eventually result
		* in a WM_MENUSELECT, wParam=0xFFFF0000, lParam=0 to indicate
		* that the menu has been closed.  The fix is to detect the
		* case when TrackPopupMenu() fails and the number of items in
		* the menu is zero and issue a fake WM_MENUSELECT.
		*-/
		boolean success = OS.TrackPopupMenu (handle, flags, nX, nY, 0, hwndParent, null);
		if (!success && GetMenuItemCount (handle) == 0) {
			OS.SendMessage (hwndParent, OS.WM_MENUSELECT, 0xFFFF0000, 0);
		}
	} else {
		OS.SendMessage (hwndParent, OS.WM_CANCELMODE, 0, 0);
	}
	*/
}

/**
 * Adds the listener to the collection of listeners who will
 * be notified when help events are generated for the control,
 * by sending it one of the messages defined in the
 * <code>HelpListener</code> interface.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see HelpListener
 * @see #removeHelpListener
 */
public void addHelpListener (HelpListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Help, typedListener);
}

/**
 * Adds the listener to the collection of listeners who will
 * be notified when menus are hidden or shown, by sending it
 * one of the messages defined in the <code>MenuListener</code>
 * interface.
 *
 * @param listener the listener which should be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see MenuListener
 * @see #removeMenuListener
 */
public void addMenuListener (MenuListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Hide,typedListener);
	addListener (SWT.Show,typedListener);
}

static Control checkNull (Control control) {
	if (control == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	return control;
}

static Menu checkNull (Menu menu) {
	if (menu == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	return menu;
}

static MenuItem checkNull (MenuItem item) {
	if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	return item;
}

static int checkStyle (int style) {
	return checkBits (style, SWT.POP_UP, SWT.BAR, SWT.DROP_DOWN, 0, 0, 0);
}

int nextMenuItemIndex (int dir) {
	int index = currentIndex;
	MenuItem[] menuItems = items;
	int tested = 0;
	int length = menuItems.length;
	if (index == -1) {
		index = dir < 0 ? length - 1 : 0;
		while (tested < length && 
				(menuItems[index].style & SWT.SEPARATOR) != 0) {
			tested++;
			index += dir;
		}
		return index;
	} else {
		index += dir;
		if (index == -1 || index == length) {
			index = dir < 0 ? length - 1 : 0;
		}
		while (tested < length &&
				(menuItems[index].style & SWT.SEPARATOR) != 0) {
			tested++;
			index += dir;
		}
	}
	if (index == length) {
		index = -1;
	}
	return index;
}
void createHandle () {
	items = new MenuItem[0];
	currentIndex = -1;
	lastFocusdTime = -1;
	
	if (handle != null) return;
	handle = document.createElement("DIV");
	if ((style & SWT.BAR) != 0) {
		handle.className = "menu-bar";
		OS.addCSSClass(parent.handle, "shell-menu-bar");
		int top = 3;
		if (parent.titleBar != null) {
			top = 3 + OS.getContainerHeight(parent.titleBar);
		}
		handle.style.top = top + "px";
		parent.handle.appendChild(handle);
		parent.shellMenuBar = handle;
	} else {
		document.body.appendChild(handle);
		handle.className = "menu-default";
		boolean supportShadow = false;
		/**
		 * @j2sNative
		 * supportShadow = window["swt.disable.shadow"] != true;
		 */ {}
		if (supportShadow) {
			Decorations.createNarrowShadowHandles(handle);
		}
	}
	
	btnFocus = document.createElement("BUTTON");
	//btnFocus.type = "BUTTON";
	btnFocus.className = "menu-focus";
	handle.appendChild(btnFocus);
	hMenuKeyDown = new RunnableCompatibility() {
		public void run() {
			HTMLEvent evt = (HTMLEvent) getEvent();
			MenuItem[] menuItems = items;
			int index = currentIndex;
			if (evt.keyCode == 13 || evt.keyCode == 10) {
				if (index != -1) {
					MenuItem i = menuItems[index];
					Element target = menuItems[index].handle;
					if (i.isEnabled())
					/**
					 * @j2sNative
					 * try {
					 * 	target.click ();
					 * } catch (e) {
					 * 	try {
					 * 		var clickEvent = document.createEvent("MouseEvents");
					 * 		clickEvent.initEvent("click", true, true);
					 * 		target.dispatchEvent(clickEvent);
					 * 	} catch (e) {
					 * 	}
					 * }
					 */ { target.toString(); }
				}
			} else if (evt.keyCode == 38 || evt.keyCode == 104) { // up
				if (index == -1) {
					index = nextMenuItemIndex(-1);
					MenuItem i = menuItems[index];
					/**
					 * @j2sNative
					 * i.hItemMouseEnter ();
					 */ { i.toString(); }
				} else {
					MenuItem i = menuItems[index];
					index = nextMenuItemIndex(-1);
					MenuItem i1 = menuItems[index];
					/**
					 * @j2sNative
					 * i.hItemMouseExit ();
					 * i1.hItemMouseEnter ();
					 */ { i.toString(); i1.toString(); }
				} 
			} else if (evt.keyCode == 40 || evt.keyCode == 98) { // down
				if (index == -1) {
					index = nextMenuItemIndex(1);
					MenuItem i = menuItems[index];
					/**
					 * @j2sNative
					 * i.hItemMouseEnter ();
					 */ { i.toString(); }
				} else {
					MenuItem i = menuItems[index];
					index = nextMenuItemIndex(1);
					MenuItem i1 = menuItems[index];
					/**
					 * @j2sNative
					 * i.hItemMouseExit ();
					 * i1.hItemMouseEnter ();
					 */ { i.toString(); i1.toString(); }
				}
			} else if (evt.keyCode == 37 || evt.keyCode == 100) { // left
				if ((style & SWT.BAR) != 0) {
					if (index == -1) {
						index = nextMenuItemIndex(-1);
						MenuItem i = menuItems[index];
						/**
						 * @j2sNative
						 * i.hItemMouseEnter ();
						 */ { i.toString(); }
					} else {
						MenuItem i = menuItems[index];
						index = nextMenuItemIndex(-1);
						MenuItem i1 = menuItems[index];
						/**
						 * @j2sNative
						 * i.hItemMouseExit ();
						 * i1.hItemMouseEnter ();
						 */ { i.toString(); i1.toString(); }
					} 
				}
			} else if (evt.keyCode == 39 || evt.keyCode == 102) { // up
				if ((style & SWT.BAR) != 0) {
					if (index == -1) {
						index = nextMenuItemIndex(1);
						MenuItem i = menuItems[index];
						/**
						 * @j2sNative
						 * i.hItemMouseEnter ();
						 */ { i.toString(); }
					} else {
						MenuItem i = menuItems[index];
						index = nextMenuItemIndex(1);
						MenuItem i1 = menuItems[index];
						/**
						 * @j2sNative
						 * i.hItemMouseExit ();
						 * i1.hItemMouseEnter ();
						 */ { i.toString(); i1.toString(); }
					}
				}
			} else {
				for (int i = 0; i < menuItems.length; i++) {
					if (menuItems[i] != null && menuItems[i].mnemonicChar == evt.keyCode) {
						Element target = (Element) menuItems[i].handle;
						if (menuItems[i].isEnabled())
						/**
						 * @j2sNative
						 * try {
						 * 	target.click ();
						 * } catch (e) {
						 * 	try {
						 * 		var clickEvent = document.createEvent("MouseEvents");
						 * 		clickEvent.initEvent("click", true, true);
						 * 		target.dispatchEvent(clickEvent);
						 * 	} catch (e) {
						 * 	}
						 * }
						 */ { target.toString(); }
						break;
					}
				}
			}
			currentIndex = index;
		}
	};
	Clazz.addEvent(btnFocus, "keydown", hMenuKeyDown);
	
	hMenuBlur = new RunnableCompatibility() {
		public void run() {
			long time = new Date().getTime();
			if (time - lastFocusdTime > 20) {
				if ((style & SWT.BAR) == 0) {
					handle.style.display = "none";
					sendEvent(SWT.Hide);
				} else {
					//OS.removeCSSClass(handle, "menu-bar-selected");
				}
			}
		}
	};
	Clazz.addEvent(btnFocus, "blur", hMenuBlur);
	
	hMenuFocus = new RunnableCompatibility() {
		public void run() {
			lastFocusdTime = new Date().getTime();
		}
	};
	Clazz.addEvent(btnFocus, "focus", hMenuFocus);
	
	hMenuMouseDown = new RunnableCompatibility() {
		public void run() {
			lastFocusdTime = new Date().getTime();
		}
	};
	Clazz.addEvent(handle, "mousedown", hMenuMouseDown);
	
	if ((style & SWT.BAR) != 0) {
		/*
		if (OS.IsPPC) {
			int hwndShell = parent.handle;
			SHMENUBARINFO mbi = new SHMENUBARINFO ();
			mbi.cbSize = SHMENUBARINFO.sizeof;
			mbi.hwndParent = hwndShell;
			mbi.dwFlags = OS.SHCMBF_HIDDEN;
			mbi.nToolBarId = ID_PPC;
			mbi.hInstRes = OS.GetLibraryHandle ();
			boolean success = OS.SHCreateMenuBar (mbi);
			hwndCB = mbi.hwndMB;
			if (!success) error (SWT.ERROR_NO_HANDLES);
			/* Remove the item from the resource file *-/
			OS.SendMessage (hwndCB, OS.TB_DELETEBUTTON, 0, 0);
			return;
		}
		/*
		* Note in WinCE SmartPhone.  The SoftBar contains only 2 items.
		* An item can either be a menu or a button. 
		* SWT.BAR: creates a SoftBar with 2 menus
		* SWT.BAR | SWT.BUTTON1: creates a SoftBar with 1 button
		*    for button1, and a menu for button2
		* SWT.BAR | SWT.BUTTON1 | SWT.BUTTON2: creates a SoftBar with
		*    2 buttons
		*-/
		if (OS.IsSP) {
			/* Determine type of menubar *-/
			int nToolBarId;
			if ((style & SWT.BUTTON1) != 0) {
				nToolBarId = ((style & SWT.BUTTON2) != 0) ? ID_SPBB : ID_SPBM;
			} else {
				nToolBarId = ((style & SWT.BUTTON2) != 0) ? ID_SPMB : ID_SPMM;
			}
			
			/* Create SHMENUBAR *-/
			SHMENUBARINFO mbi = new SHMENUBARINFO ();
			mbi.cbSize = SHMENUBARINFO.sizeof;
			mbi.hwndParent = parent.handle;
			mbi.dwFlags = OS.SHCMBF_HIDDEN;
			mbi.nToolBarId = nToolBarId; /* as defined in .rc file *-/
			mbi.hInstRes = OS.GetLibraryHandle ();
			if (!OS.SHCreateMenuBar (mbi)) error (SWT.ERROR_NO_HANDLES);
			hwndCB = mbi.hwndMB;
			
			/*
			* Feature on WinCE SmartPhone.  The SHCMBF_HIDDEN flag causes the
			* SHMENUBAR to not be drawn. However the keyboard events still go
			* through it.  The workaround is to also hide the SHMENUBAR with
			* ShowWindow ().
			*-/
			OS.ShowWindow (hwndCB, OS.SW_HIDE);
			
			TBBUTTONINFO info = new TBBUTTONINFO ();
			info.cbSize = TBBUTTONINFO.sizeof;
			info.dwMask = OS.TBIF_COMMAND;
			MenuItem item;
			
			/* Set first item *-/
			if (nToolBarId == ID_SPMM || nToolBarId == ID_SPMB) {
				int hMenu = OS.SendMessage (hwndCB, OS.SHCMBM_GETSUBMENU, 0, ID_SPSOFTKEY0);
				/* Remove the item from the resource file *-/
				OS.RemoveMenu (hMenu, 0, OS.MF_BYPOSITION);
				Menu menu = new Menu (parent, SWT.DROP_DOWN, hMenu);
				item = new MenuItem (this, menu, SWT.CASCADE, 0);
			} else {
				item = new MenuItem (this, null, SWT.PUSH, 0);
			}
			info.idCommand = id0 = item.id;
			OS.SendMessage (hwndCB, OS.TB_SETBUTTONINFO, ID_SPSOFTKEY0, info);	

			/* Set second item *-/
			if (nToolBarId == ID_SPMM || nToolBarId == ID_SPBM) {
				int hMenu = OS.SendMessage (hwndCB, OS.SHCMBM_GETSUBMENU, 0, ID_SPSOFTKEY1);
				OS.RemoveMenu (hMenu, 0, OS.MF_BYPOSITION);
				Menu menu = new Menu (parent, SWT.DROP_DOWN, hMenu);
				item = new MenuItem (this, menu, SWT.CASCADE, 1);
			} else {
				item = new MenuItem (this, null, SWT.PUSH, 1);
			}
			info.idCommand = id1 = item.id;
			OS.SendMessage (hwndCB, OS.TB_SETBUTTONINFO, ID_SPSOFTKEY1, info);

			/*
			* Override the Back key.  For some reason, the owner of the menubar
			* must be a Dialog or it won't receive the WM_HOTKEY message.  As
			* a result, Shell on WinCE SP must use the class Dialog.
			*-/
			int dwMask = OS.SHMBOF_NODEFAULT | OS.SHMBOF_NOTIFY;
			int lParam = dwMask << 16 | dwMask;
			OS.SendMessage (hwndCB, OS.SHCMBM_OVERRIDEKEY, OS.VK_ESCAPE, lParam);
			return;
		}
		handle = OS.CreateMenu ();
		if (handle == 0) error (SWT.ERROR_NO_HANDLES);
		if (OS.IsHPC) {
			int hwndShell = parent.handle;
			hwndCB = OS.CommandBar_Create (OS.GetModuleHandle (null), hwndShell, 1);
			if (hwndCB == 0) error (SWT.ERROR_NO_HANDLES);
			OS.CommandBar_Show (hwndCB, false);
			OS.CommandBar_InsertMenubarEx (hwndCB, 0, handle, 0);
			/*
			* The command bar hosts the 'close' button when the window does not
			* have a caption.
			*-/
			if ((parent.style & SWT.CLOSE) != 0 && (parent.style & SWT.TITLE) == 0) {
				OS.CommandBar_AddAdornments (hwndCB, 0, 0);
			}
		}
		*/
	} else {
		//handle = OS.CreatePopupMenu ();
		if (handle == null) error (SWT.ERROR_NO_HANDLES);
	}
}

void createItem (MenuItem item, int index) {
	int count = items.length; //GetMenuItemCount (handle);
	if (!(0 <= index && index <= count)) error (SWT.ERROR_INVALID_RANGE);
	for (int i = 0; i < items.length; i++) {
		if (items[i] == item) {
			return;
		}
	}
	items[items.length] = item;
	display.addMenuItem (item);
	item.handle = document.createElement("DIV");
	item.handle.className = ((style & SWT.BAR) != 0) ? "menu-bar-item" : "menu-item";
	handle.appendChild(item.handle);
	
	if ((item.style & SWT.SEPARATOR) == 0) {
		if ((item.style & (SWT.CHECK | SWT.RADIO)) != 0) {
			OS.addCSSClass(handle, "menu-enable-status");
		}
		if ((style & SWT.BAR) == 0) {
			Element el = document.createElement("DIV");
			el.className = "menu-item-status";
			item.handle.appendChild(el);
			item.statusEl = el;
			el = document.createElement("DIV");
			el.className = "menu-item-image";
			item.handle.appendChild(el);
			item.imageEl = el;
			el = document.createElement("DIV");
			el.className = "menu-item-text";
			item.handle.appendChild(el);
			item.textEl = el;
			el = document.createElement("DIV");
			el.className = "menu-item-arrow";
			item.handle.appendChild(el);
			item.arrowEl = el;
			if ((item.style & SWT.CASCADE) != 0) {
				el = document.createElement("DIV");
				el.className = "menu-item-arrow-right";
				item.arrowEl.appendChild(el);
			}
		}
	} else {
		item.handle.className += " menu-item-seperator";
	}
	/*
	boolean success = false;
	if ((OS.IsPPC || OS.IsSP) && hwndCB != 0) {
		if (OS.IsSP) return;
		TBBUTTON lpButton = new TBBUTTON ();
		lpButton.idCommand = item.id;
		lpButton.fsStyle = (byte) OS.TBSTYLE_AUTOSIZE;
		if ((item.style & SWT.CASCADE) != 0) lpButton.fsStyle |= OS.TBSTYLE_DROPDOWN | 0x80;
		if ((item.style & SWT.SEPARATOR) != 0) lpButton.fsStyle = (byte) OS.BTNS_SEP;
		lpButton.fsState = (byte) OS.TBSTATE_ENABLED;
		lpButton.iBitmap = OS.I_IMAGENONE;
		success = OS.SendMessage (hwndCB, OS.TB_INSERTBUTTON, index, lpButton) != 0;
	} else {
		if (OS.IsWinCE) {
			int uFlags = OS.MF_BYPOSITION;
			TCHAR lpNewItem = null;
			if ((item.style & SWT.SEPARATOR) != 0) {
				uFlags |= OS.MF_SEPARATOR;
			} else {
				lpNewItem = new TCHAR (0, " ", true);
			}
			success = OS.InsertMenu (handle, index, uFlags, item.id, lpNewItem);
			if (success) {
				MENUITEMINFO info = new MENUITEMINFO ();
				info.cbSize = MENUITEMINFO.sizeof;
				info.fMask = OS.MIIM_DATA;
				info.dwItemData = item.id;
				success = OS.SetMenuItemInfo (handle, index, true, info);
			}
		} else {
			/*
			* Bug in Windows.  For some reason, when InsertMenuItem()
			* is used to insert an item without text, it is not possible
			* to use SetMenuItemInfo() to set the text at a later time.
			* The fix is to insert the item with some text.
			* 
			* Feature in Windows.  When an empty string is used instead
			* of a space and InsertMenuItem() is used to set a submenu
			* before setting text to a non-empty string, the menu item
			* becomes unexpectedly disabled.  The fix is to insert a
			* space.
			*-/
			int hHeap = OS.GetProcessHeap ();
			TCHAR buffer = new TCHAR (0, " ", true);
			int byteCount = buffer.length () * TCHAR.sizeof;
			int pszText = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
			OS.MoveMemory (pszText, buffer, byteCount);	
			MENUITEMINFO info = new MENUITEMINFO ();
			info.cbSize = MENUITEMINFO.sizeof;
			info.fMask = OS.MIIM_ID | OS.MIIM_TYPE | OS.MIIM_DATA;
			info.wID = info.dwItemData = item.id;
			info.fType = item.widgetStyle ();
			info.dwTypeData = pszText;
			success = OS.InsertMenuItem (handle, index, true, info);
			if (pszText != 0) OS.HeapFree (hHeap, 0, pszText);
		}
	}
	if (!success) {
		display.removeMenuItem (item);
		error (SWT.ERROR_ITEM_NOT_ADDED);
	}
	*/
	redraw ();
}
	
void createWidget () {
	/*
	* Bug in IBM JVM 1.3.1.  For some reason, when the following code is called
	* from this method, the JVM issues this error:
	*
	* JVM Exception 0x2 (subcode 0x0) occurred in thread "main" (TID:0x9F19D8)
	* 
	* In addition, on Windows XP, a dialog appears with following error message,
	* indicating that the problem may be in the JIT:
	* 
	* AppName: java.exe	 AppVer: 0.0.0.0	 ModName: jitc.dll
	* ModVer: 0.0.0.0	 Offset: 000b6912
	* 
	* The fix is to move the code to the caller of this method.
	*/
//	checkOrientation (parent);
	createHandle ();
	parent.addMenu (this );
}

/*
* Currently not used.
*-/
int defaultBackground () {
	return OS.GetSysColor (OS.COLOR_MENU);
}
/*
* Currently not used.
*-/
int defaultForeground () {
	return OS.GetSysColor (OS.COLOR_MENUTEXT);
}
*/

void destroyAccelerators () {
	parent.destroyAccelerators ();
}

void registerAccelerator(int accelerator, MenuItem item){
	if(acceleratorTable == null){
		acceleratorTable = new Object[0];
	}
	int size = acceleratorTable.length;
	acceleratorTable[size] = new Integer(accelerator);
	acceleratorTable[size+1] = item;
}

boolean isAccelerated(HTMLEvent keyEvent){
	int size = acceleratorTable.length;
	for(int i = 0; i < size; i+=2){
		int acclCode = ((Integer) acceleratorTable[i]).intValue();
		if(
				(((acclCode & SWT.CONTROL) != 0 && keyEvent.ctrlKey) || ((acclCode & SWT.CONTROL) == 0 )) && 
				(((acclCode & SWT.ALT) != 0 && keyEvent.altKey) || ((acclCode & SWT.ALT) == 0)) &&
				((acclCode & SWT.SHIFT) != 0 && keyEvent.shiftKey) || ((acclCode & SWT.SHIFT) == 0)
				) {
			acclCode &= ~(SWT.ALT | SWT.SHIFT | SWT.CONTROL);
			if(acclCode == keyEvent.keyCode){				
				MenuItem item = (MenuItem) acceleratorTable[i+1];
				/**
				 * @j2sNative
				 * try {
				 * 	item.handle.click ();
				 * } catch (e) {
				 * 	try {
				 * 		var clickEvent = document.createEvent("MouseEvents");
				 * 		clickEvent.initEvent("click", true, true);
				 * 		item.handle.dispatchEvent(clickEvent);
				 * 	} catch (e) {
				 * 	}
				 * }
				 */ { item.toString(); }
			}
		}
	}
	return false;
}

void destroyItem (MenuItem item) {
	/*
	if (OS.IsWinCE) {
		if ((OS.IsPPC || OS.IsSP) && hwndCB != 0) {
			if (OS.IsSP) {
				redraw();
				return;
			}
			int index = OS.SendMessage (hwndCB, OS.TB_COMMANDTOINDEX, item.id, 0);
			if (OS.SendMessage (hwndCB, OS.TB_DELETEBUTTON, index, 0) == 0) {
				error (SWT.ERROR_ITEM_NOT_REMOVED);
			}
			int count = OS.SendMessage (hwndCB, OS.TB_BUTTONCOUNT, 0, 0);
			if (count == 0) {
				if (imageList != null) {
					OS.SendMessage (handle, OS.TB_SETIMAGELIST, 0, 0);
					display.releaseImageList (imageList);
					imageList = null;
				}
			}
		} else {
			int index = 0;
			MENUITEMINFO info = new MENUITEMINFO ();
			info.cbSize = MENUITEMINFO.sizeof;
			info.fMask = OS.MIIM_DATA;
			while (OS.GetMenuItemInfo (handle, index, true, info)) {
				if (info.dwItemData == item.id) break;
				index++;
			}
			if (info.dwItemData != item.id) {
				error (SWT.ERROR_ITEM_NOT_REMOVED);
			}	
			if (!OS.RemoveMenu (handle, index, OS.MF_BYPOSITION)) {
				error (SWT.ERROR_ITEM_NOT_REMOVED);
			}
		}
	} else {
		if (!OS.RemoveMenu (handle, item.id, OS.MF_BYCOMMAND)) {
			error (SWT.ERROR_ITEM_NOT_REMOVED);
		}
	}
	*/
	redraw ();
}

void destroyWidget () {
//	int hMenu = handle, hCB = hwndCB;
	releaseHandle ();
	/*
	if (OS.IsWinCE && hCB != 0) {
		OS.CommandBar_Destroy (hCB);
	} else {
		if (hMenu != 0) OS.DestroyMenu (hMenu);
	}
	*/
	if (handle != null) {
		OS.destroyHandle(handle);
		handle = null;
	}
}

void fixMenus (Decorations newParent) {
	MenuItem [] items = getItems ();
	for (int i=0; i<items.length; i++) {
		items [i].fixMenus (newParent);
	}
	parent.removeMenu (this );
	newParent.addMenu (this );
	this .parent = newParent;
}

/**
 * Returns a rectangle describing the receiver's size and location
 * relative to its parent (or its display if its parent is null),
 * unless the receiver is a menu or a shell. In this case, the
 * location is relative to the display.
 * <p>
 * Note that the bounds of a menu or menu item are undefined when
 * the menu is not visible.  This is because most platforms compute
 * the bounds of a menu dynamically just before it is displayed.
 * </p>
 *
 * @return the receiver's bounding rectangle
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 3.1
 */
/*public*/ Rectangle getBounds () {
	checkWidget ();
	//if (OS.IsWinCE) return new Rectangle (0, 0, 0, 0);
	if ((style & SWT.BAR) != 0) {
		if (parent.menuBar != this ) {
			return new Rectangle (0, 0, 0, 0);
		}
		/*
		int hwndShell = parent.handle;
		MENUBARINFO info = new MENUBARINFO ();
		info.cbSize = MENUBARINFO.sizeof;
		if (OS.GetMenuBarInfo (hwndShell, OS.OBJID_MENU, 0, info)) {
			int width = info.right - info.left;
			int height = info.bottom - info.top;
			return new Rectangle (info.left, info.top, width, height);
		}
		*/
		// TODO: SWT.BAR
	} else {
		int count = items.length; //GetMenuItemCount (handle);
		if (count != 0) {
			/*
			RECT rect1 = new RECT ();
			if (OS.GetMenuItemRect (0, handle, 0, rect1)) {
				RECT rect2 = new RECT ();
				if (OS.GetMenuItemRect (0, handle, count - 1, rect2)) {
					int x = rect1.left - 2, y = rect1.top - 2;
					int width = (rect2.right - rect2.left) + 4;
					int height = (rect2.bottom - rect1.top) + 4;
					return new Rectangle (x, y, width, height);
				}
			}
			*/
			int x, y, w, h;
			Element hdl1 = items[0].handle;
			Point pt1 = OS.calcuateRelativePosition(hdl1, document.body);
			x = pt1.x;
			y = pt1.y;
			
			int textWidth = 0;
			int accelWidth = 0;
			for (int i = 0; i < count; i++) {
				String text = items[i].text;
				if (text == null) {
					continue;
				}
				int idx = text.indexOf('\t');
				String normalText = text;
				String accelText = null;
				if (idx != -1) {
					normalText = text.substring(0, idx);
					accelText = text.substring(idx + 1);
				}
				if (accelText != null && accelText.length() != 0) {
					int width = OS.getStringStyledWidth(accelText, "menu-item-text", null);
					if (width > accelWidth) {
						accelWidth = width;
					}
				}
				int width = OS.getStringStyledWidth(normalText, "menu-item-text", null);
				if (width > textWidth) {
					textWidth = width;
				}
			}
			w = 16 + textWidth + 16 + accelWidth + 16 + 8; // 8 for extra safe width
			if (handle.className.indexOf("menu-enable-status") != -1 &&
					handle.className.indexOf("menu-enable-image") != -1) {
				w += 16;
			}
			if (count == 1) {
				//w = OS.getContainerWidth(hdl1);
				h = OS.getContainerHeight(hdl1);
			} else {
				Element hdl2 = items[count - 1].handle;
				Point pt2 = OS.calcuateRelativePosition(hdl2, document.body);
				//w = OS.getContainerWidth(hdl2);
				h = pt2.y - pt1.y + OS.getContainerHeight(hdl2);
			}
			return new Rectangle(x - 2, y - 2, w + 4, h + 4);
		}
	}
	return new Rectangle (0, 0, 0, 0);
}

/**
 * Returns the default menu item or null if none has
 * been previously set.
 *
 * @return the default menu item.
 *
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public MenuItem getDefaultItem () {
	checkWidget ();
	/*
	if (OS.IsWinCE) return null;
	int id = OS.GetMenuDefaultItem (handle, OS.MF_BYCOMMAND, OS.GMDI_USEDISABLED);
	if (id == -1) return null;
	MENUITEMINFO info = new MENUITEMINFO ();
	info.cbSize = MENUITEMINFO.sizeof;
	info.fMask = OS.MIIM_ID;
	if (OS.GetMenuItemInfo (handle, id, false, info)) {
		return display.getMenuItem (info.wID);
	}
	*/
	return defaultItem;
}

/**
 * Returns <code>true</code> if the receiver is enabled, and
 * <code>false</code> otherwise. A disabled menu is typically
 * not selectable from the user interface and draws with an
 * inactive or "grayed" look.
 *
 * @return the receiver's enabled state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #isEnabled
 */
public boolean getEnabled () {
	checkWidget ();
	return (state & DISABLED) == 0;
}

/**
 * Returns the item at the given, zero-relative index in the
 * receiver. Throws an exception if the index is out of range.
 *
 * @param index the index of the item to return
 * @return the item at the given index
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public MenuItem getItem (int index) {
	checkWidget ();
	/*
	int id = 0;
	if ((OS.IsPPC || OS.IsSP) && hwndCB != 0) {
		if (OS.IsPPC) {
			TBBUTTON lpButton = new TBBUTTON ();
			int result = OS.SendMessage (hwndCB, OS.TB_GETBUTTON, index, lpButton);
			if (result == 0) error (SWT.ERROR_CANNOT_GET_ITEM);
			id = lpButton.idCommand;
		}
		if (OS.IsSP) {
			if (!(0 <= index && index <= 1)) error (SWT.ERROR_CANNOT_GET_ITEM);
			id = index == 0 ? id0 : id1;
		}
	} else {
		MENUITEMINFO info = new MENUITEMINFO ();
		info.cbSize = MENUITEMINFO.sizeof;
		info.fMask = OS.MIIM_DATA;
		if (!OS.GetMenuItemInfo (handle, index, true, info)) {
			error (SWT.ERROR_INVALID_RANGE);
		}
		id = info.dwItemData;
	}
	return display.getMenuItem (id);
	*/
	if (!(0 <= index && index <= items.length - 1)) error (SWT.ERROR_CANNOT_GET_ITEM);
	return items[index];
}

/**
 * Returns the number of items contained in the receiver.
 *
 * @return the number of items
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int getItemCount () {
	checkWidget ();
	//return GetMenuItemCount (handle);
	return items.length;
}

/**
 * Returns a (possibly empty) array of <code>MenuItem</code>s which
 * are the items in the receiver. 
 * <p>
 * Note: This is not the actual structure used by the receiver
 * to maintain its list of items, so modifying the array will
 * not affect the receiver. 
 * </p>
 *
 * @return the items in the receiver
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public MenuItem [] getItems () {
	checkWidget ();
	/*
	if ((OS.IsPPC || OS.IsSP) && hwndCB != 0) {
		if (OS.IsSP) {
			MenuItem [] result = new MenuItem [2];
			result[0] = display.getMenuItem (id0);
			result[1] = display.getMenuItem (id1);
			return result;
		}
		int count = OS.SendMessage (hwndCB, OS.TB_BUTTONCOUNT, 0, 0);
		TBBUTTON lpButton = new TBBUTTON ();
		MenuItem [] result = new MenuItem [count];
		for (int i=0; i<count; i++) {
			OS.SendMessage (hwndCB, OS.TB_GETBUTTON, i, lpButton);
			result [i] = display.getMenuItem (lpButton.idCommand);
		}
		return result;
	}
	int count = 0;
	int length = OS.IsWinCE ? 4 : OS.GetMenuItemCount (handle);
	MenuItem [] items = new MenuItem [length];
	MENUITEMINFO info = new MENUITEMINFO ();
	info.cbSize = MENUITEMINFO.sizeof;
	info.fMask = OS.MIIM_DATA;
	while (OS.GetMenuItemInfo (handle, count, true, info)) {
		if (count == items.length) {
			MenuItem [] newItems = new MenuItem [count + 4];
			System.arraycopy (items, 0, newItems, 0, count);
			items = newItems;
		}
		items [count++] = display.getMenuItem (info.dwItemData);
	}
	if (count == items.length) return items;
	*/
	int count = items.length;
	MenuItem [] result = new MenuItem [count];
	System.arraycopy (items, 0, result, 0, count);
	return result;
}

/*
int GetMenuItemCount (Element handle) {
	if (OS.IsWinCE) {
		if ((OS.IsPPC || OS.IsSP) && hwndCB != 0) {
			return OS.IsSP ? 2 : OS.SendMessage (hwndCB, OS.TB_BUTTONCOUNT, 0, 0);
		}
		int count = 0;
		MENUITEMINFO info = new MENUITEMINFO ();
		info.cbSize = MENUITEMINFO.sizeof;
		while (OS.GetMenuItemInfo (handle, count, true, info)) count++;
		return count;
	}
	return OS.GetMenuItemCount (handle);
}
*/

String getNameText () {
	String result = "";
	MenuItem [] items = getItems ();
	int length = items.length;
	if (length > 0) {
		for (int i=0; i<length-1; i++) {
			result = result + items [i].getNameText() + ", ";
		}
		result = result + items [length-1].getNameText ();
	}
	return result;
}

/**
 * Returns the receiver's parent, which must be a <code>Decorations</code>.
 *
 * @return the receiver's parent
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public Decorations getParent () {
	checkWidget ();
	return parent;
}

/**
 * Returns the receiver's parent item, which must be a
 * <code>MenuItem</code> or null when the receiver is a
 * root.
 *
 * @return the receiver's parent item
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public MenuItem getParentItem () {
	checkWidget ();
	return cascade;
}

/**
 * Returns the receiver's parent item, which must be a
 * <code>Menu</code> or null when the receiver is a
 * root.
 *
 * @return the receiver's parent item
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public Menu getParentMenu () {
	checkWidget ();
	if (cascade != null) return cascade.parent;
	return null;
}

/**
 * Returns the receiver's shell. For all controls other than
 * shells, this simply returns the control's nearest ancestor
 * shell. Shells return themselves, even if they are children
 * of other shells.
 *
 * @return the receiver's shell
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see #getParent
 */
public Shell getShell () {
	checkWidget ();
	return parent.getShell ();
}

/**
 * Returns <code>true</code> if the receiver is visible, and
 * <code>false</code> otherwise.
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, this method
 * may still indicate that it is considered visible even though
 * it may not actually be showing.
 * </p>
 *
 * @return the receiver's visibility state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public boolean getVisible () {
	checkWidget ();
	if ((style & SWT.BAR) != 0) {
		return this  == parent.menuShell ().menuBar;
	}
	if ((style & SWT.POP_UP) != 0) {
		Menu [] popups = display.popups;
		if (popups == null) return false;
		for (int i=0; i<popups.length; i++) {
			if (popups [i] == this ) return true;
		}
	}
	Shell shell = getShell ();
	Menu menu = shell.activeMenu;
	while (menu != null && menu != this ) {
		menu = menu.getParentMenu ();
	}
	return this  == menu;
}

int imageIndex (Image image) {
	/*
	if (hwndCB == 0 || image == null) return OS.I_IMAGENONE;
	if (imageList == null) {
		int hOldList = OS.SendMessage (hwndCB, OS.TB_GETIMAGELIST, 0, 0);
		if (hOldList != 0) OS.ImageList_Destroy (hOldList);
		Rectangle bounds = image.getBounds ();
		imageList = display.getImageList (style & SWT.RIGHT_TO_LEFT, bounds.width, bounds.height);
		int hImageList = imageList.getHandle ();
		OS.SendMessage (hwndCB, OS.TB_SETIMAGELIST, 0, hImageList);
	}
	*/
	int index = imageList.indexOf (image);
	if (index == -1) {
		index = imageList.add (image);
	} else {
		imageList.put (index, image);
	}
	return index;
}

/**
 * Searches the receiver's list starting at the first item
 * (index 0) until an item is found that is equal to the 
 * argument, and returns the index of that item. If no item
 * is found, returns -1.
 *
 * @param item the search item
 * @return the index of the item
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public int indexOf (MenuItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
	if (item.parent != this ) return -1;
	/*
	if ((OS.IsPPC || OS.IsSP) && hwndCB != 0) {
		if (OS.IsPPC) {
			return OS.SendMessage (hwndCB, OS.TB_COMMANDTOINDEX, item.id, 0);
		}
		if (OS.IsSP) {
			if (item.id == id0) return 0;
			if (item.id == id1) return 1;
			return -1;
		}
	}
	int index = 0;
	MENUITEMINFO info = new MENUITEMINFO ();
	info.cbSize = MENUITEMINFO.sizeof;
	info.fMask = OS.MIIM_DATA;
	while (OS.GetMenuItemInfo (handle, index, true, info)) {
		if (info.dwItemData == item.id) return index;
		index++;
	}
	*/
	for (int i = 0; i < items.length; i++) {
		if (items[i] == item) {
			return i;
		}
	}
	return -1;
}

/**
 * Returns <code>true</code> if the receiver is enabled and all
 * of the receiver's ancestors are enabled, and <code>false</code>
 * otherwise. A disabled menu is typically not selectable from the
 * user interface and draws with an inactive or "grayed" look.
 *
 * @return the receiver's enabled state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @see #getEnabled
 */
public boolean isEnabled () {
	checkWidget ();
	Menu parentMenu = getParentMenu ();
	if (parentMenu == null) return getEnabled ();
	return getEnabled () && parentMenu.isEnabled ();
}

/**
 * Returns <code>true</code> if the receiver is visible and all
 * of the receiver's ancestors are visible and <code>false</code>
 * otherwise.
 *
 * @return the receiver's visibility state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see #getVisible
 */
public boolean isVisible () {
	checkWidget ();
	return getVisible ();
}

void redraw () {
	if (!isVisible ()) return;
	if ((style & SWT.BAR) != 0) {
		display.addBar (this );
	} else {
		update ();
	}
}

protected void releaseChild () {
	super .releaseChild ();
	if (cascade != null) cascade.releaseMenu ();
	if ((style & SWT.BAR) != 0) {
		display.removeBar (this );
		if (this  == parent.menuBar) {
			parent.setMenuBar (null);
		}
	} else {
		if ((style & SWT.POP_UP) != 0) {
			display.removePopup (this );
		}
	}
}

protected void releaseHandle () {
	if (btnFocus != null) {
		if (hMenuKeyDown != null) {
			Clazz.removeEvent(btnFocus, "keydown", hMenuKeyDown);
			hMenuKeyDown = null;
		}
		if (hMenuBlur != null) {
			Clazz.removeEvent(btnFocus, "blur", hMenuBlur);
			hMenuBlur = null;
		}
		if (hMenuFocus != null) {
			Clazz.removeEvent(btnFocus, "focus", hMenuFocus);
			hMenuFocus = null;
		}
		OS.destroyHandle(btnFocus);
		btnFocus = null;
	}
	if (handle != null) {
		if (hMenuMouseDown != null) {
			Clazz.removeEvent(handle, "mousedown", hMenuMouseDown);
			hMenuMouseDown = null;
		}
		OS.destroyHandle(handle);
		handle = null;
	}
	super .releaseHandle ();
//	handle = hwndCB = 0;
}

void releaseWidget () {
	//MenuItem [] items = getItems ();
	for (int i=0; i<items.length; i++) {
		MenuItem item = items [i];
		if (!item.isDisposed ()) {
			/*
			if (OS.IsPPC && hwndCB != 0) {
				item.dispose ();
			} else {
				item.releaseResources ();
			}
			*/
			item.releaseResources ();
		}
		items[i] = null;
	}
	items = new MenuItem[0];
	/*
	if (OS.IsPPC && hwndCB != 0) {
		if (imageList != null) {
			OS.SendMessage (hwndCB, OS.TB_SETIMAGELIST, 0, 0);
			display.releaseToolImageList (imageList);
			imageList = null;
		}
	}
	*/
	super .releaseWidget ();
	if (parent != null) parent.removeMenu (this );
	parent = null;
	cascade = null;
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when the help events are generated for the control.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see HelpListener
 * @see #addHelpListener
 */
public void removeHelpListener (HelpListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook (SWT.Help, listener);
}

/**
 * Removes the listener from the collection of listeners who will
 * be notified when the menu events are generated for the control.
 *
 * @param listener the listener which should no longer be notified
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 *
 * @see MenuListener
 * @see #addMenuListener
 */
public void removeMenuListener (MenuListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook (SWT.Hide, listener);
	eventTable.unhook (SWT.Show, listener);
}

/**
 * Sets the default menu item to the argument or removes
 * the default emphasis when the argument is <code>null</code>.
 * 
 * @param item the default menu item or null
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_INVALID_ARGUMENT - if the menu item has been disposed</li> 
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setDefaultItem (MenuItem item) {
	checkWidget ();
	defaultItem = item;
	/*
	int newID = -1;
	if (item != null) {
		if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
		if (item.parent != this) return;
		newID = item.id;
	}
	if (OS.IsWinCE) return;
	int oldID = OS.GetMenuDefaultItem (handle, OS.MF_BYCOMMAND, OS.GMDI_USEDISABLED);
	if (newID == oldID) return;
	OS.SetMenuDefaultItem (handle, newID, OS.MF_BYCOMMAND);
	*/
	redraw ();
}

/**
 * Enables the receiver if the argument is <code>true</code>,
 * and disables it otherwise. A disabled menu is typically
 * not selectable from the user interface and draws with an
 * inactive or "grayed" look.
 *
 * @param enabled the new enabled state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setEnabled (boolean enabled) {
	checkWidget ();
	state &= ~DISABLED;
	if (!enabled) state |= DISABLED;
}

/**
 * Sets the location of the receiver, which must be a popup,
 * to the point specified by the arguments which are relative
 * to the display.
 * <p>
 * Note that this is different from most widgets where the
 * location of the widget is relative to the parent.
 * </p><p>
 * Note that the platform window manager ultimately has control
 * over the location of popup menus.
 * </p>
 *
 * @param x the new x coordinate for the receiver
 * @param y the new y coordinate for the receiver
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setLocation (int x, int y) {
	checkWidget ();
	if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
	this .x = x;
	this .y = y;
	hasLocation = true;
}

/**
 * Sets the location of the receiver, which must be a popup,
 * to the point specified by the argument which is relative
 * to the display.
 * <p>
 * Note that this is different from most widgets where the
 * location of the widget is relative to the parent.
 * </p><p>
 * Note that the platform window manager ultimately has control
 * over the location of popup menus.
 * </p>
 *
 * @param location the new location for the receiver
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
 * </ul>
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 * 
 * @since 2.1
 */
public void setLocation (Point location) {
	checkWidget ();
	if (location == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
	setLocation (location.x, location.y);
}

/**
 * Marks the receiver as visible if the argument is <code>true</code>,
 * and marks it invisible otherwise. 
 * <p>
 * If one of the receiver's ancestors is not visible or some
 * other condition makes the receiver not visible, marking
 * it visible may not actually cause it to be displayed.
 * </p>
 *
 * @param visible the new visibility state
 *
 * @exception SWTException <ul>
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
 * </ul>
 */
public void setVisible (boolean visible) {
	checkWidget ();
	if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
	if (visible) {
		display.addPopup (this );
	} else {
		display.removePopup (this );
		_setVisible (false);
	}
}

void update () {
	/*
	if (OS.IsPPC || OS.IsSP) return;
	if (OS.IsHPC) {
		/*
		* Each time a menu has been modified, the command menu bar
		* must be redrawn or it won't update properly.  For example,
		* a submenu will not drop down.
		*-/
		Menu menuBar = parent.menuBar;
		if (menuBar != null) {
			Menu menu = this;
			while (menu != null && menu != menuBar) {
				menu = menu.getParentMenu ();
			}
			if (menu == menuBar) {
				OS.CommandBar_DrawMenuBar (menuBar.hwndCB, 0);
				OS.CommandBar_Show (menuBar.hwndCB, true);
			}
		}
		return;
	}
	if (OS.IsWinCE) return;
	if ((style & SWT.BAR) != 0) {
		if (this == parent.menuBar) OS.DrawMenuBar (parent.handle);
		return;
	}
	if (OS.WIN32_VERSION < OS.VERSION (4, 10)) {
		return;
	}
	*/
	boolean hasCheck = false, hasImage = false;
	MenuItem [] items = getItems ();
	for (int i=0; i<items.length; i++) {
		MenuItem item = items [i];
		if (item.image != null) {
			if ((hasImage = true) && hasCheck) break;
		}
		if ((item.style & (SWT.CHECK | SWT.RADIO)) != 0) {
			if ((hasCheck = true) && hasImage) break;
		}
	}
	
	/*
	* Bug in Windows.  If a menu contains items that have
	* images and can be checked, Windows does not include
	* the width of the image and the width of the check when
	* computing the width of the menu.  When the longest item
	* does not have an image, the label and the accelerator
	* text can overlap.  The fix is to use SetMenuItemInfo()
	* to indicate that all items have a bitmap and then include
	* the width of the widest bitmap in WM_MEASURECHILD.
	* 
	* NOTE:  This work around causes problems on Windows 98.
	* Under certain circumstances that have yet to be isolated,
	* some menus can become huge and blank.  For now, do not
	* run the code on Windows 98.
	*-/	
	if (!OS.IsWin95) {
		MENUITEMINFO info = new MENUITEMINFO ();
		info.cbSize = MENUITEMINFO.sizeof;
		info.fMask = OS.MIIM_BITMAP;
		for (int i=0; i<items.length; i++) {
			MenuItem item = items [i];
			if ((style & SWT.SEPARATOR) == 0) {
				if (item.image == null) {
					info.hbmpItem = hasImage ? OS.HBMMENU_CALLBACK : 0;
					OS.SetMenuItemInfo (handle, item.id, false, info);
				}
			}
		}
	}

	/* Update the menu to hide or show the space for bitmaps *-/
	MENUINFO lpcmi = new MENUINFO ();
	lpcmi.cbSize = MENUINFO.sizeof;
	lpcmi.fMask = OS.MIM_STYLE;
	OS.GetMenuInfo (handle, lpcmi);
	if (hasImage && !hasCheck) {
		lpcmi.dwStyle |= OS.MNS_CHECKORBMP;
	} else {
		lpcmi.dwStyle &= ~OS.MNS_CHECKORBMP;
	}
	OS.SetMenuInfo (handle, lpcmi);
	*/
}

}
w__w_w_._j___a___v_a2s._c___o_m__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.