/*******************************************************************************
 * Copyright (c) 2000, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.widgets;


import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;

/**
 * Instances of this class support the layout of selectable
 * tool bar items.
 * <p>
 * The item children that may be added to instances of this class
 * must be of type <code>ToolItem</code>.
 * </p><p>
 * Note that although this class is a subclass of <code>Composite</code>,
 * it does not make sense to add <code>Control</code> children to it,
 * or set a layout on it.
 * </p><p>
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>FLAT, WRAP, RIGHT, HORIZONTAL, VERTICAL, SHADOW_OUT</dd>
 * <dt><b>Events:</b></dt>
 * <dd>(none)</dd>
 * </dl>
 * <p>
 * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
 * </p><p>
 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
 * </p>
 *
 * @see <a href="http://www.eclipse.org/swt/snippets/#toolbar">ToolBar, ToolItem snippets</a>
 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample</a>
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
 * @noextend This class is not intended to be subclassed by clients.
 */
public class ToolBar extends Composite {
	int lastFocusId, lastArrowId, lastHotId;
	ToolItem [] items;
	ToolItem [] tabItemList;
	boolean ignoreResize, ignoreMouse;
	ImageList imageList, disabledImageList, hotImageList;
	static final long /*int*/ ToolBarProc;
	static final TCHAR ToolBarClass = new TCHAR (0, OS.TOOLBARCLASSNAME, true);
	static {
		WNDCLASS lpWndClass = new WNDCLASS ();
		OS.GetClassInfo (0, ToolBarClass, lpWndClass);
		ToolBarProc = lpWndClass.lpfnWndProc;
	}
	
	/*
	* From the Windows SDK for TB_SETBUTTONSIZE:
	*
	*   "If an application does not explicitly
	*	set the button size, the size defaults
	*	to 24 by 22 pixels". 
	*/
	static final int DEFAULT_WIDTH = 24;
	static final int DEFAULT_HEIGHT = 22;

/**
 * Constructs a new instance of this class given its parent
 * 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 composite control which will be the parent of the new instance (cannot be null)
 * @param style the style of control 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#FLAT
 * @see SWT#WRAP
 * @see SWT#RIGHT
 * @see SWT#HORIZONTAL
 * @see SWT#SHADOW_OUT
 * @see SWT#VERTICAL
 * @see Widget#checkSubclass()
 * @see Widget#getStyle()
 */
public ToolBar (Composite parent, int style) {
	super (parent, checkStyle (style));
	/*
	* Ensure that either of HORIZONTAL or VERTICAL is set.
	* NOTE: HORIZONTAL and VERTICAL have the same values
	* as H_SCROLL and V_SCROLL so it is necessary to first
	* clear these bits to avoid scroll bars and then reset
	* the bits using the original style supplied by the
	* programmer.
	* 
	* NOTE: The CCS_VERT style cannot be applied when the
	* widget is created because of this conflict.
	*/
	if ((style & SWT.VERTICAL) != 0) {
		this.style |= SWT.VERTICAL;
		int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
		/*
		* Feature in Windows.  When a tool bar has the style
		* TBSTYLE_LIST and has a drop down item, Window leaves
		* too much padding around the button.  This affects
		* every button in the tool bar and makes the preferred
		* height too big.  The fix is to set the TBSTYLE_LIST
		* when the tool bar contains both text and images.
		* 
		* NOTE: Tool bars with CCS_VERT must have TBSTYLE_LIST
		* set before any item is added or the tool bar does
		* not lay out properly.  The work around does not run
		* in this case.
		*/
		if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
			if ((style & SWT.RIGHT) != 0) bits |= OS.TBSTYLE_LIST;
		}
		OS.SetWindowLong (handle, OS.GWL_STYLE, bits | OS.CCS_VERT);
	} else {
		this.style |= SWT.HORIZONTAL;
	}
}

long /*int*/ callWindowProc (long /*int*/ hwnd, int msg, long /*int*/ wParam, long /*int*/ lParam) {
	if (handle == 0) return 0;
	/*
	* Bug in Windows.  For some reason, during the processing
	* of WM_SYSCHAR, the tool bar window proc does not call the
	* default window proc causing mnemonics for the menu bar
	* to be ignored.  The fix is to always call the default
	* window proc for WM_SYSCHAR.
	*/
	if (msg == OS.WM_SYSCHAR) {
		return OS.DefWindowProc (hwnd, msg, wParam, lParam);
	}
	return OS.CallWindowProc (ToolBarProc, hwnd, msg, wParam, lParam);
}

static int checkStyle (int style) {
	/*
	* On Windows, only flat tool bars can be traversed.
	*/
	if ((style & SWT.FLAT) == 0) style |= SWT.NO_FOCUS;
	
	/*
	* A vertical tool bar cannot wrap because TB_SETROWS
	* fails when the toolbar has TBSTYLE_WRAPABLE.
	*/
	if ((style & SWT.VERTICAL) != 0) style &= ~SWT.WRAP;
		
	/*
	* Even though it is legal to create this widget
	* with scroll bars, they serve no useful purpose
	* because they do not automatically scroll the
	* widget's client area.  The fix is to clear
	* the SWT style.
	*/
	return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
}

void checkBuffered () {
	super.checkBuffered ();
	if (OS.COMCTL32_MAJOR >= 6) style |= SWT.DOUBLE_BUFFERED;
}

protected void checkSubclass () {
	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
}

public Point computeSize (int wHint, int hHint, boolean changed) {
	checkWidget ();
	int width = 0, height = 0;
	if ((style & SWT.VERTICAL) != 0) {
		RECT rect = new RECT ();
		TBBUTTON lpButton = new TBBUTTON ();
		int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
		for (int i=0; i<count; i++) {
			OS.SendMessage (handle, OS.TB_GETITEMRECT, i, rect);
			height = Math.max (height, rect.bottom);
			OS.SendMessage (handle, OS.TB_GETBUTTON, i, lpButton);
			if ((lpButton.fsStyle & OS.BTNS_SEP) != 0) {
				TBBUTTONINFO info = new TBBUTTONINFO ();
				info.cbSize = TBBUTTONINFO.sizeof;
				info.dwMask = OS.TBIF_SIZE;
				OS.SendMessage (handle, OS.TB_GETBUTTONINFO, lpButton.idCommand, info);
				width = Math.max (width, info.cx);
			} else {
				width = Math.max (width, rect.right);
			}
		}
	} else {
		RECT oldRect = new RECT ();
		OS.GetWindowRect (handle, oldRect);
		int oldWidth = oldRect.right - oldRect.left;
		int oldHeight = oldRect.bottom - oldRect.top;
		int border = getBorderWidth ();
		int newWidth = wHint == SWT.DEFAULT ? 0x3FFF : wHint + border * 2;
		int newHeight = hHint == SWT.DEFAULT ? 0x3FFF : hHint + border * 2;
		boolean redraw = getDrawing () && OS.IsWindowVisible (handle);
		ignoreResize = true;
		if (redraw) OS.UpdateWindow (handle);
		int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOREDRAW | OS.SWP_NOZORDER;
		SetWindowPos (handle, 0, 0, 0, newWidth, newHeight, flags);
		int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
		if (count != 0) {
			RECT rect = new RECT ();
			OS.SendMessage (handle, OS.TB_GETITEMRECT, count - 1, rect);
			width = Math.max (width, rect.right);
			height = Math.max (height, rect.bottom);
		}
		SetWindowPos (handle, 0, 0, 0, oldWidth, oldHeight, flags);
		if (redraw) OS.ValidateRect (handle, null);
		ignoreResize = false;
	}
	
	/*
	* From the Windows SDK for TB_SETBUTTONSIZE:
	*
	*   "If an application does not explicitly
	*	set the button size, the size defaults
	*	to 24 by 22 pixels". 
	*/
	if (width == 0) width = DEFAULT_WIDTH;
	if (height == 0) height = DEFAULT_HEIGHT;
	if (wHint != SWT.DEFAULT) width = wHint;
	if (hHint != SWT.DEFAULT) height = hHint;
	Rectangle trim = computeTrim (0, 0, width, height);
	width = trim.width;  height = trim.height;
	return new Point (width, height);
}

