1 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 ; 19 20 39 final public class OleFrame extends Composite 40 { 41 private COMObject iUnknown; 43 private COMObject iOleInPlaceFrame; 44 45 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 CHECK_FOCUS = "OLE_CHECK_FOCUS"; private static String HHOOK = "OLE_HHOOK"; private static String HHOOKMSG = "OLE_HHOOK_MSG"; 62 private static boolean ignoreNextKey; 63 private static final short [] ACCENTS = new short [] {'~', '`', '\'', '^', '"'}; 64 65 private static final String CONSUME_KEY = "org.eclipse.swt.OleFrame.ConsumeKey"; 67 82 public OleFrame(Composite parent, int style) { 83 super(parent, style); 84 85 createCOMInterfaces(); 86 87 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 addListener(SWT.Resize, listener); 109 110 addListener(SWT.Move, listener); 112 113 this.AddRef(); 117 118 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 [] timer = new Runnable [1]; 128 final Control[] lastFocus = new Control[1]; 129 timer[0] = new Runnable () { 130 public void run() { 131 if (lastFocus[0] instanceof OleClientSite && !lastFocus[0].isDisposed()) { 132 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); 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 (hHook)); 177 display.setData(HHOOKMSG, new MSG()); 178 display.disposeExec(new Runnable () { 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 hHook = (Integer )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 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 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 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 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 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 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 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 360 if (lprectBorder == 0) return COM.E_INVALIDARG; 361 RECT rectBorder = new RECT(); 362 OS.GetClientRect(handle, rectBorder); 364 OS.MoveMemory(lprectBorder, rectBorder, RECT.sizeof); 365 return COM.S_OK; 366 } 367 382 public MenuItem[] getContainerMenus(){ 383 return containerMenuItems; 384 } 385 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 440 public MenuItem[] getWindowMenus(){ 441 return windowMenuItems; 442 } 443 private int InsertMenus(int hmenuShared, int lpMenuWidths) { 444 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 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 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; if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) { 477 if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) { 478 fileMenuCount++; 480 newindex++; 481 } 482 } 483 } 484 } 485 } 486 487 COM.MoveMemory(lpMenuWidths, new int[] {fileMenuCount}, 4); 489 490 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; if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) { 502 if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) { 503 containerMenuCount++; 505 newindex++; 506 } 507 } 508 } 509 } 510 } 511 512 COM.MoveMemory(lpMenuWidths + 8, new int[] {containerMenuCount}, 4); 514 515 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; if (OS.GetMenuItemInfo(hMenu, index, true, lpmii)) { 527 if (OS.InsertMenuItem(hmenuShared, newindex, true, lpmii)) { 528 windowMenuCount++; 530 newindex++; 531 } 532 } 533 } 534 } 535 } 536 537 COM.MoveMemory(lpMenuWidths + 16, new int[] {windowMenuCount}, 4); 539 540 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 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 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 ids = new Vector (); 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 int id = getMenuItemID(hMenu, index); 629 ids.addElement(new Integer (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 (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 (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 (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 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 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 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 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 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 |