package org.eclipse.swt.ole.win32;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */
import org.eclipse.swt.*;
import org.eclipse.swt.internal.ole.win32.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.internal.*;
import java.util.Enumeration;
import java.util.Vector;

/**
 *
 * OleFrame is an OLE Container's top level frame.
 *
 * <p>This object implements the OLE Interfaces IUnknown and IOleInPlaceFrame
 *
 * <p>OleFrame allows the container to do the following: <ul>
 *	<li>position and size the ActiveX Control or OLE Document within the application
 *	<li>insert menu items from the application into the OLE Document's menu
 *	<li>activate and deactivate the OLE Document's menus
 *	<li>position the OLE Document's menu in the application
 *	<li>translate accelerator keystrokes intended for the container's frame</ul>
 * 
 * <dl>
 *	<dt><b>Styles</b> <dd>BORDER 
 *	<dt><b>Events</b> <dd>Dispose, Move, Resize
 * </dl>
 *
 */
final public class OleFrame extends Composite
{	
	// Interfaces for this Ole Client Container
	private COMObject iUnknown;
	private COMObject iOleInPlaceFrame;

	// Access to the embedded/linked Ole Object 
	private IOleInPlaceActiveObject objIOleInPlaceActiveObject;
	
	private OleClientSite currentdoc;

	private int refCount = 0;
	
	private MenuItem[] fileMenuItems;
	private MenuItem[] containerMenuItems;
	private MenuItem[] windowMenuItems;
	private Menu menubar;

	private InternalListener listener;
	private class InternalListener implements Listener {
		public void handleEvent(Event e) {
			switch (e.type) {
			case SWT.Dispose :
				onDispose(e);
				break;
			case SWT.Resize :
			case SWT.Move :
				onResize(e);
				break;
			default :
				OLE.error(SWT.ERROR_NOT_IMPLEMENTED);
			}
		}
	}
	