public Rectangle computeTrim (int x, int y, int width, int height) {
	checkWidget ();
	Rectangle trim = super.computeTrim (x, y, width, height);
	int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
	if ((bits & OS.CCS_NODIVIDER) == 0) trim.height += 2;
	return trim;
}

Widget computeTabGroup () {
	ToolItem [] items = _getItems ();
	if (tabItemList == null) {
		int i = 0;
		while (i < items.length && items [i].control == null) i++;
		if (i == items.length) return super.computeTabGroup (); 
	}
	int index = (int)/*64*/OS.SendMessage (handle, OS.TB_GETHOTITEM, 0, 0);
	if (index == -1) index = lastHotId;
	while (index >= 0) {
		ToolItem item = items [index];
		if (item.isTabGroup ()) return item;
		index--;
	}
	return super.computeTabGroup ();
}

Widget [] computeTabList () {
	ToolItem [] items = _getItems ();
	if (tabItemList == null) {
		int i = 0;
		while (i < items.length && items [i].control == null) i++;
		if (i == items.length) return super.computeTabList (); 
	}
	Widget result [] = {};
	if (!isTabGroup () || !isEnabled () || !isVisible ()) return result;
	ToolItem [] list = tabList != null ? _getTabItemList () : items;
	for (int i=0; i<list.length; i++) {
		ToolItem child = list [i];
		Widget  [] childList = child.computeTabList ();
		if (childList.length != 0) {
			Widget [] newResult = new Widget [result.length + childList.length];
			System.arraycopy (result, 0, newResult, 0, result.length);
			System.arraycopy (childList, 0, newResult, result.length, childList.length);
			result = newResult;
		}
	}
	if (result.length == 0) result = new Widget [] {this}; 
	return result;
}

void createHandle () {
	super.createHandle ();
	state &= ~CANVAS;
	
	/*
	* Feature in Windows.  When TBSTYLE_FLAT is used to create
	* a flat toolbar, for some reason TBSTYLE_TRANSPARENT is
	* also set.  This causes the toolbar to flicker when it is
	* moved or resized.  The fix is to clear TBSTYLE_TRANSPARENT.
	* 
	* NOTE:  This work around is unnecessary on XP.  There is no
	* flickering and clearing the TBSTYLE_TRANSPARENT interferes
	* with the XP theme.
	*/
	if ((style & SWT.FLAT) != 0) {
		if (OS.COMCTL32_MAJOR < 6 || !OS.IsAppThemed ()) {
			int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
			bits &= ~OS.TBSTYLE_TRANSPARENT;
			OS.SetWindowLong (handle, OS.GWL_STYLE, bits);
		}
	}

	/*
	* Feature in Windows.  Despite the fact that the
	* tool tip text contains \r\n, the tooltip will
	* not honour the new line unless TTM_SETMAXTIPWIDTH
	* is set.  The fix is to set TTM_SETMAXTIPWIDTH to
	* a large value.
	*/
	/*
	* These lines are intentionally commented.  The tool
	* bar currently sets this value to 300 so it is not
	* necessary to set TTM_SETMAXTIPWIDTH.
	*/
//	long /*int*/ hwndToolTip = OS.SendMessage (handle, OS.TB_GETTOOLTIPS, 0, 0);
//	OS.SendMessage (hwndToolTip, OS.TTM_SETMAXTIPWIDTH, 0, 0x7FFF);

	/*
	* Feature in Windows.  When the control is created,
	* it does not use the default system font.  A new HFONT
	* is created and destroyed when the control is destroyed.
	* This means that a program that queries the font from
	* this control, uses the font in another control and then
	* destroys this control will have the font unexpectedly
	* destroyed in the other control.  The fix is to assign
	* the font ourselves each time the control is created.
	* The control will not destroy a font that it did not
	* create.
	*/
	long /*int*/ hFont = OS.GetStockObject (OS.SYSTEM_FONT);
	OS.SendMessage (handle, OS.WM_SETFONT, hFont, 0);

	/* Set the button struct, bitmap and button sizes */
	OS.SendMessage (handle, OS.TB_BUTTONSTRUCTSIZE, TBBUTTON.sizeof, 0);
	OS.SendMessage (handle, OS.TB_SETBITMAPSIZE, 0, 0);
	OS.SendMessage (handle, OS.TB_SETBUTTONSIZE, 0, 0);

	/* Set the extended style bits */
	int bits = OS.TBSTYLE_EX_DRAWDDARROWS | OS.TBSTYLE_EX_MIXEDBUTTONS | OS.TBSTYLE_EX_HIDECLIPPEDBUTTONS;
	if (OS.COMCTL32_MAJOR >= 6) bits |= OS.TBSTYLE_EX_DOUBLEBUFFER;
	OS.SendMessage (handle, OS.TB_SETEXTENDEDSTYLE, 0, bits);
}

void createItem (ToolItem item, int index) {
	int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
	if (!(0 <= index && index <= count)) error (SWT.ERROR_INVALID_RANGE);
	int id = 0;
	while (id < items.length && items [id] != null) id++;
	if (id == items.length) {
		ToolItem [] newItems = new ToolItem [items.length + 4];
		System.arraycopy (items, 0, newItems, 0, items.length);
		items = newItems;
	}
	int bits = item.widgetStyle ();
	TBBUTTON lpButton = new TBBUTTON ();
	lpButton.idCommand = id;
	lpButton.fsStyle = (byte) bits;
	lpButton.fsState = (byte) OS.TBSTATE_ENABLED;
	
	/*
	* Bug in Windows.  Despite the fact that the image list
	* index has never been set for the item, Windows always
	* assumes that the image index for the item is valid.
	* When an item is inserted, the image index is zero.
	* Therefore, when the first image is inserted and is
	* assigned image index zero, every item draws with this
	* image.  The fix is to set the image index to none
	* when the item is created.  This is not necessary in
	* the case when the item has the BTNS_SEP style because
	* separators cannot show images.
	*/
	if ((bits & OS.BTNS_SEP) == 0) lpButton.iBitmap = OS.I_IMAGENONE;
	if (OS.SendMessage (handle, OS.TB_INSERTBUTTON, index, lpButton) == 0) {
		error (SWT.ERROR_ITEM_NOT_ADDED);
	}
	items [item.id = id] = item;
	if ((style & SWT.VERTICAL) != 0) setRowCount (count + 1);
	layoutItems ();
}

