X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.eclipse.swt.win32.win32.x86_64%2Fsrc%2Forg%2Feclipse%2Fswt%2Fole%2Fwin32%2FOleFrame.java;fp=bundles%2Forg.eclipse.swt.win32.win32.x86_64%2Fsrc%2Forg%2Feclipse%2Fswt%2Fole%2Fwin32%2FOleFrame.java;h=b6bd46ca491d3fa3009aedcf812edb19327ab560;hb=6b98970d0458754dd67f789afbd0a39e1e7ac6eb;hp=0000000000000000000000000000000000000000;hpb=56a61575ce0d27b340cb12438c8a7f303842095e;p=simantics%2Fplatform.git diff --git a/bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/ole/win32/OleFrame.java b/bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/ole/win32/OleFrame.java new file mode 100644 index 000000000..b6bd46ca4 --- /dev/null +++ b/bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/ole/win32/OleFrame.java @@ -0,0 +1,823 @@ +/******************************************************************************* + * Copyright (c) 2000, 2019 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.ole.win32; + +import java.util.*; +import java.util.List; + +import org.eclipse.swt.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.ole.win32.*; +import org.eclipse.swt.internal.win32.*; +import org.eclipse.swt.widgets.*; + +/** + * + * OleFrame is an OLE Container's top level frame. + * + *
This object implements the OLE Interfaces IUnknown and IOleInPlaceFrame + * + *
OleFrame allows the container to do the following:
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. + * + *
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; +} +long getIOleInPlaceFrame() { + return iOleInPlaceFrame.getAddress(); +} +private long getMenuItemID(long hMenu, int index) { + long 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(long phwnd) { + if (phwnd != 0) { + OS.MoveMemory(phwnd, new long[] {handle}, C.PTR_SIZEOF); + } + return COM.S_OK; +} +/** + * + * Returns the application menu items that will appear in the Window location when an OLE Document + * is in-place activated. + * + *
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(long hmenuShared, long lpMenuWidths) {
+ // locate menu bar
+ Menu menubar = getShell().getMenuBar();
+ if (menubar == null || menubar.isDisposed()) {
+ OS.MoveMemory(lpMenuWidths, new int[] {0}, 4);
+ return COM.S_OK;
+ }
+ long 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();
+ long hHeap = OS.GetProcessHeap();
+ int cch = 128;
+ int byteCount = cch * TCHAR.sizeof;
+ long pszText = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
+ lpmii.cbSize = MENUITEMINFO.sizeof;
+ lpmii.fMask = OS.MIIM_STATE | OS.MIIM_ID | OS.MIIM_TYPE | OS.MIIM_SUBMENU | OS.MIIM_DATA;
+ lpmii.dwTypeData = pszText;
+ lpmii.cch = cch;
+
+ // 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 = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the
+ // exact number 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
+ OS.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 = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the
+ // exact number 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
+ OS.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 = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the
+ // exact number 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
+ OS.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;
+}
+void onActivate(Event e) {
+ if (objIOleInPlaceActiveObject != null) {
+ objIOleInPlaceActiveObject.OnFrameWindowActivate(true);
+ }
+}
+void onDeactivate(Event e) {
+ if (objIOleInPlaceActiveObject != null) {
+ objIOleInPlaceActiveObject.OnFrameWindowActivate(false);
+ }
+}
+private void onDispose(Event e) {
+
+ releaseObjectInterfaces();
+ currentdoc = null;
+
+ this.Release();
+ removeListener(SWT.Activate, listener);
+ removeListener(SWT.Deactivate, listener);
+ removeListener(SWT.Dispose, listener);
+ removeListener(SWT.Resize, listener);
+ removeListener(SWT.Move, listener);
+}
+void onFocusIn(Event e) {
+ if (lastActivatedMenuHandle != newMenuHandle)
+ currentdoc.doVerb(OLE.OLEIVERB_SHOW);
+ if (OS.GetMenu(shellHandle) != newMenuHandle)
+ OS.SetMenu(shellHandle, newMenuHandle);
+}
+void onFocusOut(Event e) {
+ Control control = getDisplay().getFocusControl();
+ if (OS.GetMenu(shellHandle) != oldMenuHandle && control != null && control.handle != shellHandle)
+ OS.SetMenu(shellHandle, oldMenuHandle);
+}
+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(long riid, long 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) ) {
+ OS.MoveMemory(ppvObject, new long [] {iOleInPlaceFrame.getAddress()}, C.PTR_SIZEOF);
+ AddRef();
+ return COM.S_OK;
+ }
+
+ OS.MoveMemory(ppvObject, new long [] {0}, C.PTR_SIZEOF);
+ return COM.E_NOINTERFACE;
+}
+/**
+ * Decrement the count of references to this instance
+ *
+ * @return the current reference count
+ */
+int Release() {
+ refCount--;
+ if (refCount == 0){
+ disposeCOMInterfaces();
+ if (COM.FreeUnusedLibraries) {
+ COM.CoFreeUnusedLibraries();
+ }
+ }
+ return refCount;
+}
+private void releaseObjectInterfaces() {
+ if (objIOleInPlaceActiveObject != null) {
+ objIOleInPlaceActiveObject.Release();
+ }
+ objIOleInPlaceActiveObject = null;
+}
+private int RemoveMenus(long hmenuShared) {
+
+ Menu menubar = getShell().getMenuBar();
+ if (menubar == null || menubar.isDisposed()) return COM.S_FALSE;
+
+ long hMenu = menubar.handle;
+
+ List 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.
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * 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 File location of
+ * the menubar
+ */
+public void setFileMenus(MenuItem[] fileMenus){
+ fileMenuItems = fileMenus;
+}
+private int SetMenu(long hmenuShared, long holemenu, long hwndActiveObject) {
+ long inPlaceActiveObject = 0;
+ if (objIOleInPlaceActiveObject != null)
+ inPlaceActiveObject = objIOleInPlaceActiveObject.getAddress();
+
+ Menu menubar = getShell().getMenuBar();
+ if (menubar == null || menubar.isDisposed()){
+ return COM.OleSetMenuDescriptor(0, getShell().handle, hwndActiveObject, iOleInPlaceFrame.getAddress(), inPlaceActiveObject);
+ }
+
+ long 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;
+
+ shellHandle = handle;
+ oldMenuHandle = menubar.handle;
+ newMenuHandle = hmenuShared;
+ lastActivatedMenuHandle = newMenuHandle;
+
+ return COM.OleSetMenuDescriptor(holemenu, handle, hwndActiveObject, iOleInPlaceFrame.getAddress(), inPlaceActiveObject);
+}
+/**
+ *
+ * Set the menu items that should appear in the Window location when an OLE Document
+ * is in-place activated.
+ *
+ * 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.
+ *
+ * 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;
+ int result = objIOleInPlaceActiveObject.TranslateAccelerator(msg);
+ return (result != COM.S_FALSE && result != COM.E_NOTIMPL);
+}
+private int TranslateAccelerator(long lpmsg, int wID){
+ Menu menubar = getShell().getMenuBar();
+ if (menubar == null || menubar.isDisposed() || !menubar.isEnabled()) return COM.S_FALSE;
+ if (wID < 0) return COM.S_FALSE;
+
+ Shell shell = menubar.getShell();
+ long hwnd = shell.handle;
+ long 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;
+}
+}