	private static String CHECK_FOCUS = "OLE_CHECK_FOCUS";
	private static String HHOOK = "OLE_HHOOK";
	private static String CALLBACK = "OLE_CALLBACK";
	
/**
 * Create an OleFrame child widget using style bits
 * to select a particular look or set of properties.
 *
 * @param parent a composite widget (cannot be null)
 * @param style the bitwise OR'ing of widget styles
 *
 * @exception SWTError
 * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
 *     <li>ERROR_ERROR_NULL_ARGUMENT when the parent is null
 *     <li>ERROR_INTERFACES_NOT_INITIALIZED when unable to create callbacks for OLE Interfaces</ul>
 *
 */
public OleFrame(Composite parent, int style) {
	// set up widget attributes
	super(parent, style | SWT.CLIP_CHILDREN | SWT.CLIP_SIBLINGS);
	
	createCOMInterfaces();

	// setup cleanup proc
	listener = new InternalListener();
	addListener(SWT.Dispose, listener);

	// inform inplaceactiveobject whenever frame resizes
	addListener(SWT.Resize, listener);
	
	// inform inplaceactiveobject whenever frame moves
	addListener(SWT.Move, listener);

	// By default, set the menubar to the current frame's menubar
	menubar = getShell().getMenuBar();

	// Maintain a reference to yourself so that when
	// ClientSites close, they don't take the frame away
	// with them.
	this.AddRef();
	
	// Check for focus change
	Display display = getDisplay();
	initCheckFocus(display);
	initMsgHook(display);
}
private static void initCheckFocus (final Display display) {
	if (display.getData(CHECK_FOCUS) != null) return;
	display.setData(CHECK_FOCUS, CHECK_FOCUS);
	final int time = 50;
	final Runnable[] timer = new Runnable[1];
	final Control[] lastFocus = new Control[1];
	timer[0] = new Runnable() {
		public void run() {
			Control currentFocus = display.getFocusControl();
			if (lastFocus[0] != currentFocus) {
				Event event = new Event();
				if (lastFocus[0] instanceof OleFrame) {
					if (!lastFocus [0].isDisposed()) {
						OleFrame frame = (OleFrame) lastFocus[0];
						OleClientSite client = frame.getCurrentDocument();
						if (client != null) {
							client.notifyListeners (SWT.FocusOut, event);
						}
					}
				}
				if (lastFocus [0] instanceof OleControlSite) {
					if (!lastFocus[0].isDisposed()) {
						lastFocus[0].notifyListeners (SWT.FocusOut, event);
					}
				}
				if (currentFocus instanceof OleFrame) {
					OleFrame frame = (OleFrame) currentFocus;
					OleClientSite client = frame.getCurrentDocument();
					if (client != null) {
						client.notifyListeners (SWT.FocusIn, event);
					}
				}
				if (currentFocus instanceof OleControlSite) {
					currentFocus.notifyListeners(SWT.FocusIn, event);
				}
			}
			lastFocus[0] = currentFocus;
			display.timerExec(time, timer[0]);
		}
	};
	display.timerExec(time, timer[0]);
}
private static void initMsgHook(Display display) {
	if (display.getData(HHOOK) != null) return;
	final Callback callback = new Callback(OleFrame.class, "getMsgProc", 3);
	int address = callback.getAddress();
	int threadId = OS.GetCurrentThreadId();
	final int hHook = OS.SetWindowsHookEx(OS.WH_GETMESSAGE, address, 0, threadId);
	if (hHook == 0) {
		callback.dispose();
		return;
	}
	display.setData(HHOOK, new Integer(hHook));
	display.setData(CALLBACK, callback);
	display.disposeExec(new Runnable() {
		public void run() {
			if (hHook != 0) OS.UnhookWindowsHookEx(hHook);
			if (callback != null) callback.dispose();
		}
	});
}
static int getMsgProc(int code, int wParam, int lParam) {
	Display display = Display.getCurrent();
	if (display == null) return 0;
	Integer hHook = (Integer)display.getData(HHOOK);
	if (hHook == null) return 0;
	if (code < 0) {
		return OS.CallNextHookEx(hHook.intValue(), code, wParam, lParam);
	}
	MSG msg = new MSG();
	OS.MoveMemory(msg, lParam, MSG.sizeof);
	int message = msg.message;
	if (OS.WM_KEYFIRST <= message && message <= OS.WM_KEYLAST) {		
		if (display != null) {
			Widget widget = null;
			int hwnd = msg.hwnd;
			while (hwnd != 0) {
				widget = display.findWidget (hwnd);
				if (widget != null) break;
				hwnd = OS.GetParent (hwnd);
			}
			if (widget != null && widget instanceof OleClientSite) {
				OleClientSite site = (OleClientSite)widget;
				if (site.handle == hwnd) {
					OleFrame frame = site.frame;
					if (frame.translateOleAccelerator(msg)) {
						// In order to prevent this message from also being processed
						// by the application, zero out message, wParam and lParam
						OS.MoveMemory(lParam + 4, new int[] {OS.WM_NULL, 0, 0}, 12);
						return 0;
					}
				}
			}
		}
	}
	return OS.CallNextHookEx(hHook.intValue(), code, wParam, lParam);
}
/**
 * Increment the count of references to this instance
 *
 * @return the current reference count
 */
int AddRef() {
	refCount++;
	return refCount;
}
private int ContextSensitiveHelp(int fEnterMode) {
	return COM.S_OK;
}
private void createCOMInterfaces() {
	// Create each of the interfaces that this object implements
	iUnknown = new COMObject(new int[]{2, 0, 0}){
		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
		public int method1(int[] args) {return AddRef();}
		public int method2(int[] args) {return Release();}
	};
	
	iOleInPlaceFrame = new COMObject(new int[]{2, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 1, 1, 1, 2}){
		public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
		public int method1(int[] args) {return AddRef();}
		public int method2(int[] args) {return Release();}
		public int method3(int[] args) {return GetWindow(args[0]);}
		public int method4(int[] args) {return ContextSensitiveHelp(args[0]);}
		public int method5(int[] args) {return GetBorder(args[0]);}
		public int method6(int[] args) {return RequestBorderSpace(args[0]);}
		public int method7(int[] args) {return SetBorderSpace(args[0]);}
		public int method8(int[] args) {return SetActiveObject(args[0], args[1]);}
		public int method9(int[] args) {return InsertMenus(args[0], args[1]);}
		public int method10(int[] args) {return SetMenu(args[0], args[1], args[2]);}
		public int method11(int[] args) {return RemoveMenus(args[0]);}
		// method12 SetStatusText - not implemented
		// method13 EnableModeless - not implemented
		public int method14(int[] args) {return TranslateAccelerator(args[0], args[1]);}
	};
}
private void disposeCOMInterfaces () {
	
	if (iUnknown != null)
		iUnknown.dispose();
	iUnknown = null;
	
	if (iOleInPlaceFrame != null)
		iOleInPlaceFrame.dispose();
	iOleInPlaceFrame = null;
}
private int GetBorder(int lprectBorder) {
	/*
	The IOleInPlaceUIWindow::GetBorder function, when called on a document or frame window 
	object, returns the outer rectangle (relative to the window) where the object can put 
	toolbars or similar controls.
	*/
	if (lprectBorder == 0) return COM.E_INVALIDARG;
	RECT rectBorder = new RECT();
	// Coordinates must be relative to the window
	OS.GetClientRect(handle, rectBorder);
	OS.MoveMemory(lprectBorder, rectBorder, RECT.sizeof);
	return COM.S_OK;
}
/**
 *
 * Returns the application menu items that will appear in the Container location when an OLE Document 
 * is in-place activated.
 *
 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
 * is given the opportunity to merge some of its menus into the menubar.  The application
 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window 
 * (far right just before Help).  The OLE Document retains control of the Edit, Object and Help
 * menu locations.  Note that an application can insert more than one menu into a single location.
 *
 * @return the application menu items that will appear in the Container location when an OLE Document 
 *         is in-place activated.
 *
 */
public MenuItem[] getContainerMenus(){
	return containerMenuItems;
}
/**
 *
 * Returns the application menu items that will appear in the File location when an OLE Document 
 * is in-place activated.
 *
 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
 * is given the opportunity to merge some of its menus into the menubar.  The application
 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window 
 * (far right just before Help).  The OLE Document retains control of the Edit, Object and Help
 * menu locations.  Note that an application can insert more than one menu into a single location.
 *
 * @return the application menu items that will appear in the File location when an OLE Document 
 *         is in-place activated.
 *
 */
public MenuItem[] getFileMenus(){
	return fileMenuItems;
}
int getIOleInPlaceFrame() {
	return iOleInPlaceFrame.getAddress();
}
Menu getMenubar(){
	return menubar;
}
private int getMenuItemID(int hMenu, int index) {
	int id = 0;
	MENUITEMINFO lpmii = new MENUITEMINFO();
	lpmii.cbSize = MENUITEMINFO.sizeof;
	lpmii.fMask = OS.MIIM_STATE | OS.MIIM_SUBMENU | OS.MIIM_ID;
	OS.GetMenuItemInfo(hMenu, index, true, lpmii);
	if ((lpmii.fState & OS.MF_POPUP) == OS.MF_POPUP) {
		id = lpmii.hSubMenu;
	} else {
		id = lpmii.wID;
	}
	return id;
}
private int GetWindow(int phwnd) {
	if (phwnd != 0) {
		COM.MoveMemory(phwnd, new int[] {handle}, 4);
	}
	return COM.S_OK;
}
/**
 *
 * Returns the application menu items that will appear in the Window location when an OLE Document 
 * is in-place activated.
 *
 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
 * is given the opportunity to merge some of its menus into the menubar.  The application
 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window 
 * (far right just before Help).  The OLE Document retains control of the Edit, Object and Help
 * menu locations.  Note that an application can insert more than one menu into a single location.
 *
 * @return the application menu items that will appear in the Window location when an OLE Document 
 *         is in-place activated.
 *
 */
public MenuItem[] getWindowMenus(){
	return windowMenuItems;
}
private int InsertMenus(int hmenuShared, int lpMenuWidths) {
	// locate menu bar
	if (menubar == null || menubar.isDisposed()) {
		COM.MoveMemory(lpMenuWidths, new int[] {0}, 4);
		return COM.S_OK;
	}
	int hMenu = menubar.handle;

	// Create a holder for menu information.  This will be passed down to
	// the OS and the OS will fill in the requested information for each menu.
	MENUITEMINFO lpmii = new MENUITEMINFO();
	int hHeap = OS.GetProcessHeap();
	int maxTextLength = 128;
	int pszText = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxTextLength);
	lpmii.cbSize = MENUITEMINFO.sizeof;
	lpmii.fMask = OS.MIIM_STATE | OS.MIIM_ID | OS.MIIM_TYPE | OS.MIIM_SUBMENU;
	lpmii.dwTypeData = pszText;
	lpmii.cch = maxTextLength;