void createWidget () {
	super.createWidget ();
	items = new ToolItem [4];
	lastFocusId = lastArrowId = lastHotId = -1;
}

int defaultBackground () {
	if (OS.IsWinCE) return OS.GetSysColor (OS.COLOR_BTNFACE);
	return super.defaultBackground ();
}

void destroyItem (ToolItem item) {
	TBBUTTONINFO info = new TBBUTTONINFO ();
	info.cbSize = TBBUTTONINFO.sizeof;
	info.dwMask = OS.TBIF_IMAGE | OS.TBIF_STYLE;
	int index = (int)/*64*/OS.SendMessage (handle, OS.TB_GETBUTTONINFO, item.id, info);
	/*
	* Feature in Windows.  For some reason, a tool item that has
	* the style BTNS_SEP does not return I_IMAGENONE when queried
	* for an image index, despite the fact that no attempt has been
	* made to assign an image to the item.  As a result, operations
	* on an image list that use the wrong index cause random results.	
	* The fix is to ensure that the tool item is not a separator
	* before using the image index.  Since separators cannot have
	* an image and one is never assigned, this is not a problem.
	*/
	if ((info.fsStyle & OS.BTNS_SEP) == 0 && info.iImage != OS.I_IMAGENONE) {
		if (imageList != null) imageList.put (info.iImage, null);
		if (hotImageList != null) hotImageList.put (info.iImage, null);
		if (disabledImageList != null) disabledImageList.put (info.iImage, null);
	}
	OS.SendMessage (handle, OS.TB_DELETEBUTTON, index, 0);
	if (item.id == lastFocusId) lastFocusId = -1;
	if (item.id == lastArrowId) lastArrowId = -1;
	if (item.id == lastHotId) lastHotId = -1;
	items [item.id] = null;
	item.id = -1;
	int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
	if (count == 0) {
		if (imageList != null) {
			OS.SendMessage (handle, OS.TB_SETIMAGELIST, 0, 0);
			display.releaseToolImageList (imageList);
		}
		if (hotImageList != null) {
			OS.SendMessage (handle, OS.TB_SETHOTIMAGELIST, 0, 0);
			display.releaseToolHotImageList (hotImageList);
		}
		if (disabledImageList != null) {
			OS.SendMessage (handle, OS.TB_SETDISABLEDIMAGELIST, 0, 0);
			display.releaseToolDisabledImageList (disabledImageList);
		}
		imageList = hotImageList = disabledImageList = null;
		items = new ToolItem [4];
	}
	if ((style & SWT.VERTICAL) != 0) setRowCount (count - 1);
	layoutItems ();
}

void enableWidget (boolean enabled) {
	super.enableWidget (enabled);
	/*
	* Bug in Windows.  When a tool item with the style
	* BTNS_CHECK or BTNS_CHECKGROUP is selected and then
	* disabled, the item does not draw using the disabled
	* image.  The fix is to use the disabled image in all
	* image lists for the item.
	* 
	* Feature in Windows.  When a tool bar is disabled,
	* the text draws disabled but the images do not.
	* The fix is to use the disabled image in all image
	* lists for all items.
	*/
	for (int i=0; i<items.length; i++) {
		ToolItem item = items [i];
		if (item != null) {
			if ((item.style & SWT.SEPARATOR) == 0) {
				item.updateImages (enabled && item.getEnabled ());
			}
		}
	}
}

ImageList getDisabledImageList () {
	return disabledImageList;
}

ImageList getHotImageList () {
	return hotImageList;
}

ImageList getImageList () {
	return imageList;
}

/**
 * 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 ToolItem getItem (int index) {
	checkWidget ();
	int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
	if (!(0 <= index && index < count)) error (SWT.ERROR_INVALID_RANGE);	
	TBBUTTON lpButton = new TBBUTTON ();
	long /*int*/ result = OS.SendMessage (handle, OS.TB_GETBUTTON, index, lpButton);
	if (result == 0) error (SWT.ERROR_CANNOT_GET_ITEM);
	return items [lpButton.idCommand];
}

/**
 * Returns the item at the given point in the receiver
 * or null if no such item exists. The point is in the
 * coordinate system of the receiver.
 *
 * @param point the point used to locate the item
 * @return the item at the given point
 *
 * @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>
 */
public ToolItem getItem (Point point) {
	checkWidget ();
	if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
	ToolItem [] items = getItems ();
	for (int i=0; i<items.length; i++) {
		Rectangle rect = items [i].getBounds ();
		if (rect.contains (point)) return items [i];
	}
	return null;
}

/**
 * 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 (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
}

/**
 * Returns an array of <code>ToolItem</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 ToolItem [] getItems () {
	checkWidget ();
	return _getItems ();
}

ToolItem [] _getItems () {
	int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
	TBBUTTON lpButton = new TBBUTTON ();
	ToolItem [] result = new ToolItem [count];
	for (int i=0; i<count; i++) {
		OS.SendMessage (handle, OS.TB_GETBUTTON, i, lpButton);
		result [i] = items [lpButton.idCommand];
	}
	return result;
}

/**
 * Returns the number of rows in the receiver. When
 * the receiver has the <code>WRAP</code> style, the
 * number of rows can be greater than one.  Otherwise,
 * the number of rows is always one.
 *
 * @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 getRowCount () {
	checkWidget ();
	if ((style & SWT.VERTICAL) != 0) {
		return (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
	}
	return (int)/*64*/OS.SendMessage (handle, OS.TB_GETROWS, 0, 0);
}

ToolItem [] _getTabItemList () {
	if (tabItemList == null) return tabItemList;
	int count = 0;
	for (int i=0; i<tabItemList.length; i++) {
		if (!tabItemList [i].isDisposed ()) count++;
	}
	if (count == tabItemList.length) return tabItemList;
	ToolItem [] newList = new ToolItem [count];
	int index = 0;
	for (int i=0; i<tabItemList.length; i++) {
		if (!tabItemList [i].isDisposed ()) {
			newList [index++] = tabItemList [i];
		}
	}
	tabItemList = newList;
	return tabItemList;
}

/**
 * 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 tool item is null</li>
 *    <li>ERROR_INVALID_ARGUMENT - if the tool 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 int indexOf (ToolItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (item.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
	return (int)/*64*/OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, item.id, 0);
}

