KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > ole > win32 > OleFrame


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.ole.win32;
12
13 import org.eclipse.swt.*;
14 import org.eclipse.swt.internal.ole.win32.*;
15 import org.eclipse.swt.widgets.*;
16 import org.eclipse.swt.internal.win32.*;
17 import org.eclipse.swt.internal.*;
18 import java.util.Vector JavaDoc;
19
20 /**
21  *
22  * OleFrame is an OLE Container's top level frame.
23  *
24  * <p>This object implements the OLE Interfaces IUnknown and IOleInPlaceFrame
25  *
26  * <p>OleFrame allows the container to do the following: <ul>
27  * <li>position and size the ActiveX Control or OLE Document within the application
28  * <li>insert menu items from the application into the OLE Document's menu
29  * <li>activate and deactivate the OLE Document's menus
30  * <li>position the OLE Document's menu in the application
31  * <li>translate accelerator keystrokes intended for the container's frame</ul>
32  *
33  * <dl>
34  * <dt><b>Styles</b> <dd>BORDER
35  * <dt><b>Events</b> <dd>Dispose, Move, Resize
36  * </dl>
37  *
38  */

39 final public class OleFrame extends Composite
40 {
41     // Interfaces for this Ole Client Container
42
private COMObject iUnknown;
43     private COMObject iOleInPlaceFrame;
44
45     // Access to the embedded/linked Ole Object
46
private IOleInPlaceActiveObject objIOleInPlaceActiveObject;
47     
48     private OleClientSite currentdoc;
49
50     private int refCount = 0;
51     
52     private MenuItem[] fileMenuItems;
53     private MenuItem[] containerMenuItems;
54     private MenuItem[] windowMenuItems;
55
56     private Listener listener;
57     
58     private static String JavaDoc CHECK_FOCUS = "OLE_CHECK_FOCUS"; //$NON-NLS-1$
59
private static String JavaDoc HHOOK = "OLE_HHOOK"; //$NON-NLS-1$
60
private static String JavaDoc HHOOKMSG = "OLE_HHOOK_MSG"; //$NON-NLS-1$
61

62     private static boolean ignoreNextKey;
63     private static final short [] ACCENTS = new short [] {'~', '`', '\'', '^', '"'};
64     
65     private static final String JavaDoc CONSUME_KEY = "org.eclipse.swt.OleFrame.ConsumeKey"; //$NON-NLS-1$
66

67 /**
68  * Create an OleFrame child widget using style bits
69  * to select a particular look or set of properties.
70  *
71  * @param parent a composite widget (cannot be null)
72  * @param style the bitwise OR'ing of widget styles
73  *
74  * @exception IllegalArgumentException <ul>
75  * <li>ERROR_NULL_ARGUMENT when the parent is null
76  * </ul>
77  * @exception SWTException <ul>
78  * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
79  * </ul>
80  *
81  */

82 public OleFrame(Composite parent, int style) {
83     super(parent, style);
84     
85     createCOMInterfaces();
86
87     // setup cleanup proc
88
listener = new Listener() {
89         public void handleEvent(Event e) {
90             switch (e.type) {
91             case SWT.Activate : onActivate(e); break;
92             case SWT.Deactivate : onDeactivate(e); break;
93             case SWT.Dispose : onDispose(e); break;
94             case SWT.Resize :
95             case SWT.Move : onResize(e); break;
96             default :
97                 OLE.error(SWT.ERROR_NOT_IMPLEMENTED);
98             }
99         }
100     };
101     
102
103     addListener(SWT.Activate, listener);
104     addListener(SWT.Deactivate, listener);
105     addListener(SWT.Dispose, listener);
106
107     // inform inplaceactiveobject whenever frame resizes
108
addListener(SWT.Resize, listener);
109     
110     // inform inplaceactiveobject whenever frame moves
111
addListener(SWT.Move, listener);
112
113     // Maintain a reference to yourself so that when
114
// ClientSites close, they don't take the frame away
115
// with them.
116
this.AddRef();
117     
118     // Check for focus change
119
Display display = getDisplay();
120     initCheckFocus(display);
121     initMsgHook(display);
122 }
123 private static void initCheckFocus (final Display display) {
124     if (display.getData(CHECK_FOCUS) != null) return;
125     display.setData(CHECK_FOCUS, CHECK_FOCUS);
126     final int time = 50;
127     final Runnable JavaDoc[] timer = new Runnable JavaDoc[1];
128     final Control[] lastFocus = new Control[1];
129     timer[0] = new Runnable JavaDoc() {
130         public void run() {
131             if (lastFocus[0] instanceof OleClientSite && !lastFocus[0].isDisposed()) {
132                 // ignore popup menus and dialogs
133
int hwnd = OS.GetFocus();
134                 while (hwnd != 0) {
135                     int ownerHwnd = OS.GetWindow(hwnd, OS.GW_OWNER);
136                     if (ownerHwnd != 0) {
137                         display.timerExec(time, timer[0]);
138                         return;
139                     }
140                     hwnd = OS.GetParent(hwnd);
141                 }
142             }
143             if (lastFocus[0] == null || lastFocus[0].isDisposed() || !lastFocus[0].isFocusControl()) {
144                 Control currentFocus = display.getFocusControl();
145                 if (currentFocus instanceof OleFrame) {
146                     OleFrame frame = (OleFrame) currentFocus;
147                     currentFocus = frame.getCurrentDocument();
148                 }
149                 if (lastFocus[0] != currentFocus) {
150                     Event event = new Event();
151                     if (lastFocus[0] instanceof OleClientSite && !lastFocus[0].isDisposed()) {
152                         lastFocus[0].notifyListeners (SWT.FocusOut, event);
153                     }
154                     if (currentFocus instanceof OleClientSite && !currentFocus.isDisposed()) {
155                         currentFocus.notifyListeners(SWT.FocusIn, event);
156                     }
157                 }
158                 lastFocus[0] = currentFocus;
159             }
160             display.timerExec(time, timer[0]);
161         }
162     };
163     display.timerExec(time, timer[0]);
164 }
165 private static void initMsgHook(Display display) {
166     if (display.getData(HHOOK) != null) return;
167     final Callback callback = new Callback(OleFrame.class, "getMsgProc", 3); //$NON-NLS-1$
168
int address = callback.getAddress();
169     if (address == 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);
170     int threadId = OS.GetCurrentThreadId();
171     final int hHook = OS.SetWindowsHookEx(OS.WH_GETMESSAGE, address, 0, threadId);
172     if (hHook == 0) {
173         callback.dispose();
174         return;
175     }
176     display.setData(HHOOK, new Integer JavaDoc(hHook));
177     display.setData(HHOOKMSG, new MSG());
178     display.disposeExec(new Runnable JavaDoc() {
179         public void run() {
180             if (hHook != 0) OS.UnhookWindowsHookEx(hHook);
181             if (callback != null) callback.dispose();
182         }
183     });
184 }
185 static int getMsgProc(int code, int wParam, int lParam) {
186     Display display = Display.getCurrent();
187     if (display == null) return 0;
188     Integer JavaDoc hHook = (Integer JavaDoc)display.getData(HHOOK);
189     if (hHook == null) return 0;
190     if (code < 0) {
191         return OS.CallNextHookEx(hHook.intValue(), code, wParam, lParam);
192     }
193     MSG msg = (MSG)display.getData(HHOOKMSG);
194     OS.MoveMemory(msg, lParam, MSG.sizeof);
195     int message = msg.message;
196     if (OS.WM_KEYFIRST <= message && message <= OS.WM_KEYLAST) {
197         if (display != null) {
198             Widget widget = null;
199             int hwnd = msg.hwnd;
200             while (hwnd != 0) {
201                 widget = display.findWidget (hwnd);
202                 if (widget != null) break;
203                 hwnd = OS.GetParent (hwnd);
204             }
205             if (widget != null && widget instanceof OleClientSite) {
206                 OleClientSite site = (OleClientSite)widget;
207                 if (site.handle == hwnd) {
208                     boolean consumed = false;
209                     /* Allow activeX control to translate accelerators except when a menu is active. */
210                     int thread = OS.GetWindowThreadProcessId(msg.hwnd, null);
211                     GUITHREADINFO lpgui = new GUITHREADINFO();
212                     lpgui.cbSize = GUITHREADINFO.sizeof;
213                     boolean rc = OS.GetGUIThreadInfo(thread, lpgui);
214                     int mask = OS.GUI_INMENUMODE | OS.GUI_INMOVESIZE | OS.GUI_POPUPMENUMODE | OS.GUI_SYSTEMMENUMODE;
215                     if (!rc || (lpgui.flags & mask) == 0) {
216                         OleFrame frame = site.frame;
217                         frame.setData(CONSUME_KEY, null);
218                         consumed = frame.translateOleAccelerator(msg);
219                         if (frame.getData(CONSUME_KEY) != null) consumed = false;
220                         frame.setData(CONSUME_KEY, null);
221                     }
222                     boolean accentKey = false;
223                     switch (msg.message) {
224                         case OS.WM_KEYDOWN:
225                         case OS.WM_SYSKEYDOWN: {
226                             if (!OS.IsWinCE) {
227                                 switch (msg.wParam) {
228                                     case OS.VK_SHIFT:
229                                     case OS.VK_MENU:
230                                     case OS.VK_CONTROL:
231                                     case OS.VK_CAPITAL:
232                                     case OS.VK_NUMLOCK:
233                                     case OS.VK_SCROLL:
234                                         break;
235                                     default: {
236                                         /*
237                                         * Bug in Windows. The high bit in the result of MapVirtualKey() on
238                                         * Windows NT is bit 32 while the high bit on Windows 95 is bit 16.
239                                         * They should both be bit 32. The fix is to test the right bit.
240                                         */

241                                         int mapKey = OS.MapVirtualKey (msg.wParam, 2);
242                                         if (mapKey != 0) {
243                                             accentKey = (mapKey & (OS.IsWinNT ? 0x80000000 : 0x8000)) != 0;
244                                             if (!accentKey) {
245                                                 for (int i=0; i<ACCENTS.length; i++) {
246                                                     int value = OS.VkKeyScan (ACCENTS [i]);
247                                                     if (value != -1 && (value & 0xFF) == msg.wParam) {
248                                                         int state = value >> 8;
249                                                         if ((OS.GetKeyState (OS.VK_SHIFT) < 0) == ((state & 0x1) != 0) &&
250                                                             (OS.GetKeyState (OS.VK_CONTROL) < 0) == ((state & 0x2) != 0) &&
251                                                             (OS.GetKeyState (OS.VK_MENU) < 0) == ((state & 0x4) != 0)) {
252                                                                 if ((state & 0x7) != 0) accentKey = true;
253                                                                 break;
254                                                         }
255                                                     }
256                                                 }
257                                             }
258                                         }
259                                         break;
260                                     }
261                                 }
262                             }
263                             break;
264                         }
265                     }
266                     /* Allow OleClientSite to process key events before activeX control */
267                     if (!consumed && !accentKey && !ignoreNextKey) {
268                         int hwndOld = msg.hwnd;
269                         msg.hwnd = site.handle;
270                         consumed = OS.DispatchMessage (msg) == 1;
271                         msg.hwnd = hwndOld;
272                     }
273                     switch (msg.message) {
274                         case OS.WM_KEYDOWN:
275                         case OS.WM_SYSKEYDOWN: {
276                             switch (msg.wParam) {
277                                 case OS.VK_SHIFT:
278                                 case OS.VK_MENU:
279                                 case OS.VK_CONTROL:
280                                 case OS.VK_CAPITAL:
281                                 case OS.VK_NUMLOCK:
282                                 case OS.VK_SCROLL:
283                                     break;
284                                 default: {
285                                     ignoreNextKey = accentKey;
286                                     break;
287                                 }
288                             }
289                         }
290                     }
291
292                     if (consumed) {
293                         // In order to prevent this message from also being processed
294
// by the application, zero out message, wParam and lParam
295
msg.message = OS.WM_NULL;
296                         msg.wParam = msg.lParam = 0;
297                         OS.MoveMemory(lParam, msg, MSG.sizeof);
298                         return 0;
299                     }
300                 }
301             }
302         }
303     }
304     return OS.CallNextHookEx(hHook.intValue(), code, wParam, lParam);
305 }
306 /**
307  * Increment the count of references to this instance
308  *
309  * @return the current reference count
310  */

311 int AddRef() {
312     refCount++;
313     return refCount;
314 }
315 private int ContextSensitiveHelp(int fEnterMode) {
316     return COM.S_OK;
317 }
318 private void createCOMInterfaces() {
319     // Create each of the interfaces that this object implements
320
iUnknown = new COMObject(new int[]{2, 0, 0}){
321         public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
322         public int method1(int[] args) {return AddRef();}
323         public int method2(int[] args) {return Release();}
324     };
325     
326     iOleInPlaceFrame = new COMObject(new int[]{2, 0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 1, 1, 1, 2}){
327         public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
328         public int method1(int[] args) {return AddRef();}
329         public int method2(int[] args) {return Release();}
330         public int method3(int[] args) {return GetWindow(args[0]);}
331         public int method4(int[] args) {return ContextSensitiveHelp(args[0]);}
332         public int method5(int[] args) {return GetBorder(args[0]);}
333         public int method6(int[] args) {return RequestBorderSpace(args[0]);}
334         public int method7(int[] args) {return SetBorderSpace(args[0]);}
335         public int method8(int[] args) {return SetActiveObject(args[0], args[1]);}
336         public int method9(int[] args) {return InsertMenus(args[0], args[1]);}
337         public int method10(int[] args) {return SetMenu(args[0], args[1], args[2]);}
338         public int method11(int[] args) {return RemoveMenus(args[0]);}
339         // method12 SetStatusText - not implemented
340
// method13 EnableModeless - not implemented
341
public int method14(int[] args) {return TranslateAccelerator(args[0], args[1]);}
342     };
343 }
344 private void disposeCOMInterfaces () {
345     
346     if (iUnknown != null)
347         iUnknown.dispose();
348     iUnknown = null;
349     
350     if (iOleInPlaceFrame != null)
351         iOleInPlaceFrame.dispose();
352     iOleInPlaceFrame = null;
353 }
354 private int GetBorder(int lprectBorder) {
355     /*
356     The IOleInPlaceUIWindow::GetBorder function, when called on a document or frame window
357     object, returns the outer rectangle (relative to the window) where the object can put
358     toolbars or similar controls.
359     */

360     if (lprectBorder == 0) return COM.E_INVALIDARG;
361     RECT rectBorder = new RECT();
362     // Coordinates must be relative to the window
363
OS.GetClientRect(handle, rectBorder);
364     OS.MoveMemory(lprectBorder, rectBorder, RECT.sizeof);
365     return COM.S_OK;
366 }
367 /**
368  *
369  * Returns the application menu items that will appear in the Container location when an OLE Document
370  * is in-place activated.
371  *
372  * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
373  * is given the opportunity to merge some of its menus into the menubar. The application
374  * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
375  * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
376  * menu locations. Note that an application can insert more than one menu into a single location.
377  *
378  * @return the application menu items that will appear in the Container location when an OLE Document
379  * is in-place activated.
380  *
381  */

382 public MenuItem[] getContainerMenus(){
383     return containerMenuItems;
384 }
385 /**
386  *
387  * Returns the application menu items that will appear in the File location when an OLE Document
388  * is in-place activated.
389  *
390  * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
391  * is given the opportunity to merge some of its menus into the menubar. The application
392  * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
393  * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
394  * menu locations. Note that an application can insert more than one menu into a single location.
395  *
396  * @return the application menu items that will appear in the File location when an OLE Document
397  * is in-place activated.
398  *
399  */

400 public MenuItem[] getFileMenus(){
401     return fileMenuItems;
402 }
403 int getIOleInPlaceFrame() {
404     return iOleInPlaceFrame.getAddress();
405 }
406 private int getMenuItemID(int hMenu, int index) {
407     int id = 0;
408     MENUITEMINFO lpmii = new MENUITEMINFO();
409     lpmii.cbSize = MENUITEMINFO.sizeof;
410     lpmii.fMask = OS.MIIM_STATE | OS.MIIM_SUBMENU | OS.MIIM_ID;
411     OS.GetMenuItemInfo(hMenu, index, true, lpmii);
412     if ((lpmii.fState & OS.MF_POPUP) == OS.MF_POPUP) {
413         id = lpmii.hSubMenu;
414     } else {
415         id = lpmii.wID;
416     }
417     return id;
418 }
419 private int GetWindow(int phwnd) {
420     if (phwnd != 0) {
421         COM.MoveMemory(phwnd, new int[] {handle}, 4);
422     }
423     return COM.S_OK;
424 }
425 /**
426  *
427  * Returns the application menu items that will appear in the Window location when an OLE Document
428  * is in-place activated.
429  *
430  * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
431  * is given the opportunity to merge some of its menus into the menubar. The application
432  * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
433  * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
434  * menu locations. Note that an application can insert more than one menu into a single location.
435  *
436  * @return the application menu items that will appear in the Window location when an OLE Document
437  * is in-place activated.
438  *
439  */

440 public MenuItem[] getWindowMenus(){
441     return windowMenuItems;
442 }
443 private int InsertMenus(int hmenuShared, int lpMenuWidths) {
444     // locate menu bar
445
Menu menubar = getShell().getMenuBar();
446     if (menubar == null || menubar.isDisposed()) {
447         COM.MoveMemory(lpMenuWidths, new int[] {0}, 4);
448         return COM.S_OK;
449     }
450     int hMenu = menubar.handle;
451
452     // Create a holder for menu information. This will be passed down to
453
// the OS and the OS will fill in the requested information for each menu.
454
MENUITEMINFO lpmii = new MENUITEMINFO();
455     int hHeap = OS.GetProcessHeap();
456     int cch = 128;
457     int byteCount = cch * TCHAR.sizeof;
458     int pszText = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
459     lpmii.cbSize = MENUITEMINFO.sizeof;
460     lpmii.fMask = OS.MIIM_STATE | OS.MIIM_ID | OS.MIIM_TYPE | OS.MIIM_SUBMENU | OS.MIIM_DATA;
461     lpmii.dwTypeData = pszText;
462     lpmii.cch = cch;
463
464     // Loop over all "File-like" menus in the menubar and get information about the
465
// item from the OS.
466
int fileMenuCount = 0;
467     int newindex = 0;
468     if (this.fileMenuItems != null) {
469         for (int i = 0; i < this.fileMenuItems.length; i++) {
470             MenuItem item = this.fileMenuItems[i];
471             if (item != null) {
472                 int index = item.getParent().indexOf(item);
473                 lpmii.cch = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the
474
// exact number of characters in name. Reset it to our max size
475
// before each call.
476
if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) {
477                     if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) {
478                         // keep track of the number of items
479
fileMenuCount++;
480                         newindex++;
481                     }
482                 }
483             }
484         }
485     }
486
487     // copy the menu item count information to the pointer
488
COM.MoveMemory(lpMenuWidths, new int[] {fileMenuCount}, 4);
489
490     // Loop over all "Container-like" menus in the menubar and get information about the
491
// item from the OS.
492
int containerMenuCount = 0;
493     if (this.containerMenuItems != null) {
494         for (int i = 0; i < this.containerMenuItems.length; i++) {
495             MenuItem item = this.containerMenuItems[i];
496             if (item != null) {
497                 int index = item.getParent().indexOf(item);
498                 lpmii.cch = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the
499
// exact number of characters in name. Reset it to a large number
500
// before each call.
501
if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) {
502                     if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) {
503                         // keep track of the number of items
504
containerMenuCount++;
505                         newindex++;
506                     }
507                 }
508             }
509         }
510     }
511     
512     // copy the menu item count information to the pointer
513
COM.MoveMemory(lpMenuWidths + 8, new int[] {containerMenuCount}, 4);
514
515     // Loop over all "Window-like" menus in the menubar and get information about the
516
// item from the OS.
517
int windowMenuCount = 0;
518     if (this.windowMenuItems != null) {
519         for (int i = 0; i < this.windowMenuItems.length; i++) {
520             MenuItem item = this.windowMenuItems[i];
521             if (item != null) {
522                 int index = item.getParent().indexOf(item);
523                 lpmii.cch = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the
524
// exact number of characters in name. Reset it to a large number
525
// before each call.
526
if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) {
527                     if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) {
528                         // keep track of the number of items
529
windowMenuCount++;
530                         newindex++;
531                     }
532                 }
533             }
534         }
535     }
536     
537     // copy the menu item count information to the pointer
538
COM.MoveMemory(lpMenuWidths + 16, new int[] {windowMenuCount}, 4);
539         
540     // free resources used in querying the OS
541
if (pszText != 0)
542         OS.HeapFree(hHeap, 0, pszText);
543     return COM.S_OK;
544 }
545 void onActivate(Event e) {
546     if (objIOleInPlaceActiveObject != null) {
547         objIOleInPlaceActiveObject.OnFrameWindowActivate(true);
548     }
549     if (objIOleInPlaceActiveObject != null) {
550         objIOleInPlaceActiveObject.OnDocWindowActivate(true);
551     }
552 }
553 void onDeactivate(Event e) {
554     if (objIOleInPlaceActiveObject != null) {
555         objIOleInPlaceActiveObject.OnFrameWindowActivate(false);
556     }
557     if (objIOleInPlaceActiveObject != null) {
558         objIOleInPlaceActiveObject.OnDocWindowActivate(false);
559     }
560 }
561 private void onDispose(Event e) {
562
563     releaseObjectInterfaces();
564     currentdoc = null;
565
566     this.Release();
567     removeListener(SWT.Activate, listener);
568     removeListener(SWT.Deactivate, listener);
569     removeListener(SWT.Dispose, listener);
570     removeListener(SWT.Resize, listener);
571     removeListener(SWT.Move, listener);
572 }
573 private void onResize(Event e) {
574     if (objIOleInPlaceActiveObject != null) {
575         RECT lpRect = new RECT();
576         OS.GetClientRect(handle, lpRect);
577         objIOleInPlaceActiveObject.ResizeBorder(lpRect, iOleInPlaceFrame.getAddress(), true);
578     }
579 }
580 private int QueryInterface(int riid, int ppvObject) {
581 // implements IUnknown, IOleInPlaceFrame, IOleContainer, IOleInPlaceUIWindow
582
if (riid == 0 || ppvObject == 0)
583         return COM.E_INVALIDARG;
584     GUID guid = new GUID();
585     COM.MoveMemory(guid, riid, GUID.sizeof);
586     if (COM.IsEqualGUID(guid, COM.IIDIUnknown) || COM.IsEqualGUID(guid, COM.IIDIOleInPlaceFrame) ) {
587         COM.MoveMemory(ppvObject, new int[] {iOleInPlaceFrame.getAddress()}, 4);
588         AddRef();
589         return COM.S_OK;
590     }
591
592     COM.MoveMemory(ppvObject, new int[] {0}, 4);
593     return COM.E_NOINTERFACE;
594 }
595 /**
596  * Decrement the count of references to this instance
597  *
598  * @return the current reference count
599  */