	// Loop over all "File-like" menus in the menubar and get information about the
	// item from the OS.
	int fileMenuCount = 0;
	int newindex = 0;
	if (this.fileMenuItems != null) {
		for (int i = 0; i < this.fileMenuItems.length; i++) {
			MenuItem item = this.fileMenuItems[i];
			if (item != null) {
				int index = item.getParent().indexOf(item);
				lpmii.cch = maxTextLength; // lpmii.cch gets updated by GetMenuItemInfo to indicate the 
				                           // exact nuber of characters in name.  Reset it to our max size 
				                           // before each call.
				if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) {
					if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) {
						// keep track of the number of items
						fileMenuCount++;
						newindex++;
					}
				}
			}
		}
	}

	// copy the menu item count information to the pointer
	COM.MoveMemory(lpMenuWidths, new int[] {fileMenuCount}, 4);

	// Loop over all "Container-like" menus in the menubar and get information about the
	// item from the OS.
	int containerMenuCount = 0;
	if (this.containerMenuItems != null) {
		for (int i = 0; i < this.containerMenuItems.length; i++) {
			MenuItem item = this.containerMenuItems[i];
			if (item != null) {
				int index = item.getParent().indexOf(item);
				lpmii.cch = maxTextLength; // lpmii.cch gets updated by GetMenuItemInfo to indicate the 
				                           // exact nuber of characters in name.  Reset it to a large number 
				                           // before each call.
				if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) {
					if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) {
						// keep track of the number of items
						containerMenuCount++;
						newindex++;
					}
				}
			}
		}
	}
	
	// copy the menu item count information to the pointer
	COM.MoveMemory(lpMenuWidths + 8, new int[] {containerMenuCount}, 4);

	// Loop over all "Window-like" menus in the menubar and get information about the
	// item from the OS.
	int windowMenuCount = 0;
	if (this.windowMenuItems != null) {
		for (int i = 0; i < this.windowMenuItems.length; i++) {
			MenuItem item = this.windowMenuItems[i];
			if (item != null) {
				int index = item.getParent().indexOf(item);
				lpmii.cch = maxTextLength; // lpmii.cch gets updated by GetMenuItemInfo to indicate the 
				                           // exact nuber of characters in name.  Reset it to a large number 
				                           // before each call.
				if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) {
					if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) {
						// keep track of the number of items
						windowMenuCount++;
						newindex++;
					}
				}
			}
		}
	}
	
	// copy the menu item count information to the pointer
	COM.MoveMemory(lpMenuWidths + 16, new int[] {windowMenuCount}, 4);
		
	// free resources used in querying the OS
	if (pszText != 0)
		OS.HeapFree(hHeap, 0, pszText);
	return COM.S_OK;
}
private void onDispose(Event e) {

	releaseObjectInterfaces();
	currentdoc = null;

	this.Release();
}
private void onResize(Event e) {
	if (objIOleInPlaceActiveObject != null) {
		RECT lpRect = new RECT();
		OS.GetClientRect(handle, lpRect);
		objIOleInPlaceActiveObject.ResizeBorder(lpRect, iOleInPlaceFrame.getAddress(), true);
	}
}
private int QueryInterface(int riid, int ppvObject) {
//	implements IUnknown, IOleInPlaceFrame, IOleContainer, IOleInPlaceUIWindow
	if (riid == 0 || ppvObject == 0)
		return COM.E_INVALIDARG;
	GUID guid = new GUID();
	COM.MoveMemory(guid, riid, GUID.sizeof);
	if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIOleInPlaceFrame) ) {
		COM.MoveMemory(ppvObject, new int[] {iOleInPlaceFrame.getAddress()}, 4);
		AddRef();
		return COM.S_OK;
	}

	COM.MoveMemory(ppvObject, new int[] {0}, 4);
	return COM.E_NOINTERFACE;
}
/**
 * Decrement the count of references to this instance
 *
 * @return the current reference count
 */