void layoutItems () {	
	/*
	* Feature in Windows.  When a tool bar has the style
	* TBSTYLE_LIST and has a drop down item, Window leaves
	* too much padding around the button.  This affects
	* every button in the tool bar and makes the preferred
	* height too big.  The fix is to set the TBSTYLE_LIST
	* when the tool bar contains both text and images.
	* 
	* NOTE: Tool bars with CCS_VERT must have TBSTYLE_LIST
	* set before any item is added or the tool bar does
	* not lay out properly.  The work around does not run
	* in this case.
	*/
	if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
		if ((style & SWT.RIGHT) != 0 && (style & SWT.VERTICAL) == 0) {
			boolean hasText = false, hasImage = false;
			for (int i=0; i<items.length; i++) {
				ToolItem item = items [i];
				if (item != null) {
					if (!hasText) hasText = item.text.length () != 0;
					if (!hasImage) hasImage = item.image != null;
					if (hasText && hasImage) break;
				}
			}
			int oldBits = OS.GetWindowLong (handle, OS.GWL_STYLE), newBits = oldBits;
			if (hasText && hasImage) {
				newBits |= OS.TBSTYLE_LIST;
			} else {
				newBits &= ~OS.TBSTYLE_LIST;
			}
			if (newBits != oldBits) {
				setDropDownItems (false);
				OS.SetWindowLong (handle, OS.GWL_STYLE, newBits);
				/*
				* Feature in Windows.  For some reason, when the style
				* is changed to TBSTYLE_LIST, Windows does not lay out
				* the tool items.  The fix is to use WM_SETFONT to force
				* the tool bar to redraw and lay out.
				*/
				long /*int*/ hFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
				OS.SendMessage (handle, OS.WM_SETFONT, hFont, 0);
				setDropDownItems (true);
			}
		}
	}
	
	if ((style & SWT.WRAP) != 0) {
		OS.SendMessage (handle, OS.TB_AUTOSIZE, 0, 0);
	}
	/*
	*  When the tool bar is vertical, make the width of each button
	*  be the width of the widest button in the tool bar.  Note that
	*  when the tool bar contains a drop down item, it needs to take
	*  into account extra padding.
	*/
	if ((style & SWT.VERTICAL) != 0) {
		int itemCount = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
		if (itemCount > 1) {
			TBBUTTONINFO info = new TBBUTTONINFO ();
			info.cbSize = TBBUTTONINFO.sizeof;
			info.dwMask = OS.TBIF_SIZE;
			long /*int*/ size = OS.SendMessage (handle, OS.TB_GETBUTTONSIZE, 0, 0);
			info.cx = (short) OS.LOWORD (size);
			int index = 0;
			while (index < items.length) {
				ToolItem item = items [index];
				if (item != null && (item.style & SWT.DROP_DOWN) != 0) break;
				index++;
			}
			if (index < items.length) {
				long /*int*/ padding = OS.SendMessage (handle, OS.TB_GETPADDING, 0, 0);
				info.cx += OS.LOWORD (padding) * 2;
			}
			for (int i=0; i<items.length; i++) {
				ToolItem item = items [i];
				if (item != null && (item.style & SWT.SEPARATOR) == 0) {
					OS.SendMessage (handle, OS.TB_SETBUTTONINFO, item.id, info);
				}
			}
		}
	}

	/*
	* Feature on Windows. When SWT.WRAP or SWT.VERTICAL are set
	* the separator items with control are implemented using BTNS_BUTTON 
	* instead of BTNS_SEP. When that is the case and TBSTYLE_LIST is 
	* set, the layout of the ToolBar recalculates the width for all 
	* BTNS_BUTTON based on the text and bitmap of the item.
	* This is not strictly wrong, but the user defined width for the
	* separators has to be respected if set.
	* The fix is to detect this case and reset the cx width for the item.  
	*/
	if ((style & (SWT.WRAP | SWT.VERTICAL)) != 0) {
		int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
		if ((bits & OS.TBSTYLE_LIST) != 0) {
			TBBUTTONINFO info = new TBBUTTONINFO ();
			info.cbSize = TBBUTTONINFO.sizeof;
			info.dwMask = OS.TBIF_SIZE;
			for (int i=0; i<items.length; i++) {
				ToolItem item = items [i];
				if (item != null && item.cx > 0) {
					info.cx = item.cx;
					OS.SendMessage (handle, OS.TB_SETBUTTONINFO, item.id, info);
				}
			}
		}
	}
	
	for (int i=0; i<items.length; i++) {
		ToolItem item = items [i];
		if (item != null) item.resizeControl ();
	}
}

boolean mnemonicHit (char ch) {
	int key = Display.wcsToMbcs (ch);
	int [] id = new int [1];
	if (OS.SendMessage (handle, OS.TB_MAPACCELERATOR, key, id) == 0) {
		return false;
	}
	if ((style & SWT.FLAT) != 0 && !setTabGroupFocus ()) return false;
	int index = (int)/*64*/OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, id [0], 0);
	if (index == -1) return false;
	OS.SendMessage (handle, OS.TB_SETHOTITEM, index, 0);
	items [id [0]].click (false);
	return true;
}

boolean mnemonicMatch (char ch) {
	int key = Display.wcsToMbcs (ch);
	int [] id = new int [1];
	if (OS.SendMessage (handle, OS.TB_MAPACCELERATOR, key, id) == 0) {
		return false;
	}
	/*
	* Feature in Windows.  TB_MAPACCELERATOR matches either the mnemonic
	* character or the first character in a tool item.  This behavior is
	* undocumented and unwanted.  The fix is to ensure that the tool item
	* contains a mnemonic when TB_MAPACCELERATOR returns true.
	*/
	int index = (int)/*64*/OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, id [0], 0);
	if (index == -1) return false;
	return findMnemonic (items [id [0]].text) != '\0';
}

void releaseChildren (boolean destroy) {
	if (items != null) {
		for (int i=0; i<items.length; i++) {
			ToolItem item = items [i];
			if (item != null && !item.isDisposed ()) {
				item.release (false);
			}
		}
		items = null;
	}
	super.releaseChildren (destroy);
}

void releaseWidget () {
	super.releaseWidget ();
	if (imageList != null) {
		OS.SendMessage (handle, OS.TB_SETIMAGELIST, 0, 0);
		display.releaseToolImageList (imageList);
	}
	if (hotImageList != null) {
		OS.SendMessage (handle, OS.TB_SETHOTIMAGELIST, 0, 0);
		display.releaseToolHotImageList (hotImageList);
	}
	if (disabledImageList != null) {
		OS.SendMessage (handle, OS.TB_SETDISABLEDIMAGELIST, 0, 0);
		display.releaseToolDisabledImageList (disabledImageList);
	}
	imageList = hotImageList = disabledImageList = null;
}

void removeControl (Control control) {
	super.removeControl (control);
	for (int i=0; i<items.length; i++) {
		ToolItem item = items [i];
		if (item != null && item.control == control) {
			item.setControl (null);
		}
	}
}

void reskinChildren (int flags) {
	if (items != null) {
		for (int i=0; i<items.length; i++) {
			ToolItem item = items [i];
			if (item != null) item.reskin (flags);
		}
	}
	super.reskinChildren (flags);
}

void setBackgroundImage (long /*int*/ hBitmap) {
	super.setBackgroundImage (hBitmap);
	setBackgroundTransparent (hBitmap != 0);
}

void setBackgroundPixel (int pixel) {
	super.setBackgroundPixel (pixel);
	setBackgroundTransparent (pixel != -1);
}

void setBackgroundTransparent (boolean transparent) {
	/*
	* Feature in Windows.  When TBSTYLE_TRANSPARENT is set
	* in a tool bar that is drawing a background, images in
	* the image list that include transparency information
	* do not draw correctly.  The fix is to clear and set
	* TBSTYLE_TRANSPARENT depending on the background color.
	* 
	* NOTE:  This work around is unnecessary on XP.  The
	* TBSTYLE_TRANSPARENT style is never cleared on that
	* platform.
	*/
	if ((style & SWT.FLAT) != 0) {
		if (OS.COMCTL32_MAJOR < 6 || !OS.IsAppThemed ()) {
			int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
			if (!transparent && findBackgroundControl () == null) {
				bits &= ~OS.TBSTYLE_TRANSPARENT;
			} else {
				bits |= OS.TBSTYLE_TRANSPARENT;
			}
			OS.SetWindowLong (handle, OS.GWL_STYLE, bits);
		}
	}
}