600 int Release() {
601     refCount--;
602     if (refCount == 0){
603         disposeCOMInterfaces();
604         COM.CoFreeUnusedLibraries();
605     }
606     return refCount;
607 }
608 private void releaseObjectInterfaces() {
609     if (objIOleInPlaceActiveObject != null) {
610         objIOleInPlaceActiveObject.Release();
611     }
612     objIOleInPlaceActiveObject = null;
613 }
614 private int RemoveMenus(int hmenuShared) {
615
616     Menu menubar = getShell().getMenuBar();
617     if (menubar == null || menubar.isDisposed()) return COM.S_FALSE;
618
619     int hMenu = menubar.handle;
620     
621     Vector JavaDoc ids = new Vector JavaDoc();
622     if (this.fileMenuItems != null) {
623         for (int i = 0; i < this.fileMenuItems.length; i++) {
624             MenuItem item = this.fileMenuItems[i];
625             if (item != null && !item.isDisposed()) {
626                 int index = item.getParent().indexOf(item);
627                 // get Id from original menubar
628
int id = getMenuItemID(hMenu, index);
629                 ids.addElement(new Integer JavaDoc(id));
630             }
631         }
632     }
633     if (this.containerMenuItems != null) {
634         for (int i = 0; i < this.containerMenuItems.length; i++) {
635             MenuItem item = this.containerMenuItems[i];
636             if (item != null && !item.isDisposed()) {
637                 int index = item.getParent().indexOf(item);
638                 int id = getMenuItemID(hMenu, index);
639                 ids.addElement(new Integer JavaDoc(id));
640             }
641         }
642     }
643     if (this.windowMenuItems != null) {
644         for (int i = 0; i < this.windowMenuItems.length; i++) {
645             MenuItem item = this.windowMenuItems[i];
646             if (item != null && !item.isDisposed()) {
647                 int index = item.getParent().indexOf(item);
648                 int id = getMenuItemID(hMenu, index);
649                 ids.addElement(new Integer JavaDoc(id));
650             }
651         }
652     }
653     int index = OS.GetMenuItemCount(hmenuShared) - 1;
654     for (int i = index; i >= 0; i--) {
655         int id = getMenuItemID(hmenuShared, i);
656         if (ids.contains(new Integer JavaDoc(id))){
657             OS.RemoveMenu(hmenuShared, i, OS.MF_BYPOSITION);
658         }
659     }
660     return COM.S_OK;
661 }
662 private int RequestBorderSpace(int pborderwidths) {
663     return COM.S_OK;
664 }
665 int SetActiveObject(int pActiveObject, int pszObjName) {
666     if (objIOleInPlaceActiveObject != null) {
667         objIOleInPlaceActiveObject.Release();
668         objIOleInPlaceActiveObject = null;
669     }
670     if (pActiveObject != 0) {
671         objIOleInPlaceActiveObject = new IOleInPlaceActiveObject(pActiveObject);
672         objIOleInPlaceActiveObject.AddRef();
673     }
674
675     return COM.S_OK;
676 }
677 private int SetBorderSpace(int pborderwidths) {
678     // A Control/Document can :
679
// Use its own toolbars, requesting border space of a specific size, or,
680
// Use no toolbars, but force the container to remove its toolbars by passing a
681
// valid BORDERWIDTHS structure containing nothing but zeros in the pborderwidths parameter, or,
682
// Use no toolbars but allow the in-place container to leave its toolbars up by
683
// passing NULL as the pborderwidths parameter.
684
if (objIOleInPlaceActiveObject == null) return COM.S_OK;
685     RECT borderwidth = new RECT();
686     if (pborderwidths == 0 || currentdoc == null ) return COM.S_OK;
687         
688     COM.MoveMemory(borderwidth, pborderwidths, RECT.sizeof);
689     currentdoc.setBorderSpace(borderwidth);
690
691     return COM.S_OK;
692 }
693 /**
694  *
695  * Specify the menu items that should appear in the Container location when an OLE Document
696  * is in-place activated.
697  *
698  * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
699  * is given the opportunity to merge some of its menus into the menubar. The application
700  * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
701  * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
702  * menu locations. Note that an application can insert more than one menu into a single location.
703  *
704  * <p>This method must be called before in place activation of the OLE Document. After the Document
705  * is activated, the menu bar will not be modified until a subsequent activation.
706  *
707  * @param containerMenus an array of top level MenuItems to be inserted into the Container location of
708  * the menubar
709  */