int Release() {
	refCount--;
	if (refCount == 0){
		disposeCOMInterfaces();
		COM.CoFreeUnusedLibraries();
	}
	return refCount;
}
private void releaseObjectInterfaces() {
	if (objIOleInPlaceActiveObject != null) {
		objIOleInPlaceActiveObject.Release();
	}
	objIOleInPlaceActiveObject = null;
}
private int RemoveMenus(int hmenuShared) {

	if (menubar == null || menubar.isDisposed()) return COM.S_FALSE;

	int hMenu = menubar.handle;
	
	Vector ids = new Vector();
	if (this.fileMenuItems != null) {
		for (int i = 0; i < this.fileMenuItems.length; i++) {
			MenuItem item = this.fileMenuItems[i];
			if (item != null && !item.isDisposed()) {
				int index = item.getParent().indexOf(item);
				// get Id from original menubar
				int id = getMenuItemID(hMenu, index);
				ids.addElement(new Integer(id));
			}
		}
	}
	if (this.containerMenuItems != null) {
		for (int i = 0; i < this.containerMenuItems.length; i++) {
			MenuItem item = this.containerMenuItems[i];
			if (item != null && !item.isDisposed()) {
				int index = item.getParent().indexOf(item);
				int id = getMenuItemID(hMenu, index);
				ids.addElement(new Integer(id));
			}
		}
	}
	if (this.windowMenuItems != null) {
		for (int i = 0; i < this.windowMenuItems.length; i++) {
			MenuItem item = this.windowMenuItems[i];
			if (item != null && !item.isDisposed()) {
				int index = item.getParent().indexOf(item);
				int id = getMenuItemID(hMenu, index);
				ids.addElement(new Integer(id));
			}
		}
	}
	int index = OS.GetMenuItemCount(hmenuShared) - 1;
	for (int i = index; i >= 0; i--) {
		int id = getMenuItemID(hmenuShared, i);
		if (ids.contains(new Integer(id))){
			OS.RemoveMenu(hmenuShared, i, OS.MF_BYPOSITION);
		}
	}
	return COM.S_OK;
}
private int RequestBorderSpace(int pborderwidths) {
	return COM.S_OK;
}
int SetActiveObject(int pActiveObject, int pszObjName) {
	if (objIOleInPlaceActiveObject != null) {
		objIOleInPlaceActiveObject.Release();
		objIOleInPlaceActiveObject = null;
	}
	if (pActiveObject != 0) {
		objIOleInPlaceActiveObject = new IOleInPlaceActiveObject(pActiveObject);
		objIOleInPlaceActiveObject.AddRef();
	}

	return COM.S_OK;
}
private int SetBorderSpace(int pborderwidths) {
	// A Control/Document can :
	// Use its own toolbars, requesting border space of a specific size, or, 
	// Use no toolbars, but force the container to remove its toolbars by passing a 
	//   valid BORDERWIDTHS structure containing nothing but zeros in the pborderwidths parameter, or, 
	// Use no toolbars but allow the in-place container to leave its toolbars up by 
	//   passing NULL as the pborderwidths parameter.
	
	RECT borderwidth = new RECT();
	if (pborderwidths == 0 || currentdoc == null ) return COM.S_OK;
		
	COM.MoveMemory(borderwidth, pborderwidths, RECT.sizeof);
	currentdoc.setBorderSpace(borderwidth);

	return COM.S_OK;
}
/**
 *
 * Specify the menu items that should appear in the Container location when an OLE Document 
 * is in-place activated.
 *
 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
 * is given the opportunity to merge some of its menus into the menubar.  The application
 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window 
 * (far right just before Help).  The OLE Document retains control of the Edit, Object and Help
 * menu locations.  Note that an application can insert more than one menu into a single location.
 *
 * <p>This method must be called before in place activation of the OLE Document.  After the Document
 * is activated, the menu bar will not be modified until a subsequent activation.
 *
 * @param containerMenus an array of top level MenuItems to be inserted into the Container location of 
 *        the menubar
 */