void setBounds (int x, int y, int width, int height, int flags) {
	/*
	* Feature in Windows.  For some reason, when a tool bar is
	* repositioned more than once using DeferWindowPos () into
	* the same HDWP, the toolbar redraws more than once, defeating
	* the purpose of DeferWindowPos ().  The fix is to end the
	* deferred positioning before the next tool bar is added,
	* ensuring that only one tool bar position is deferred at
	* any given time.
	*/
	if (parent.lpwp != null) {
		if (getDrawing () && OS.IsWindowVisible (handle)) {
			parent.setResizeChildren (false);
			parent.setResizeChildren (true);
		}
	}
	super.setBounds (x, y, width, height, flags);
}

void setDefaultFont () {
	super.setDefaultFont ();
	OS.SendMessage (handle, OS.TB_SETBITMAPSIZE, 0, 0);
	OS.SendMessage (handle, OS.TB_SETBUTTONSIZE, 0, 0);
}

void setDropDownItems (boolean set) {
	/*
	* Feature in Windows.  When the first button in a tool bar
	* is a drop down item, Window leaves too much padding around
	* the button.  This affects every button in the tool bar and
	* makes the preferred height too big.  The fix is clear the
	* BTNS_DROPDOWN before Windows lays out the tool bar and set
	* the bit afterwards.
	* 
	* NOTE:  This work around only runs when the tool bar contains
	* only images.
	*/
	if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
		boolean hasText = false, hasImage = false;
		for (int i=0; i<items.length; i++) {
			ToolItem item = items [i];
			if (item != null) {
				if (!hasText) hasText = item.text.length () != 0;
				if (!hasImage) hasImage = item.image != null;
				if (hasText && hasImage) break;
			}
		}
		if (hasImage && !hasText) {
			for (int i=0; i<items.length; i++) {
				ToolItem item = items [i];
				if (item != null && (item.style & SWT.DROP_DOWN) != 0) {
					TBBUTTONINFO info = new TBBUTTONINFO ();
					info.cbSize = TBBUTTONINFO.sizeof;
					info.dwMask = OS.TBIF_STYLE;
					OS.SendMessage (handle, OS.TB_GETBUTTONINFO, item.id, info);
					if (set) {
						info.fsStyle |= OS.BTNS_DROPDOWN;
					} else {
						info.fsStyle &= ~OS.BTNS_DROPDOWN;
					}
					OS.SendMessage (handle, OS.TB_SETBUTTONINFO, item.id, info);
				}
			}
		}
	}
}

void setDisabledImageList (ImageList imageList) {
	if (disabledImageList == imageList) return;
	long /*int*/ hImageList = 0;
	if ((disabledImageList = imageList) != null) {
		hImageList = disabledImageList.getHandle ();
	}
	setDropDownItems (false);
	OS.SendMessage (handle, OS.TB_SETDISABLEDIMAGELIST, 0, hImageList);
	setDropDownItems (true);
}

public void setFont (Font font) {
	checkWidget ();
	setDropDownItems (false);
	super.setFont (font);
	setDropDownItems (true);
	/*
	* Bug in Windows.  When WM_SETFONT is sent to a tool bar
	* that contains only separators, causes the bitmap and button
	* sizes to be set.  The fix is to reset these sizes after the font
	* has been changed when the tool bar contains only separators.
	*/
	int index = 0;
	int mask = SWT.PUSH | SWT.CHECK | SWT.RADIO | SWT.DROP_DOWN;
	while (index < items.length) {
		ToolItem item = items [index];
		if (item != null && (item.style & mask) != 0) break;		
		index++;
	}
	if (index == items.length) {
		OS.SendMessage (handle, OS.TB_SETBITMAPSIZE, 0, 0);
		OS.SendMessage (handle, OS.TB_SETBUTTONSIZE, 0, 0);
	}
	layoutItems ();
}

void setHotImageList (ImageList imageList) {
	if (hotImageList == imageList) return;
	long /*int*/ hImageList = 0;
	if ((hotImageList = imageList) != null) {
		hImageList = hotImageList.getHandle ();
	}
	setDropDownItems (false);
	OS.SendMessage (handle, OS.TB_SETHOTIMAGELIST, 0, hImageList);
	setDropDownItems (true);
}

void setImageList (ImageList imageList) {
	if (this.imageList == imageList) return;
	long /*int*/ hImageList = 0;
	if ((this.imageList = imageList) != null) {
		hImageList = imageList.getHandle ();
	}
	setDropDownItems (false);
	OS.SendMessage (handle, OS.TB_SETIMAGELIST, 0, hImageList);
	setDropDownItems (true);
}

public boolean setParent (Composite parent) {
	checkWidget ();
	if (!super.setParent (parent)) return false;
	long /*int*/ hwndParent = parent.handle;
	OS.SendMessage (handle, OS.TB_SETPARENT, hwndParent, 0);
	/*
	* Bug in Windows.  When a tool bar is reparented, the tooltip
	* control that is automatically created for the item is not
	* reparented to the new shell.  The fix is to move the tooltip
	* over using SetWindowLongPtr().  Note that for some reason,
	* SetParent() does not work.
	*/
	long /*int*/ hwndShell = parent.getShell ().handle;
	long /*int*/ hwndToolTip = OS.SendMessage (handle, OS.TB_GETTOOLTIPS, 0, 0);
	OS.SetWindowLongPtr (hwndToolTip, OS.GWLP_HWNDPARENT, hwndShell);
	return true;
}

public void setRedraw (boolean redraw) {
	checkWidget ();
	setDropDownItems (false);
	super.setRedraw (redraw);
	setDropDownItems (true);
}

void setRowCount (int count) {
	if ((style & SWT.VERTICAL) != 0) {
		/*
		* Feature in Windows.  When the TB_SETROWS is used to set the
		* number of rows in a tool bar, the tool bar is resized to show
		* the items.  This is unexpected.  The fix is to save and restore
		* the current size of the tool bar.
		*/
		RECT rect = new RECT ();
		OS.GetWindowRect (handle, rect);
		OS.MapWindowPoints (0, parent.handle, rect, 2);
		ignoreResize = true;
		/*
		* Feature in Windows.  When the last button in a tool bar has the
		* style BTNS_SEP and TB_SETROWS is used to set the number of rows
		* in the tool bar, depending on the number of buttons, the toolbar
		* will wrap items with the style BTNS_CHECK, even when the fLarger
		* flags is used to force the number of rows to be larger than the
		* number of items.  The fix is to set the number of rows to be two
		* larger than the actual number of rows in the tool bar.  When items
		* are being added, as long as the number of rows is at least one
		* item larger than the count, the tool bar is laid out properly.
		* When items are being removed, setting the number of rows to be
		* one more than the item count has no effect.  The number of rows
		* is already one more causing TB_SETROWS to do nothing.  Therefore,
		* choosing two instead of one as the row increment fixes both cases.
		*/
		count += 2;
		OS.SendMessage (handle, OS.TB_SETROWS, OS.MAKEWPARAM (count, 1), 0);
		int flags = OS.SWP_NOACTIVATE | OS.SWP_NOMOVE | OS.SWP_NOZORDER;
		SetWindowPos (handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, flags);
		ignoreResize = false;
	}
}