710 public void setContainerMenus(MenuItem[] containerMenus){
711     containerMenuItems = containerMenus;
712 }
713 OleClientSite getCurrentDocument() {
714     return currentdoc;
715 }
716 void setCurrentDocument(OleClientSite doc) {
717     currentdoc = doc;
718
719     if (currentdoc != null && objIOleInPlaceActiveObject != null) {
720         RECT lpRect = new RECT();
721         OS.GetClientRect(handle, lpRect);
722         objIOleInPlaceActiveObject.ResizeBorder(lpRect, iOleInPlaceFrame.getAddress(), true);
723     }
724 }
725 /**
726  *
727  * Specify the menu items that should appear in the File location when an OLE Document
728  * is in-place activated.
729  *
730  * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
731  * is given the opportunity to merge some of its menus into the menubar. The application
732  * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
733  * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
734  * menu locations. Note that an application can insert more than one menu into a single location.
735  *
736  * <p>This method must be called before in place activation of the OLE Document. After the Document
737  * is activated, the menu bar will not be modified until a subsequent activation.
738  *
739  * @param fileMenus an array of top level MenuItems to be inserted into the File location of
740  * the menubar
741  */

742 public void setFileMenus(MenuItem[] fileMenus){
743     fileMenuItems = fileMenus;
744 }
745 private int SetMenu(int hmenuShared, int holemenu, int hwndActiveObject) {
746     int inPlaceActiveObject = 0;
747     if (objIOleInPlaceActiveObject != null)
748         inPlaceActiveObject = objIOleInPlaceActiveObject.getAddress();
749     
750     Menu menubar = getShell().getMenuBar();
751     if (menubar == null || menubar.isDisposed()){
752         return COM.OleSetMenuDescriptor(0, getShell().handle, hwndActiveObject, iOleInPlaceFrame.getAddress(), inPlaceActiveObject);
753     }
754     
755     int handle = menubar.getShell().handle;
756     
757     if (hmenuShared == 0 && holemenu == 0) {
758         // re-instate the original menu - this occurs on deactivation
759
hmenuShared = menubar.handle;
760     }
761     if (hmenuShared == 0) return COM.E_FAIL;
762     
763     OS.SetMenu(handle, hmenuShared);
764     OS.DrawMenuBar(handle);
765     
766     return COM.OleSetMenuDescriptor(holemenu, handle, hwndActiveObject, iOleInPlaceFrame.getAddress(), inPlaceActiveObject);
767 }
768 /**
769  *
770  * Set the menu items that should appear in the Window location when an OLE Document
771  * is in-place activated.
772  *
773  * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
774  * is given the opportunity to merge some of its menus into the menubar. The application
775  * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
776  * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
777  * menu locations. Note that an application can insert more than one menu into a single location.
778  *
779  * <p>This method must be called before in place activation of the OLE Document. After the Document
780  * is activated, the menu bar will not be modified until a subsequent activation.
781  *
782  * @param windowMenus an array of top level MenuItems to be inserted into the Window location of
783  * the menubar
784  */

785 public void setWindowMenus(MenuItem[] windowMenus){
786     windowMenuItems = windowMenus;
787 }
788 private boolean translateOleAccelerator(MSG msg) {
789     if (objIOleInPlaceActiveObject == null) return false;
790     int result = objIOleInPlaceActiveObject.TranslateAccelerator(msg);
791     return (result != COM.S_FALSE && result != COM.E_NOTIMPL);
792 }
793 private int TranslateAccelerator(int lpmsg, int wID){
794     Menu menubar = getShell().getMenuBar();
795     if (menubar == null || menubar.isDisposed() || !menubar.isEnabled()) return COM.S_FALSE;
796     if (wID < 0) return COM.S_FALSE;
797     
798     Shell shell = menubar.getShell();
799     int hwnd = shell.handle;
800     int hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
801     if (hAccel == 0) return COM.S_FALSE;
802     
803     MSG msg = new MSG();
804     OS.MoveMemory(msg, lpmsg, MSG.sizeof);
805     int result = OS.TranslateAccelerator(hwnd, hAccel, msg);
806     return result == 0 ? COM.S_FALSE : COM.S_OK;
807 }
808 }
809
Popular Tags