1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 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 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/13 moduleorg.eclipse.swt.ole.win32.OleFrame;
14 15 importjava.util.Vector;
16 17 importorg.eclipse.swt.SWT;
18 importorg.eclipse.swt.SWTException;
19 importorg.eclipse.swt.internal.ole.win32.COM;
20 importorg.eclipse.swt.internal.ole.win32.OLEIDL;
21 importorg.eclipse.swt.internal.ole.win32.extras;
22 importorg.eclipse.swt.internal.win32.OS;
23 importorg.eclipse.swt.widgets.Composite;
24 importorg.eclipse.swt.widgets.Control;
25 importorg.eclipse.swt.widgets.Display;
26 importorg.eclipse.swt.widgets.Event;
27 importorg.eclipse.swt.widgets.Listener;
28 importorg.eclipse.swt.widgets.Menu;
29 importorg.eclipse.swt.widgets.MenuItem;
30 importorg.eclipse.swt.widgets.Shell;
31 importorg.eclipse.swt.widgets.Widget;
32 33 importorg.eclipse.swt.ole.win32.OleClientSite;
34 importorg.eclipse.swt.ole.win32.OLE;
35 36 importorg.eclipse.swt.internal.LONG;
37 38 importjava.lang.all;
39 importjava.lang.Runnable;
40 41 /**
42 *
43 * OleFrame is an OLE Container's top level frame.
44 *
45 * <p>This object implements the OLE Interfaces IUnknown and IOleInPlaceFrame
46 *
47 * <p>OleFrame allows the container to do the following: <ul>
48 * <li>position and size the ActiveX Control or OLE Document within the application
49 * <li>insert menu items from the application into the OLE Document's menu
50 * <li>activate and deactivate the OLE Document's menus
51 * <li>position the OLE Document's menu in the application
52 * <li>translate accelerator keystrokes intended for the container's frame</ul>
53 *
54 * <dl>
55 * <dt><b>Styles</b> <dd>BORDER
56 * <dt><b>Events</b> <dd>Dispose, Move, Resize
57 * </dl>
58 *
59 * @see <a href="http://www.eclipse.org/swt/snippets/#ole">OLE and ActiveX snippets</a>
60 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: OLEExample, OleWebBrowser</a>
61 */62 finalpublicclassOleFrame : Composite63 {
64 // Interfaces for this Ole Client Container65 //private COMObject iUnknown;66 private_IOleInPlaceFrameImpliOleInPlaceFrame;
67 68 // Access to the embedded/linked Ole Object69 privateIOleInPlaceActiveObjectobjIOleInPlaceActiveObject;
70 71 privateOleClientSitecurrentdoc;
72 73 privateintrefCount = 0;
74 75 privateMenuItem[] fileMenuItems;
76 privateMenuItem[] containerMenuItems;
77 privateMenuItem[] windowMenuItems;
78 79 privateListenerlistener;
80 81 privatestaticStringCHECK_FOCUS = "OLE_CHECK_FOCUS"; //$NON-NLS-1$82 privatestaticStringHHOOK = "OLE_HHOOK"; //$NON-NLS-1$83 privatestaticStringHHOOKMSG = "OLE_HHOOK_MSG"; //$NON-NLS-1$84 85 privatestaticboolignoreNextKey;
86 privatestaticconstshort [] ACCENTS = [ cast(short)'~', '`', '\'', '^', '"'];
87 88 privatestaticconstStringCONSUME_KEY = "org.eclipse.swt.OleFrame.ConsumeKey"; //$NON-NLS-1$89 90 /**
91 * Create an OleFrame child widget using style bits
92 * to select a particular look or set of properties.
93 *
94 * @param parent a composite widget (cannot be null)
95 * @param style the bitwise OR'ing of widget styles
96 *
97 * @exception IllegalArgumentException <ul>
98 * <li>ERROR_NULL_ARGUMENT when the parent is null
99 * </ul>
100 * @exception SWTException <ul>
101 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
102 * </ul>
103 *
104 */105 publicthis(Compositeparent, intstyle) {
106 super(parent, style);
107 108 createCOMInterfaces();
109 110 // setup cleanup proc111 listener = newclass() Listener {
112 publicvoidhandleEvent(Evente) {
113 switch (e.type) {
114 caseSWT.Activate : onActivate(e); break;
115 caseSWT.Deactivate : onDeactivate(e); break;
116 caseSWT.Dispose : onDispose(e); break;
117 caseSWT.Resize :
118 caseSWT.Move : onResize(e); break;
119 default :
120 OLE.error(SWT.ERROR_NOT_IMPLEMENTED);
121 }
122 }
123 };
124 125 126 addListener(SWT.Activate, listener);
127 addListener(SWT.Deactivate, listener);
128 addListener(SWT.Dispose, listener);
129 130 // inform inplaceactiveobject whenever frame resizes131 addListener(SWT.Resize, listener);
132 133 // inform inplaceactiveobject whenever frame moves134 addListener(SWT.Move, listener);
135 136 // Maintain a reference to yourself so that when137 // ClientSites close, they don't take the frame away138 // with them.139 this.AddRef();
140 141 // Check for focus change142 Displaydisplay = getDisplay();
143 initCheckFocus(display);
144 initMsgHook(display);
145 }
146 privatestaticvoidinitCheckFocus (Displaydisplay_) {
147 if (display_.getData(CHECK_FOCUS) !isnull) return;
148 display_.setData(CHECK_FOCUS, newArrayWrapperString(CHECK_FOCUS));
149 staticconstinttime = 50;
150 autotimer = newclass(display_) Runnable {
151 Displaydisplay;
152 Control[1] lastFocus;
153 this( Displaydisplay){ this.display = display; }
154 publicvoidrun() {
155 if (( null !iscast(OleClientSite)lastFocus[0] ) && !lastFocus[0].isDisposed()) {
156 // ignore popup menus and dialogs157 autohwnd = OS.GetFocus();
158 while (hwnd !isnull) {
159 autoownerHwnd = OS.GetWindow(hwnd, OS.GW_OWNER);
160 if (ownerHwnd !isnull) {
161 display.timerExec(time, this);
162 return;
163 }
164 hwnd = OS.GetParent(hwnd);
165 }
166 }
167 if (lastFocus[0] isnull || lastFocus[0].isDisposed() || !lastFocus[0].isFocusControl()) {
168 ControlcurrentFocus = display.getFocusControl();
169 if ( autoframe = cast(OleFrame)currentFocus ) {
170 currentFocus = frame.getCurrentDocument();
171 }
172 if (lastFocus[0] !iscurrentFocus) {
173 Eventevent = newEvent();
174 if (( null !iscast(OleClientSite)lastFocus[0] ) && !lastFocus[0].isDisposed()) {
175 lastFocus[0].notifyListeners (SWT.FocusOut, event);
176 }
177 if (( null !iscast(OleClientSite)currentFocus ) && !currentFocus.isDisposed()) {
178 currentFocus.notifyListeners(SWT.FocusIn, event);
179 }
180 }
181 lastFocus[0] = currentFocus;
182 }
183 display.timerExec(time, this);
184 }
185 };
186 display_.timerExec(time, timer);
187 }
188 privatestaticvoidinitMsgHook(Displaydisplay) {
189 if (display.getData(HHOOK) !isnull) return;
190 //final Callback callback = new Callback(OleFrame.class, "getMsgProc", 3); //$NON-NLS-1$191 //int address = callback.getAddress();192 //if (address is 0) SWT.error(SWT.ERROR_NO_MORE_CALLBACKS);193 intthreadId = OS.GetCurrentThreadId();
194 autohHook_ = OS.SetWindowsHookEx(OS.WH_GETMESSAGE, &getMsgProc, null, threadId);
195 if (hHook_isnull) {
196 //callback.dispose();197 return;
198 }
199 display.setData(HHOOK, newValueWrapperT!(void*)(hHook_));
200 display.setData(HHOOKMSG, newValueWrapperT!(MSG*)(newMSG()));
201 display.disposeExec(newclass(hHook_) Runnable {
202 void* hHook;
203 this( void* hHook ){ this.hHook = hHook; }
204 publicvoidrun() {
205 if (hHook !isnull) OS.UnhookWindowsHookEx(hHook);
206 //if (callback !is null) callback.dispose();207 }
208 });
209 }
210 staticextern(Windows) .LRESULTgetMsgProc(intcode, WPARAMwParam, LPARAMlParam) {
211 Displaydisplay = Display.getCurrent();
212 if (displayisnull) return0;
213 autohHook = cast(ValueWrapperT!(void*))display.getData(HHOOK);
214 if (hHookisnull) return0;
215 if (code < 0) {
216 returnOS.CallNextHookEx(hHook.value, code, wParam, lParam);
217 }
218 MSG* msg = cast(MSG*)(cast(ValueWrapperT!(MSG*))display.getData(HHOOKMSG)).value;
219 OS.MoveMemory(msg, lParam, MSG.sizeof);
220 intmessage = msg.message;
221 if (OS.WM_KEYFIRST <= message && message <= OS.WM_KEYLAST) {
222 if (display !isnull) {
223 Widgetwidget = null;
224 autohwnd = msg.hwnd;
225 while (hwnd !isnull) {
226 widget = display.findWidget (hwnd);
227 if (widget !isnull) break;
228 hwnd = OS.GetParent (hwnd);
229 }
230 if (widget !isnull && (null !iscast(OleClientSite)widget )) {
231 OleClientSitesite = cast(OleClientSite)widget;
232 if (site.handleishwnd) {
233 boolconsumed = false;
234 /* Allow activeX control to translate accelerators except when a menu is active. */235 intthread = OS.GetWindowThreadProcessId(msg.hwnd, null);
236 GUITHREADINFO* lpgui = newGUITHREADINFO();
237 lpgui.cbSize = GUITHREADINFO.sizeof;
238 boolrc = cast(bool) OS.GetGUIThreadInfo(thread, lpgui);
239 intmask = OS.GUI_INMENUMODE | OS.GUI_INMOVESIZE | OS.GUI_POPUPMENUMODE | OS.GUI_SYSTEMMENUMODE;
240 if (!rc || (lpgui.flags & mask) is0) {
241 OleFrameframe = site.frame;
242 frame.setData(CONSUME_KEY, null);
243 consumed = frame.translateOleAccelerator(msg);
244 if (frame.getData(CONSUME_KEY) !isnull) consumed = false;
245 frame.setData(CONSUME_KEY, null);
246 }
247 boolaccentKey = false;
248 switch (msg.message) {
249 caseOS.WM_KEYDOWN:
250 caseOS.WM_SYSKEYDOWN: {
251 staticif (!OS.IsWinCE) {
252 switch (msg.wParam) {
253 caseOS.VK_SHIFT:
254 caseOS.VK_MENU:
255 caseOS.VK_CONTROL:
256 caseOS.VK_CAPITAL:
257 caseOS.VK_NUMLOCK:
258 caseOS.VK_SCROLL:
259 break;
260 default: {
261 /*
262 * Bug in Windows. The high bit in the result of MapVirtualKey() on
263 * Windows NT is bit 32 while the high bit on Windows 95 is bit 16.
264 * They should both be bit 32. The fix is to test the right bit.
265 */266 intmapKey = OS.MapVirtualKey (cast(int)/*64bit*/msg.wParam, 2);
267 if (mapKey !is0) {
268 accentKey = (mapKey & (OS.IsWinNT ? 0x80000000 : 0x8000)) !is0;
269 if (!accentKey) {
270 for (inti=0; i<ACCENTS.length; i++) {
271 intvalue = OS.VkKeyScan (ACCENTS [i]);
272 if (value !is -1 && (value & 0xFF) ismsg.wParam) {
273 intstate = value >> 8;
274 if ((OS.GetKeyState (OS.VK_SHIFT) < 0) is ((state & 0x1) !is0) &&
275 (OS.GetKeyState (OS.VK_CONTROL) < 0) is ((state & 0x2) !is0) &&
276 (OS.GetKeyState (OS.VK_MENU) < 0) is ((state & 0x4) !is0)) {
277 if ((state & 0x7) !is0) accentKey = true;
278 break;
279 }
280 }
281 }
282 }
283 }
284 break;
285 }
286 }
287 }
288 break;
289 }
290 default:
291 }
292 /* Allow OleClientSite to process key events before activeX control */293 if (!consumed && !accentKey && !ignoreNextKey) {
294 autohwndOld = msg.hwnd;
295 msg.hwnd = site.handle;
296 consumed = OS.DispatchMessage (msg) is1;
297 msg.hwnd = hwndOld;
298 }
299 switch (msg.message) {
300 caseOS.WM_KEYDOWN:
301 caseOS.WM_SYSKEYDOWN: {
302 switch (msg.wParam) {
303 caseOS.VK_SHIFT:
304 caseOS.VK_MENU:
305 caseOS.VK_CONTROL:
306 caseOS.VK_CAPITAL:
307 caseOS.VK_NUMLOCK:
308 caseOS.VK_SCROLL:
309 break;
310 default: {
311 ignoreNextKey = accentKey;
312 break;
313 }
314 }
315 break;
316 }
317 default:
318 break;
319 }
320 321 if (consumed) {
322 // In order to prevent this message from also being processed323 // by the application, zero out message, wParam and lParam324 msg.message = OS.WM_NULL;
325 msg.wParam = msg.lParam = 0;
326 OS.MoveMemory(lParam, msg, MSG.sizeof);
327 return0;
328 }
329 }
330 }
331 }
332 }
333 returnOS.CallNextHookEx( hHook.value, code, wParam, lParam);
334 }
335 /**
336 * Increment the count of references to this instance
337 *
338 * @return the current reference count
339 */340 intAddRef() {
341 refCount++;
342 returnrefCount;
343 }
344 privateintContextSensitiveHelp(intfEnterMode) {
345 returnCOM.S_OK;
346 }
347 privatevoidcreateCOMInterfaces() {
348 iOleInPlaceFrame = new_IOleInPlaceFrameImpl(this);
349 }
350 privatevoiddisposeCOMInterfaces () {
351 iOleInPlaceFrame = null;
352 }
353 privateHRESULTGetBorder(LPRECTlprectBorder) {
354 /*
355 The IOleInPlaceUIWindow::GetBorder function, when called on a document or frame window
356 object, returns the outer rectangle (relative to the window) where the object can put
357 toolbars or similar controls.
358 */359 if (lprectBorderisnull) returnCOM.E_INVALIDARG;
360 RECT* rectBorder = newRECT();
361 // Coordinates must be relative to the window362 OS.GetClientRect(handle, lprectBorder);
363 returnCOM.S_OK;
364 }
365 /**
366 *
367 * Returns the application menu items that will appear in the Container location when an OLE Document
368 * is in-place activated.
369 *
370 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
371 * is given the opportunity to merge some of its menus into the menubar. The application
372 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
373 * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
374 * menu locations. Note that an application can insert more than one menu into a single location.
375 *
376 * @return the application menu items that will appear in the Container location when an OLE Document
377 * is in-place activated.
378 *
379 */380 publicMenuItem[] getContainerMenus(){
381 returncontainerMenuItems;
382 }
383 /**
384 *
385 * Returns the application menu items that will appear in the File location when an OLE Document
386 * is in-place activated.
387 *
388 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
389 * is given the opportunity to merge some of its menus into the menubar. The application
390 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
391 * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
392 * menu locations. Note that an application can insert more than one menu into a single location.
393 *
394 * @return the application menu items that will appear in the File location when an OLE Document
395 * is in-place activated.
396 *
397 */398 publicMenuItem[] getFileMenus(){
399 returnfileMenuItems;
400 }
401 IOleInPlaceFramegetIOleInPlaceFrame() {
402 returniOleInPlaceFrame;
403 }
404 privateptrdiff_tgetMenuItemID(HMENUhMenu, intindex) {
405 ptrdiff_tid = 0;
406 MENUITEMINFOlpmii;
407 lpmii.cbSize = OS.MENUITEMINFO_sizeof;
408 lpmii.fMask = OS.MIIM_STATE | OS.MIIM_SUBMENU | OS.MIIM_ID;
409 OS.GetMenuItemInfo(hMenu, index, true, &lpmii);
410 if ((lpmii.fState & OS.MF_POPUP) isOS.MF_POPUP) {
411 id = cast(ptrdiff_t)lpmii.hSubMenu;
412 } else {
413 id = lpmii.wID;
414 }
415 returnid;
416 }
417 privateintGetWindow(HWND* phwnd) {
418 if (phwnd !isnull) {
419 *phwnd = handle;
420 }
421 returnCOM.S_OK;
422 }
423 /**
424 *
425 * Returns the application menu items that will appear in the Window location when an OLE Document
426 * is in-place activated.
427 *
428 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
429 * is given the opportunity to merge some of its menus into the menubar. The application
430 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
431 * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
432 * menu locations. Note that an application can insert more than one menu into a single location.
433 *
434 * @return the application menu items that will appear in the Window location when an OLE Document
435 * is in-place activated.
436 *
437 */438 publicMenuItem[] getWindowMenus(){
439 returnwindowMenuItems;
440 }
441 privateHRESULTInsertMenus( HMENUhmenuShared, LPOLEMENUGROUPWIDTHSlpMenuWidths ) {
442 // locate menu bar443 Menumenubar = getShell().getMenuBar();
444 if (menubarisnull || menubar.isDisposed()) {
445 inttemp = 0;
446 COM.MoveMemory(lpMenuWidths, &temp, 4);
447 returnCOM.S_OK;
448 }
449 HMENUhMenu = menubar.handle;
450 451 // Create a holder for menu information. This will be passed down to452 // the OS and the OS will fill in the requested information for each menu.453 MENUITEMINFOlpmii;
454 autohHeap = OS.GetProcessHeap();
455 intcch = 128;
456 autobyteCount = cch * TCHAR.sizeof;
457 autopszText = cast(TCHAR*) OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, byteCount);
458 lpmii.cbSize = OS.MENUITEMINFO_sizeof;
459 lpmii.fMask = OS.MIIM_STATE | OS.MIIM_ID | OS.MIIM_TYPE | OS.MIIM_SUBMENU | OS.MIIM_DATA;
460 lpmii.dwTypeData = pszText;
461 lpmii.cch = cch;
462 463 // Loop over all "File-like" menus in the menubar and get information about the464 // item from the OS.465 intfileMenuCount = 0;
466 intnewindex = 0;
467 if (this.fileMenuItems !isnull) {
468 for (inti = 0; i < this.fileMenuItems.length; i++) {
469 MenuItemitem = this.fileMenuItems[i];
470 if (item !isnull) {
471 intindex = item.getParent().indexOf(item);
472 lpmii.cch = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the473 // exact number of characters in name. Reset it to our max size474 // before each call.475 if (OS.GetMenuItemInfo(hMenu, index, true, &lpmii)) {
476 if (OS.InsertMenuItem(hmenuShared, newindex, true, &lpmii)) {
477 // keep track of the number of items478 fileMenuCount++;
479 newindex++;
480 }
481 }
482 }
483 }
484 }
485 486 // copy the menu item count information to the pointer487 COM.MoveMemory(lpMenuWidths, &fileMenuCount, 4);
488 489 // Loop over all "Container-like" menus in the menubar and get information about the490 // item from the OS.491 intcontainerMenuCount = 0;
492 if (this.containerMenuItems !isnull) {
493 for (inti = 0; i < this.containerMenuItems.length; i++) {
494 MenuItemitem = this.containerMenuItems[i];
495 if (item !isnull) {
496 intindex = item.getParent().indexOf(item);
497 lpmii.cch = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the498 // exact number of characters in name. Reset it to a large number499 // before each call.500 if (OS.GetMenuItemInfo(hMenu, index, true, &lpmii)) {
501 if (OS.InsertMenuItem(hmenuShared, newindex, true, &lpmii)) {
502 // keep track of the number of items503 containerMenuCount++;
504 newindex++;
505 }
506 }
507 }
508 }
509 }
510 511 // copy the menu item count information to the pointer512 COM.MoveMemory((cast(void*)lpMenuWidths) + 8, &containerMenuCount, 4);
513 514 // Loop over all "Window-like" menus in the menubar and get information about the515 // item from the OS.516 intwindowMenuCount = 0;
517 if (this.windowMenuItems !isnull) {
518 for (inti = 0; i < this.windowMenuItems.length; i++) {
519 MenuItemitem = this.windowMenuItems[i];
520 if (item !isnull) {
521 intindex = item.getParent().indexOf(item);
522 lpmii.cch = cch; // lpmii.cch gets updated by GetMenuItemInfo to indicate the523 // exact number of characters in name. Reset it to a large number524 // before each call.525 if (OS.GetMenuItemInfo(hMenu, index, true, &lpmii)) {
526 if (OS.InsertMenuItem(hmenuShared, newindex, true, &lpmii)) {
527 // keep track of the number of items528 windowMenuCount++;
529 newindex++;
530 }
531 }
532 }
533 }
534 }
535 536 // copy the menu item count information to the pointer537 COM.MoveMemory((cast(void*)lpMenuWidths) + 16, &windowMenuCount, 4);
538 539 // free resources used in querying the OS540 if (pszText !isnull)
541 OS.HeapFree(hHeap, 0, pszText);
542 returnCOM.S_OK;
543 }
544 voidonActivate(Evente) {
545 if (objIOleInPlaceActiveObject !isnull) {
546 objIOleInPlaceActiveObject.OnFrameWindowActivate(true);
547 }
548 if (objIOleInPlaceActiveObject !isnull) {
549 objIOleInPlaceActiveObject.OnDocWindowActivate(true);
550 }
551 }
552 voidonDeactivate(Evente) {
553 if (objIOleInPlaceActiveObject !isnull) {
554 objIOleInPlaceActiveObject.OnFrameWindowActivate(false);
555 }
556 if (objIOleInPlaceActiveObject !isnull) {
557 objIOleInPlaceActiveObject.OnDocWindowActivate(false);
558 }
559 }
560 privatevoidonDispose(Evente) {
561 562 releaseObjectInterfaces();
563 currentdoc = null;
564 565 this.Release();
566 removeListener(SWT.Activate, listener);
567 removeListener(SWT.Deactivate, listener);
568 removeListener(SWT.Dispose, listener);
569 removeListener(SWT.Resize, listener);
570 removeListener(SWT.Move, listener);
571 }
572 privatevoidonResize(Evente) {
573 if (objIOleInPlaceActiveObject !isnull) {
574 RECTlpRect;
575 OS.GetClientRect(handle, &lpRect);
576 objIOleInPlaceActiveObject.ResizeBorder(&lpRect, iOleInPlaceFrame, true);
577 }
578 }
579 privateHRESULTQueryInterface(REFCIIDriid, void** ppvObject) {
580 // implements IUnknown, IOleInPlaceFrame, IOleContainer, IOleInPlaceUIWindow581 if (riidisnull || ppvObjectisnull)
582 returnCOM.E_INVALIDARG;
583 584 if (COM.IsEqualGUID(riid, &COM.IIDIUnknown) || COM.IsEqualGUID(riid, &COM.IIDIOleInPlaceFrame) ) {
585 *ppvObject = cast(void*)cast(IOleInPlaceFrame)iOleInPlaceFrame;
586 AddRef();
587 returnCOM.S_OK;
588 }
589 590 *ppvObject = null;
591 returnCOM.E_NOINTERFACE;
592 }
593 /**
594 * Decrement the count of references to this instance
595 *
596 * @return the current reference count
597 */598 intRelease() {
599 refCount--;
600 if (refCountis0){
601 disposeCOMInterfaces();
602 COM.CoFreeUnusedLibraries();
603 }
604 returnrefCount;
605 }
606 privatevoidreleaseObjectInterfaces() {
607 if (objIOleInPlaceActiveObject !isnull) {
608 objIOleInPlaceActiveObject.Release();
609 }
610 objIOleInPlaceActiveObject = null;
611 }
612 privateintRemoveMenus(HMENUhmenuShared) {
613 614 Menumenubar = getShell().getMenuBar();
615 if (menubarisnull || menubar.isDisposed()) returnCOM.S_FALSE;
616 617 autohMenu = menubar.handle;
618 619 Vectorids = newVector();
620 if (this.fileMenuItems !isnull) {
621 for (inti = 0; i < this.fileMenuItems.length; i++) {
622 MenuItemitem = this.fileMenuItems[i];
623 if (item !isnull && !item.isDisposed()) {
624 intindex = item.getParent().indexOf(item);
625 // get Id from original menubar626 autoid = getMenuItemID(hMenu, index);
627 ids.addElement(neworg.eclipse.swt.internal.LONG.LONG_PTR(id));
628 }
629 }
630 }
631 if (this.containerMenuItems !isnull) {
632 for (inti = 0; i < this.containerMenuItems.length; i++) {
633 MenuItemitem = this.containerMenuItems[i];
634 if (item !isnull && !item.isDisposed()) {
635 intindex = item.getParent().indexOf(item);
636 autoid = getMenuItemID(hMenu, index);
637 ids.addElement(neworg.eclipse.swt.internal.LONG.LONG_PTR(id));
638 }
639 }
640 }
641 if (this.windowMenuItems !isnull) {
642 for (inti = 0; i < this.windowMenuItems.length; i++) {
643 MenuItemitem = this.windowMenuItems[i];
644 if (item !isnull && !item.isDisposed()) {
645 intindex = item.getParent().indexOf(item);
646 autoid = getMenuItemID(hMenu, index);
647 ids.addElement(neworg.eclipse.swt.internal.LONG.LONG_PTR(id));
648 }
649 }
650 }
651 intindex = OS.GetMenuItemCount(hmenuShared) - 1;
652 for (inti = index; i >= 0; i--) {
653 autoid = getMenuItemID(hmenuShared, i);
654 if (ids.contains(neworg.eclipse.swt.internal.LONG.LONG_PTR(id))){
655 OS.RemoveMenu(hmenuShared, i, OS.MF_BYPOSITION);
656 }
657 }
658 returnCOM.S_OK;
659 }
660 privateintRequestBorderSpace(LPCBORDERWIDTHSpborderwidths) {
661 returnCOM.S_OK;
662 }
663 HRESULTSetActiveObject( LPOLEINPLACEACTIVEOBJECTpActiveObject, LPCOLESTRpszObjName ) {
664 if (objIOleInPlaceActiveObject !isnull) {
665 objIOleInPlaceActiveObject.Release();
666 objIOleInPlaceActiveObject = null;
667 }
668 if (pActiveObject !isnull) {
669 objIOleInPlaceActiveObject = pActiveObject;
670 objIOleInPlaceActiveObject.AddRef();
671 }
672 673 returnCOM.S_OK;
674 }
675 676 privateHRESULTSetBorderSpace( LPCBORDERWIDTHSpborderwidths ) {
677 // A Control/Document can :678 // Use its own toolbars, requesting border space of a specific size, or,679 // Use no toolbars, but force the container to remove its toolbars by passing a680 // valid BORDERWIDTHS structure containing nothing but zeros in the pborderwidths parameter, or,681 // Use no toolbars but allow the in-place container to leave its toolbars up by682 // passing NULL as the pborderwidths parameter.683 if (objIOleInPlaceActiveObjectisnull) returnCOM.S_OK;
684 RECT* borderwidth = newRECT();
685 if (pborderwidthsisnull || currentdocisnull ) returnCOM.S_OK;
686 687 COM.MoveMemory(borderwidth, pborderwidths, RECT.sizeof);
688 currentdoc.setBorderSpace(borderwidth);
689 690 returnCOM.S_OK;
691 }
692 /**
693 *
694 * Specify the menu items that should appear in the Container location when an OLE Document
695 * is in-place activated.
696 *
697 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
698 * is given the opportunity to merge some of its menus into the menubar. The application
699 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
700 * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
701 * menu locations. Note that an application can insert more than one menu into a single location.
702 *
703 * <p>This method must be called before in place activation of the OLE Document. After the Document
704 * is activated, the menu bar will not be modified until a subsequent activation.
705 *
706 * @param containerMenus an array of top level MenuItems to be inserted into the Container location of
707 * the menubar
708 */709 publicvoidsetContainerMenus(MenuItem[] containerMenus){
710 containerMenuItems = containerMenus;
711 }
712 OleClientSitegetCurrentDocument() {
713 returncurrentdoc;
714 }
715 voidsetCurrentDocument(OleClientSitedoc) {
716 currentdoc = doc;
717 718 if (currentdoc !isnull && objIOleInPlaceActiveObject !isnull) {
719 RECTlpRect;
720 OS.GetClientRect(handle, &lpRect);
721 objIOleInPlaceActiveObject.ResizeBorder(&lpRect, iOleInPlaceFrame, true);
722 }
723 }
724 /**
725 *
726 * Specify the menu items that should appear in the File location when an OLE Document
727 * is in-place activated.
728 *
729 * <p>When an OLE Document is in-place active, the Document provides its own menus but the application
730 * is given the opportunity to merge some of its menus into the menubar. The application
731 * is allowed to insert its menus in three locations: File (far left), Container(middle) and Window
732 * (far right just before Help). The OLE Document retains control of the Edit, Object and Help
733 * menu locations. Note that an application can insert more than one menu into a single location.
734 *
735 * <p>This method must be called before in place activation of the OLE Document. After the Document
736 * is activated, the menu bar will not be modified until a subsequent activation.
737 *
738 * @param fileMenus an array of top level MenuItems to be inserted into the File location of
739 * the menubar
740 */741 publicvoidsetFileMenus(MenuItem[] fileMenus){
742 fileMenuItems = fileMenus;
743 }
744 HRESULTSetMenu( HMENUhmenuShared, HOLEMENUholemenu, HWNDhwndActiveObject ) {
745 IOleInPlaceActiveObjectinPlaceActiveObject;
746 if (objIOleInPlaceActiveObject !isnull)
747 inPlaceActiveObject = objIOleInPlaceActiveObject;
748 749 Menumenubar = getShell().getMenuBar();
750 if (menubarisnull || menubar.isDisposed()){
751 returnCOM.OleSetMenuDescriptor(null, getShell().handle, hwndActiveObject, iOleInPlaceFrame, inPlaceActiveObject);
752 }
753 754 HWNDhandle = menubar.getShell().handle;
755 756 if (hmenuSharedisnull && holemenuisnull) {
757 // re-instate the original menu - this occurs on deactivation758 hmenuShared = menubar.handle;
759 }
760 if (hmenuSharedisnull) returnCOM.E_FAIL;
761 762 OS.SetMenu(handle, hmenuShared);
763 OS.DrawMenuBar(handle);
764 765 returnCOM.OleSetMenuDescriptor(holemenu, handle, hwndActiveObject, iOleInPlaceFrame, inPlaceActiveObject);
766 }
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 publicvoidsetWindowMenus(MenuItem[] windowMenus){
786 windowMenuItems = windowMenus;
787 }
788 privatebooltranslateOleAccelerator(MSG* msg) {
789 if (objIOleInPlaceActiveObjectisnull) returnfalse;
790 intresult = objIOleInPlaceActiveObject.TranslateAccelerator(msg);
791 return (result != COM.S_FALSE && result != COM.E_NOTIMPL);
792 }
793 794 HRESULTTranslateAccelerator( LPMSGlpmsg, WORDwID ){
795 Menumenubar = getShell().getMenuBar();
796 if (menubarisnull || menubar.isDisposed() || !menubar.isEnabled()) returnCOM.S_FALSE;
797 if (wID < 0) returnCOM.S_FALSE;
798 799 Shellshell = menubar.getShell();
800 HWNDhwnd = shell.handle;
801 HACCELhAccel = cast(HACCEL)OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
802 if (hAccelisnull) returnCOM.S_FALSE;
803 804 MSGmsg = *lpmsg;
805 intresult = OS.TranslateAccelerator(hwnd, hAccel, &msg);
806 returnresult == 0 ? COM.S_FALSE : COM.S_OK;
807 }
808 }
809 810 // implements IOleInPlaceFrame, IOleInPlaceUIWindow, IOleWindow, IUnknown811 class_IOleInPlaceFrameImpl : IOleInPlaceFrame {
812 813 OleFrameparent;
814 this(OleFramep) { parent = p; }
815 extern (Windows) :
816 // interface of IUnknown817 HRESULTQueryInterface(REFCIIDriid, void ** ppvObject) { returnparent.QueryInterface(riid, ppvObject); }
818 ULONGAddRef() { returnparent.AddRef(); }
819 ULONGRelease() { returnparent.Release(); }
820 821 // interface IOleWindow822 HRESULTGetWindow( HWND * phwnd ) { returnparent.GetWindow(phwnd); }
823 HRESULTContextSensitiveHelp( BOOLfEnterMode ){ returnCOM.S_OK; }
824 825 //interface IOleInPlaceUIWindow826 HRESULTGetBorder( LPRECTlprectBorder ) { returnparent.GetBorder(lprectBorder); }
827 HRESULTRequestBorderSpace( LPCBORDERWIDTHSpborderwidths ){ returnCOM.S_OK; }
828 HRESULTSetBorderSpace( LPCBORDERWIDTHSpborderwidths ) { returnparent.SetBorderSpace(pborderwidths); }
829 HRESULTSetActiveObject( LPOLEINPLACEACTIVEOBJECTpActiveObject, LPCOLESTRpszObjName ) {
830 returnparent.SetActiveObject(pActiveObject, pszObjName);
831 }
832 833 // interface IOleInPlaceFrame : IOleInPlaceUIWindow834 HRESULTInsertMenus( HMENUhmenuShared, LPOLEMENUGROUPWIDTHSlpMenuWidths ){
835 returnparent.InsertMenus(hmenuShared, lpMenuWidths);
836 }
837 HRESULTSetMenu( HMENUhmenuShared, HOLEMENUholemenu, HWNDhwndActiveObject ){
838 returnparent.SetMenu(hmenuShared, holemenu, hwndActiveObject);
839 }
840 HRESULTRemoveMenus( HMENUhmenuShared ) {
841 returnparent.RemoveMenus(hmenuShared);
842 }
843 HRESULTSetStatusText( LPCOLESTRpszStatusText ) { returnCOM.E_NOTIMPL; }
844 HRESULTEnableModeless( BOOLfEnable ) { returnCOM.E_NOTIMPL; }
845 HRESULTTranslateAccelerator( LPMSGlpmsg, WORDwID ) {
846 returnparent.TranslateAccelerator(lpmsg, wID);
847 }
848 849 }
850