/*public*/ void setTabItemList (ToolItem [] tabList) {
	checkWidget ();
	if (tabList != null) {
		for (int i=0; i<tabList.length; i++) {
			ToolItem item = tabList [i];
			if (item == null) error (SWT.ERROR_INVALID_ARGUMENT);
			if (item.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT);
			if (item.parent != this) error (SWT.ERROR_INVALID_PARENT);
		}
		ToolItem [] newList = new ToolItem [tabList.length];
		System.arraycopy (tabList, 0, newList, 0, tabList.length);
		tabList = newList;
	} 
	this.tabItemList = tabList;
}

boolean setTabItemFocus () {
	int index = 0;
	while (index < items.length) {
		ToolItem item = items [index];
		if (item != null && (item.style & SWT.SEPARATOR) == 0) {
			if (item.getEnabled ()) break;
		}
		index++;
	}
	if (index == items.length) return false;
	return super.setTabItemFocus ();
}

String toolTipText (NMTTDISPINFO hdr) {
	if ((hdr.uFlags & OS.TTF_IDISHWND) != 0) {
		return null;
	}
	/*
	* Bug in Windows.  On Windows XP, when TB_SETHOTITEM is
	* used to set the hot item, the tool bar control attempts
	* to display the tool tip, even when the cursor is not in
	* the hot item.  The fix is to detect this case and fail to
	* provide the string, causing no tool tip to be displayed.
	*/
	if (!hasCursor ()) return ""; //$NON-NLS-1$
	int index = (int)/*64*/hdr.idFrom;
	long /*int*/ hwndToolTip = OS.SendMessage (handle, OS.TB_GETTOOLTIPS, 0, 0);
	if (hwndToolTip == hdr.hwndFrom) {
		/*
		* Bug in Windows. For some reason the reading order
		* in NMTTDISPINFO is sometimes set incorrectly.  The
		* reading order seems to change every time the mouse
		* enters the control from the top edge.  The fix is
		* to explicitly set TTF_RTLREADING.
		*/
		if ((style & SWT.RIGHT_TO_LEFT) != 0) {
			hdr.uFlags |= OS.TTF_RTLREADING;
		} else {
			hdr.uFlags &= ~OS.TTF_RTLREADING;
		}
		if (toolTipText != null) return ""; //$NON-NLS-1$
		if (0 <= index && index < items.length) {
			ToolItem item = items [index];
			if (item != null) {	
				/*
				* Bug in Windows.  When the  arrow keys are used to change
				* the hot item, for some reason, Windows displays the tool
				* tip for the hot item in at (0, 0) on the screen rather
				* than next to the current hot item.  This fix is to disallow
				* tool tips while the user is traversing with the arrow keys.
				*/
				if (lastArrowId != -1) return "";
				return item.toolTipText;
			}
		}
	}
	return super.toolTipText (hdr);
}

void updateOrientation () {
	super.updateOrientation ();
	if (imageList != null) {
		Point size = imageList.getImageSize ();
		ImageList newImageList = display.getImageListToolBar (style & SWT.RIGHT_TO_LEFT, size.x, size.y);
		ImageList newHotImageList = display.getImageListToolBarHot (style & SWT.RIGHT_TO_LEFT, size.x, size.y);
		ImageList newDisabledImageList = display.getImageListToolBarDisabled (style & SWT.RIGHT_TO_LEFT, size.x, size.y);	
		TBBUTTONINFO info = new TBBUTTONINFO ();
		info.cbSize = TBBUTTONINFO.sizeof;
		info.dwMask = OS.TBIF_IMAGE;
		int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
		for (int i=0; i<count; i++) {
			ToolItem item = items [i];
			if ((item.style & SWT.SEPARATOR) != 0) continue;
			if (item.image == null) continue;
			OS.SendMessage (handle, OS.TB_GETBUTTONINFO, item.id, info);
			if (info.iImage != OS.I_IMAGENONE) {
				Image image = imageList.get(info.iImage);
				Image hot = hotImageList.get(info.iImage);
				Image disabled = disabledImageList.get(info.iImage);
				imageList.put(info.iImage, null);
				hotImageList.put(info.iImage, null);
				disabledImageList.put(info.iImage, null);
				info.iImage = newImageList.add(image);
				newHotImageList.add(hot);
				newDisabledImageList.add(disabled);
				OS.SendMessage (handle, OS.TB_SETBUTTONINFO, item.id, info);
			}
		}
		display.releaseToolImageList (imageList);
		display.releaseToolHotImageList (hotImageList);
		display.releaseToolDisabledImageList (disabledImageList);
		OS.SendMessage (handle, OS.TB_SETIMAGELIST, 0, newImageList.getHandle ());
		OS.SendMessage (handle, OS.TB_SETHOTIMAGELIST, 0, newHotImageList.getHandle ());
		OS.SendMessage (handle, OS.TB_SETDISABLEDIMAGELIST, 0, newDisabledImageList.getHandle ());
		imageList = newImageList;
		hotImageList = newHotImageList;
		disabledImageList = newDisabledImageList;
		OS.InvalidateRect (handle, null, true);
	}
}

int widgetStyle () {
	int bits = super.widgetStyle () | OS.CCS_NORESIZE | OS.TBSTYLE_TOOLTIPS | OS.TBSTYLE_CUSTOMERASE;
	if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) bits |= OS.TBSTYLE_TRANSPARENT;
	if ((style & SWT.SHADOW_OUT) == 0) bits |= OS.CCS_NODIVIDER;
	if ((style & SWT.WRAP) != 0) bits |= OS.TBSTYLE_WRAPABLE;
	if ((style & SWT.FLAT) != 0) bits |= OS.TBSTYLE_FLAT;
	/*
	* Feature in Windows.  When a tool bar has the style
	* TBSTYLE_LIST and has a drop down item, Window leaves
	* too much padding around the button.  This affects
	* every button in the tool bar and makes the preferred
	* height too big.  The fix is to set the TBSTYLE_LIST
	* when the tool bar contains both text and images.
	* 
	* NOTE: Tool bars with CCS_VERT must have TBSTYLE_LIST
	* set before any item is added or the tool bar does
	* not lay out properly.  The work around does not run
	* in this case.
	*/
	if (OS.COMCTL32_MAJOR < 6 || !OS.IsAppThemed ()) {
		if ((style & SWT.RIGHT) != 0) bits |= OS.TBSTYLE_LIST;
	}
	return bits;
}

TCHAR windowClass () {
	return ToolBarClass;
}

long /*int*/ windowProc () {
	return ToolBarProc;
}

LRESULT WM_CAPTURECHANGED (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_CAPTURECHANGED (wParam, lParam);
	if (result != null) return result;
	/*
	* Bug in Windows.  When the tool bar loses capture while an
	* item is pressed, the item remains pressed.  The fix is
	* unpress all items using TB_SETSTATE and TBSTATE_PRESSED.
	*/
	for (int i=0; i<items.length; i++) {
		ToolItem item = items [i];
		if (item != null) {
			int fsState = (int)/*64*/OS.SendMessage (handle, OS.TB_GETSTATE, item.id, 0);
			if ((fsState & OS.TBSTATE_PRESSED) != 0) {
				fsState &= ~OS.TBSTATE_PRESSED;
				OS.SendMessage (handle, OS.TB_SETSTATE, item.id, fsState);
			}
		}
	}
	return result;
}