public void setContainerMenus(MenuItem[] containerMenus){
	containerMenuItems = containerMenus;
}
OleClientSite getCurrentDocument() {
	return currentdoc;
}
void setCurrentDocument(OleClientSite doc) {
	currentdoc = doc;

	if (currentdoc != null && objIOleInPlaceActiveObject != null) {
		RECT lpRect = new RECT();
		OS.GetClientRect(handle, lpRect);
		objIOleInPlaceActiveObject.ResizeBorder(lpRect, iOleInPlaceFrame.getAddress(), true);
	}
}
/**
 *
 * Specify the menu items that should appear in the File location when an OLE Document 
 * is in-place activated.
 *
 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
 * is given the opportunity to merge some of its menus into the menubar.  The application
 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window 
 * (far right just before Help).  The OLE Document retains control of the Edit, Object and Help
 * menu locations.  Note that an application can insert more than one menu into a single location.
 *
 * <p>This method must be called before in place activation of the OLE Document.  After the Document
 * is activated, the menu bar will not be modified until a subsequent activation.
 *
 * @param fileMenus an array of top level MenuItems to be inserted into the Flie location of 
 *        the menubar
 */
public void setFileMenus(MenuItem[] fileMenus){
	fileMenuItems = fileMenus;
}
public boolean forceFocus () {
	if (currentdoc == null)	return super.forceFocus();
	return currentdoc.forceFocus();
}
private int SetMenu(int hmenuShared, int holemenu, int hwndActiveObject) {

	int inPlaceActiveObject = 0;
	if (objIOleInPlaceActiveObject != null)
		inPlaceActiveObject = objIOleInPlaceActiveObject.getAddress();		
	
	if (menubar == null || menubar.isDisposed()){
		return COM.OleSetMenuDescriptor(0, getShell().handle, hwndActiveObject, iOleInPlaceFrame.getAddress(), inPlaceActiveObject);
	}
	
	int handle = menubar.getShell().handle;
	
	if (hmenuShared == 0 && holemenu == 0) {
		// re-instate the original menu - this occurs on deactivation
		hmenuShared = menubar.handle;
	}
	if (hmenuShared == 0) return COM.E_FAIL;
	
	OS.SetMenu(handle, hmenuShared);
	OS.DrawMenuBar(handle);
	
	return COM.OleSetMenuDescriptor(holemenu, handle, hwndActiveObject, iOleInPlaceFrame.getAddress(), inPlaceActiveObject);
}
private void setMenubar(Menu bar){
	menubar = bar;
}
/**
 *
 * Set the menu items that should appear in the Window location when an OLE Document 
 * is in-place activated.
 *
 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
 * is given the opportunity to merge some of its menus into the menubar.  The application
 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window 
 * (far right just before Help).  The OLE Document retains control of the Edit, Object and Help
 * menu locations.  Note that an application can insert more than one menu into a single location.
 *
 * <p>This method must be called before in place activation of the OLE Document.  After the Document
 * is activated, the menu bar will not be modified until a subsequent activation.
 *
 * @param windowMenus an array of top level MenuItems to be inserted into the Window location of 
 *        the menubar
 */
public void setWindowMenus(MenuItem[] windowMenus){
	windowMenuItems = windowMenus;
}
private boolean translateOleAccelerator(MSG msg) {
	if (objIOleInPlaceActiveObject == null) return false;
	return objIOleInPlaceActiveObject.TranslateAccelerator(msg) != OLE.S_FALSE;
}
private int TranslateAccelerator(int lpmsg, int wID){
	if (menubar == null || menubar.isDisposed() || !menubar.isEnabled()) return COM.S_FALSE;
	if (wID < 0) return COM.S_FALSE;
	
	Shell shell = menubar.getShell();
	int hwnd = shell.handle;
	int hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
	if (hAccel == 0) return COM.S_FALSE;
	
	MSG msg = new MSG();
	OS.MoveMemory(msg, lpmsg, MSG.sizeof);
	int result = OS.TranslateAccelerator(hwnd, hAccel, msg);
	return result == 0 ? COM.S_FALSE : COM.S_OK;
}
}