LRESULT WM_CHAR (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_CHAR (wParam, lParam);
	if (result != null) return result;
	switch ((int)/*64*/wParam) {
		case ' ':
			int index = (int)/*64*/OS.SendMessage (handle, OS.TB_GETHOTITEM, 0, 0);
			if (index != -1) {
				TBBUTTON lpButton = new TBBUTTON ();
				long /*int*/ code = OS.SendMessage (handle, OS.TB_GETBUTTON, index, lpButton);
				if (code != 0) {
					items [lpButton.idCommand].click (false);
					return LRESULT.ZERO;
				}
			}
	}
	return result;
}

LRESULT WM_COMMAND (long /*int*/ wParam, long /*int*/ lParam) {
	/*
	* Feature in Windows.  When the toolbar window
	* proc processes WM_COMMAND, it forwards this
	* message to its parent.  This is done so that
	* children of this control that send this message 
	* type to their parent will notify not only
	* this control but also the parent of this control,
	* which is typically the application window and
	* the window that is looking for the message.
	* If the control did not forward the message, 
	* applications would have to subclass the control 
	* window to see the message. Because the control
	* window is subclassed by SWT, the message
	* is delivered twice, once by SWT and once when
	* the message is forwarded by the window proc.
	* The fix is to avoid calling the window proc 
	* for this control.
	*/
	LRESULT result = super.WM_COMMAND (wParam, lParam);
	if (result != null) return result;
	return LRESULT.ZERO;
}

LRESULT WM_ERASEBKGND (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_ERASEBKGND (wParam, lParam);
	/*
	* Bug in Windows.  For some reason, NM_CUSTOMDRAW with
	* CDDS_PREERASE and CDDS_POSTERASE is never sent for
	* versions of Windows earlier than XP.  The fix is to
	* draw the background in WM_ERASEBKGND;
	*/
	if (findBackgroundControl () != null) {
		if (OS.COMCTL32_MAJOR < 6) {
			drawBackground (wParam);
			return LRESULT.ONE;
		}
	}
	return result;
}

LRESULT WM_GETDLGCODE (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_GETDLGCODE (wParam, lParam);
	/*
	* Return DLGC_BUTTON so that mnemonics will be
	* processed without needing to press the ALT key
	* when the widget has focus.
	*/
	if (result != null) return result;
	return new LRESULT (OS.DLGC_BUTTON | OS.DLGC_WANTARROWS);
}

LRESULT WM_KEYDOWN (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_KEYDOWN (wParam, lParam);
	if (result != null) return result;
	switch ((int)/*64*/wParam) {
		case OS.VK_SPACE:	
			/*
			* Ensure that the window proc does not process VK_SPACE
			* so that it can be handled in WM_CHAR.  This allows the
			* application the opportunity to cancel the operation.
			*/
			return LRESULT.ZERO;
	}
	return result;
}

LRESULT WM_KILLFOCUS (long /*int*/ wParam, long /*int*/ lParam) {
	int index = (int)/*64*/OS.SendMessage (handle, OS.TB_GETHOTITEM, 0, 0);
	TBBUTTON lpButton = new TBBUTTON ();
	long /*int*/ code = OS.SendMessage (handle, OS.TB_GETBUTTON, index, lpButton);
	if (code != 0) lastFocusId = lpButton.idCommand;
	return super.WM_KILLFOCUS (wParam, lParam);
}

LRESULT WM_LBUTTONDOWN (long /*int*/ wParam, long /*int*/ lParam) {
	if (ignoreMouse) return null;
	return super.WM_LBUTTONDOWN (wParam, lParam);
}

LRESULT WM_LBUTTONUP (long /*int*/ wParam, long /*int*/ lParam) {
	if (ignoreMouse) return null;
	return super.WM_LBUTTONUP (wParam, lParam);
}

LRESULT WM_MOUSELEAVE (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_MOUSELEAVE (wParam, lParam);
	if (result != null) return result;
	/*
	* Bug in Windows.  On XP, when a tooltip is
	* hidden due to a time out or mouse press,
	* the tooltip remains active although no
	* longer visible and won't show again until
	* another tooltip becomes active.  If there
	* is only one tooltip in the window,  it will
	* never show again.  The fix is to remove the
	* current tooltip and add it again every time
	* the mouse leaves the control.
	*/
	if (OS.COMCTL32_MAJOR >= 6) {
		TOOLINFO lpti = new TOOLINFO ();
		lpti.cbSize = TOOLINFO.sizeof;
		long /*int*/ hwndToolTip = OS.SendMessage (handle, OS.TB_GETTOOLTIPS, 0, 0);
		if (OS.SendMessage (hwndToolTip, OS.TTM_GETCURRENTTOOL, 0, lpti) != 0) {
			if ((lpti.uFlags & OS.TTF_IDISHWND) == 0) {
				OS.SendMessage (hwndToolTip, OS.TTM_DELTOOL, 0, lpti);
				OS.SendMessage (hwndToolTip, OS.TTM_ADDTOOL, 0, lpti);
			}
		}
	}
	return result;
}

LRESULT WM_MOUSEMOVE (long /*int*/ wParam, long /*int*/ lParam) {
	if (OS.GetMessagePos () != display.lastMouse) lastArrowId = -1;
	return super.WM_MOUSEMOVE (wParam, lParam);
}

LRESULT WM_NOTIFY (long /*int*/ wParam, long /*int*/ lParam) {
	/*
	* Feature in Windows.  When the toolbar window
	* proc processes WM_NOTIFY, it forwards this
	* message to its parent.  This is done so that
	* children of this control that send this message 
	* type to their parent will notify not only
	* this control but also the parent of this control,
	* which is typically the application window and
	* the window that is looking for the message.
	* If the control did not forward the message, 
	* applications would have to subclass the control 
	* window to see the message. Because the control
	* window is subclassed by SWT, the message
	* is delivered twice, once by SWT and once when
	* the message is forwarded by the window proc.
	* The fix is to avoid calling the window proc 
	* for this control.
	*/
	LRESULT result = super.WM_NOTIFY (wParam, lParam);
	if (result != null) return result;
	return LRESULT.ZERO;
}

LRESULT WM_SETFOCUS (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_SETFOCUS (wParam, lParam);
	if (lastFocusId != -1 && handle == OS.GetFocus ()) {
		int index = (int)/*64*/OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, lastFocusId, 0); 
		OS.SendMessage (handle, OS.TB_SETHOTITEM, index, 0);
	}
	return result;
}

LRESULT WM_SIZE (long /*int*/ wParam, long /*int*/ lParam) {
	if (ignoreResize) {
		long /*int*/ code = callWindowProc (handle, OS.WM_SIZE, wParam, lParam);
		if (code == 0) return LRESULT.ZERO;
		return new LRESULT (code);
	}
	LRESULT result = super.WM_SIZE (wParam, lParam);
	if (isDisposed ()) return result;
	/*
	* Bug in Windows.  The code in Windows that determines
	* when tool items should wrap seems to use the window
	* bounds rather than the client area.  Unfortunately,
	* tool bars with the style TBSTYLE_EX_HIDECLIPPEDBUTTONS
	* use the client area.  This means that buttons which
	* overlap the border are hidden before they are wrapped.
	* The fix is to compute TBSTYLE_EX_HIDECLIPPEDBUTTONS
	* and set it each time the tool bar is resized.
	*/
	if ((style & SWT.BORDER) != 0 && (style & SWT.WRAP) != 0) {
		RECT windowRect = new RECT ();
		OS.GetWindowRect (handle, windowRect);
		int index = 0, border = getBorderWidth () * 2; 
		RECT rect = new RECT ();
		int count = (int)/*64*/OS.SendMessage (handle, OS.TB_BUTTONCOUNT, 0, 0);
		while (index < count) {
			OS.SendMessage (handle, OS.TB_GETITEMRECT, index, rect);
			OS.MapWindowPoints (handle, 0, rect, 2);
			if (rect.right > windowRect.right - border * 2) break;
			index++;
		}
		int bits = (int)/*64*/OS.SendMessage (handle, OS.TB_GETEXTENDEDSTYLE, 0, 0);
		if (index == count) {
			bits |= OS.TBSTYLE_EX_HIDECLIPPEDBUTTONS;
		} else {
			bits &= ~OS.TBSTYLE_EX_HIDECLIPPEDBUTTONS;
		}
		OS.SendMessage (handle, OS.TB_SETEXTENDEDSTYLE, 0, bits);
	}
	layoutItems ();
	return result;
}

LRESULT WM_WINDOWPOSCHANGING (long /*int*/ wParam, long /*int*/ lParam) {
	LRESULT result = super.WM_WINDOWPOSCHANGING (wParam, lParam);
	if (result != null) return result;
	if (ignoreResize) return result;
	/*
	* Bug in Windows.  When a flat tool bar is wrapped,
	* Windows draws a horizontal separator between the
	* rows.  The tool bar does not draw the first or
	* the last two pixels of this separator.  When the
	* toolbar is resized to be bigger, only the new
	* area is drawn and the last two pixels, which are
	* blank are drawn over by separator.  This leaves
	* garbage on the screen.  The fix is to damage the
	* pixels.
	*/
	if (!getDrawing ()) return result;
	if ((style & SWT.WRAP) == 0) return result;
	if (!OS.IsWindowVisible (handle)) return result;
	if (OS.SendMessage (handle, OS.TB_GETROWS, 0, 0) == 1) {
		return result;
	}
	WINDOWPOS lpwp = new WINDOWPOS ();
	OS.MoveMemory (lpwp, lParam, WINDOWPOS.sizeof);
	if ((lpwp.flags & (OS.SWP_NOSIZE | OS.SWP_NOREDRAW)) != 0) {
		return result;
	}
	RECT oldRect = new RECT ();
	OS.GetClientRect (handle, oldRect);
	RECT newRect = new RECT ();
	OS.SetRect (newRect, 0, 0, lpwp.cx, lpwp.cy);
	OS.SendMessage (handle, OS.WM_NCCALCSIZE, 0, newRect);
	int oldWidth = oldRect.right - oldRect.left;
	int newWidth = newRect.right - newRect.left;
	if (newWidth > oldWidth) {
		RECT rect = new RECT ();
		int newHeight = newRect.bottom - newRect.top;
		OS.SetRect (rect, oldWidth - 2, 0, oldWidth, newHeight);
		OS.InvalidateRect (handle, rect, false);
	}
	return result;
}

LRESULT wmCommandChild (long /*int*/ wParam, long /*int*/ lParam) {
	ToolItem child = items [OS.LOWORD (wParam)];
	if (child == null) return null;
	return child.wmCommandChild (wParam, lParam);
}

LRESULT wmNotifyChild (NMHDR hdr, long /*int*/ wParam, long /*int*/ lParam) {
	switch (hdr.code) {
		case OS.TBN_DROPDOWN:
			NMTOOLBAR lpnmtb = new NMTOOLBAR ();
			OS.MoveMemory (lpnmtb, lParam, NMTOOLBAR.sizeof);
			ToolItem child = items [lpnmtb.iItem];
			if (child != null) {
				Event event = new Event ();
				event.detail = SWT.ARROW;
				int index = (int)/*64*/OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, lpnmtb.iItem, 0);
				RECT rect = new RECT ();
				OS.SendMessage (handle, OS.TB_GETITEMRECT, index, rect);
				event.x = rect.left;
				event.y = rect.bottom;
				child.sendSelectionEvent (SWT.Selection, event, false);
			}
			break;
		case OS.NM_CUSTOMDRAW:
			if (OS.COMCTL32_MAJOR < 6) break;
			/*
			* Bug in Windows.  For some reason, under the XP Silver
			* theme, tool bars continue to draw using the gray color
			* from the default Blue theme.  The fix is to draw the
			* background.
			*/
			NMCUSTOMDRAW nmcd = new NMCUSTOMDRAW ();
			OS.MoveMemory (nmcd, lParam, NMCUSTOMDRAW.sizeof);
//			if (drawCount != 0 || !OS.IsWindowVisible (handle)) {
//				if (!OS.IsWinCE && OS.WindowFromDC (nmcd.hdc) == handle) break;
//			}
			switch (nmcd.dwDrawStage) {
				case OS.CDDS_PREERASE: {
					/*
					* Bug in Windows.  When a tool bar does not have the style
					* TBSTYLE_FLAT, the rectangle to be erased in CDDS_PREERASE
					* is empty.  The fix is to draw the whole client area.
					*/
					int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
					if ((bits & OS.TBSTYLE_FLAT) == 0) {
						drawBackground (nmcd.hdc);
					} else {
						RECT rect = new RECT ();
						OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);
						drawBackground (nmcd.hdc, rect);
					}
					return new LRESULT (OS.CDRF_SKIPDEFAULT);
				}
			}
			break;
		case OS.TBN_HOTITEMCHANGE:
			if (!OS.IsWinCE) {
				NMTBHOTITEM lpnmhi = new NMTBHOTITEM ();
				OS.MoveMemory (lpnmhi, lParam, NMTBHOTITEM.sizeof);
				switch (lpnmhi.dwFlags) {
					case OS.HICF_MOUSE: {
						/*
						* Bug in Windows.  When the tool bar has focus, a mouse is
						* in an item and hover help for that item is displayed and
						* then the arrow keys are used to change the hot item,
						* for some reason, Windows snaps the hot item back to the
						* one that is under the mouse.  The fix is to disallow
						* hot item changes when the user is traversing using the
						* arrow keys.
						*/
						if (lastArrowId != -1) return LRESULT.ONE;
						break;
					}
					case OS.HICF_ARROWKEYS:	{
			        	RECT client = new RECT ();
			        	OS.GetClientRect (handle, client);
			        	int index = (int)/*64*/OS.SendMessage (handle, OS.TB_COMMANDTOINDEX, lpnmhi.idNew, 0);
			        	RECT rect = new RECT ();
			        	OS.SendMessage (handle, OS.TB_GETITEMRECT, index, rect);
						if (rect.right > client.right || rect.bottom > client.bottom) {
							return LRESULT.ONE;
						}
						lastArrowId = lpnmhi.idNew;
						break;
					}
					default:
						lastArrowId = -1;
				}
				if ((lpnmhi.dwFlags & OS.HICF_LEAVING) == 0) {
					lastHotId = lpnmhi.idNew;
				}
			}
			break;
	}
	return super.wmNotifyChild (hdr, wParam, lParam);
}

}
