| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| // Modified by Google |
| package org.eclipse.swt.browser; |
| |
| import org.eclipse.swt.*; |
| import org.eclipse.swt.internal.ole.win32.*; |
| import org.eclipse.swt.ole.win32.*; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.swt.internal.win32.*; |
| |
| class WebSite extends OleControlSite { |
| COMObject iDocHostUIHandler; |
| COMObject iDocHostShowUI; |
| COMObject iServiceProvider; |
| COMObject iInternetSecurityManager; |
| COMObject iOleCommandTarget; |
| |
| static final int OLECMDID_SHOWSCRIPTERROR = 40; |
| |
| public WebSite(Composite parent, int style, String progId) { |
| super(parent, style, progId); |
| } |
| |
| // GOOGLE: attempt to load Gears |
| /** |
| * Load the Google Gears BHO if possible. |
| * |
| * @return true if Gears was successfully loaded and initialized |
| */ |
| public boolean startGears() { |
| // Get the classID of the Gears BHO. |
| try { |
| GUID appClsid = getClassID("gears.BHO"); |
| if (appClsid == null) { |
| return false; |
| } |
| } catch(SWTException e) { |
| return false; |
| } |
| |
| // Create an instance of the Gears BHO. |
| int[] address = new int[1]; |
| if (COM.CoCreateInstance(appClsid, 0, COM.CLSCTX_INPROC_SERVER, |
| COM.IIDIUnknown, address) != COM.S_OK) { |
| return false; |
| } |
| |
| // Get the IObjectWithSite interface and call SetSite. |
| IUnknown obj = new IUnknown(address[0]); |
| int[] ppvObject = new int[1]; |
| if (obj.QueryInterface(COM.IIDIObjectWithSite, ppvObject) == COM.S_OK) { |
| IObjectWithSite objectWithSite = new IObjectWithSite(ppvObject[0]); |
| /* |
| * TODO: Gears currently does not check the parameter passed other than |
| * to see if it is non-null. If Gears ever changes to actually use the |
| * passed object, we will need to make sure that this works as expected. |
| */ |
| objectWithSite.SetSite(objIUnknown); |
| objectWithSite.Release(); |
| return true; |
| } |
| return false; |
| } |
| |
| protected void createCOMInterfaces () { |
| super.createCOMInterfaces(); |
| iDocHostUIHandler = new COMObject(new int[]{2, 0, 0, 4, 1, 5, 0, 0, 1, 1, 1, 3, 3, 2, 2, 1, 3, 2}){ |
| public int method0(int[] args) {return QueryInterface(args[0], args[1]);} |
| public int method1(int[] args) {return AddRef();} |
| public int method2(int[] args) {return Release();} |
| public int method3(int[] args) {return ShowContextMenu(args[0], args[1], args[2], args[3]);} |
| public int method4(int[] args) {return GetHostInfo(args[0]);} |
| public int method5(int[] args) {return ShowUI(args[0], args[1], args[2], args[3], args[4]);} |
| public int method6(int[] args) {return HideUI();} |
| public int method7(int[] args) {return UpdateUI();} |
| public int method8(int[] args) {return EnableModeless(args[0]);} |
| public int method9(int[] args) {return OnDocWindowActivate(args[0]);} |
| public int method10(int[] args) {return OnFrameWindowActivate(args[0]);} |
| public int method11(int[] args) {return ResizeBorder(args[0], args[1], args[2]);} |
| public int method12(int[] args) {return TranslateAccelerator(args[0], args[1], args[2]);} |
| public int method13(int[] args) {return GetOptionKeyPath(args[0], args[1]);} |
| public int method14(int[] args) {return GetDropTarget(args[0], args[1]);} |
| public int method15(int[] args) {return GetExternal(args[0]);} |
| public int method16(int[] args) {return TranslateUrl(args[0], args[1], args[2]);} |
| public int method17(int[] args) {return FilterDataObject(args[0], args[1]);} |
| }; |
| iDocHostShowUI = new COMObject(new int[]{2, 0, 0, 7, 7}){ |
| public int method0(int[] args) {return QueryInterface(args[0], args[1]);} |
| public int method1(int[] args) {return AddRef();} |
| public int method2(int[] args) {return Release();} |
| public int method3(int[] args) {return ShowMessage(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);} |
| public int method4(int[] args) {return ShowHelp(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);} |
| }; |
| iServiceProvider = new COMObject(new int[]{2, 0, 0, 3}){ |
| public int method0(int[] args) {return QueryInterface(args[0], args[1]);} |
| public int method1(int[] args) {return AddRef();} |
| public int method2(int[] args) {return Release();} |
| public int method3(int[] args) {return QueryService(args[0], args[1], args[2]);} |
| }; |
| iInternetSecurityManager = new COMObject(new int[]{2, 0, 0, 1, 1, 3, 4, 8, 7, 3, 3}){ |
| public int method0(int[] args) {return QueryInterface(args[0], args[1]);} |
| public int method1(int[] args) {return AddRef();} |
| public int method2(int[] args) {return Release();} |
| public int method3(int[] args) {return SetSecuritySite(args[0]);} |
| public int method4(int[] args) {return GetSecuritySite(args[0]);} |
| public int method5(int[] args) {return MapUrlToZone(args[0], args[1], args[2]);} |
| public int method6(int[] args) {return GetSecurityId(args[0], args[1], args[2], args[3]);} |
| public int method7(int[] args) {return ProcessUrlAction(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);} |
| public int method8(int[] args) {return QueryCustomPolicy(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);} |
| public int method9(int[] args) {return SetZoneMapping(args[0], args[1], args[2]);} |
| public int method10(int[] args) {return GetZoneMappings(args[0], args[1], args[2]);} |
| }; |
| iOleCommandTarget = new COMObject(new int[]{2, 0, 0, 4, 5}) { |
| public int method0(int[] args) {return QueryInterface(args[0], args[1]);} |
| public int method1(int[] args) {return AddRef();} |
| public int method2(int[] args) {return Release();} |
| public int method3(int[] args) {return QueryStatus(args[0], args[1], args[2], args[3]);} |
| public int method4(int[] args) {return Exec(args[0], args[1], args[2], args[3], args[4]);} |
| }; |
| } |
| |
| protected void disposeCOMInterfaces() { |
| super.disposeCOMInterfaces(); |
| if (iDocHostUIHandler != null) { |
| iDocHostUIHandler.dispose(); |
| iDocHostUIHandler = null; |
| } |
| if (iDocHostShowUI != null) { |
| iDocHostShowUI.dispose(); |
| iDocHostShowUI = null; |
| } |
| if (iServiceProvider != null) { |
| iServiceProvider.dispose(); |
| iServiceProvider = null; |
| } |
| if (iInternetSecurityManager != null) { |
| iInternetSecurityManager.dispose(); |
| iInternetSecurityManager = null; |
| } |
| if (iOleCommandTarget != null) { |
| iOleCommandTarget.dispose(); |
| iOleCommandTarget = null; |
| } |
| } |
| |
| protected int AddRef() { |
| /* Workaround for javac 1.1.8 bug */ |
| return super.AddRef(); |
| } |
| |
| protected int QueryInterface(int riid, int ppvObject) { |
| int result = super.QueryInterface(riid, ppvObject); |
| if (result == COM.S_OK) return result; |
| if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG; |
| GUID guid = new GUID(); |
| COM.MoveMemory(guid, riid, GUID.sizeof); |
| if (COM.IsEqualGUID(guid, COM.IIDIDocHostUIHandler)) { |
| COM.MoveMemory(ppvObject, new int[] {iDocHostUIHandler.getAddress()}, 4); |
| AddRef(); |
| return COM.S_OK; |
| } |
| if (COM.IsEqualGUID(guid, COM.IIDIDocHostShowUI)) { |
| COM.MoveMemory(ppvObject, new int[] {iDocHostShowUI.getAddress()}, 4); |
| AddRef(); |
| return COM.S_OK; |
| } |
| if (COM.IsEqualGUID(guid, COM.IIDIServiceProvider)) { |
| COM.MoveMemory(ppvObject, new int[] {iServiceProvider.getAddress()}, 4); |
| AddRef(); |
| return COM.S_OK; |
| } |
| if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) { |
| COM.MoveMemory(ppvObject, new int[] {iInternetSecurityManager.getAddress()}, 4); |
| AddRef(); |
| return COM.S_OK; |
| } |
| if (COM.IsEqualGUID(guid, COM.IIDIOleCommandTarget)) { |
| COM.MoveMemory(ppvObject, new int[] {iOleCommandTarget.getAddress()}, 4); |
| AddRef(); |
| return COM.S_OK; |
| } |
| COM.MoveMemory(ppvObject, new int[] {0}, 4); |
| return COM.E_NOINTERFACE; |
| } |
| |
| /* IDocHostUIHandler */ |
| |
| int EnableModeless(int EnableModeless) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int FilterDataObject(int pDO, int ppDORet) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int GetDropTarget(int pDropTarget, int ppDropTarget) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int GetExternal(int ppDispatch) { |
| OS.MoveMemory(ppDispatch, new int[] {0}, 4); |
| return COM.S_FALSE; |
| } |
| |
| int GetHostInfo(int pInfo) { |
| Browser browser = (Browser)getParent().getParent(); |
| OS.MoveMemory(pInfo + 4, new int[] {browser.info}, 4); |
| return COM.S_OK; |
| } |
| |
| int GetOptionKeyPath(int pchKey, int dw) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int HideUI() { |
| return COM.E_NOTIMPL; |
| } |
| |
| int OnDocWindowActivate(int fActivate) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int OnFrameWindowActivate(int fActivate) { |
| return COM.E_NOTIMPL; |
| } |
| |
| protected int Release() { |
| /* Workaround for javac 1.1.8 bug */ |
| return super.Release(); |
| } |
| |
| int ResizeBorder(int prcBorder, int pUIWindow, int fFrameWindow) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int ShowContextMenu(int dwID, int ppt, int pcmdtReserved, int pdispReserved) { |
| Browser browser = (Browser)getParent().getParent(); |
| Event event = new Event(); |
| POINT pt = new POINT(); |
| OS.MoveMemory(pt, ppt, POINT.sizeof); |
| event.x = pt.x; |
| event.y = pt.y; |
| browser.notifyListeners(SWT.MenuDetect, event); |
| if (!event.doit) return COM.S_OK; |
| Menu menu = browser.getMenu(); |
| if (menu != null && !menu.isDisposed ()) { |
| if (pt.x != event.x || pt.y != event.y) { |
| menu.setLocation (event.x, event.y); |
| } |
| menu.setVisible (true); |
| return COM.S_OK; |
| } |
| /* Show default IE popup menu */ |
| return COM.S_FALSE; |
| } |
| |
| int ShowUI(int dwID, int pActiveObject, int pCommandTarget, int pFrame, int pDoc) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int TranslateAccelerator(int lpMsg, int pguidCmdGroup, int nCmdID) { |
| /* |
| * Feature on Internet Explorer. By default the embedded Internet Explorer control runs |
| * the Internet Explorer shortcuts (e.g. F5 for refresh). This overrides the shortcuts |
| * defined by SWT. The workaround is to forward the accelerator keys to the parent window |
| * and have Internet Explorer ignore the ones handled by the parent window. |
| */ |
| Menu menubar = getShell().getMenuBar(); |
| if (menubar != null && !menubar.isDisposed() && menubar.isEnabled()) { |
| Shell shell = menubar.getShell(); |
| int hwnd = shell.handle; |
| int hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0); |
| if (hAccel != 0) { |
| MSG msg = new MSG(); |
| OS.MoveMemory(msg, lpMsg, MSG.sizeof); |
| if (OS.TranslateAccelerator(hwnd, hAccel, msg) != 0) return COM.S_OK; |
| } |
| } |
| /* |
| * Feature on Internet Explorer. By default the embedded Internet Explorer control runs |
| * the Internet Explorer shortcuts. F5 causes refresh. CTRL-N opens a standalone Internet |
| * Explorer. These behaviours are undesired when rendering HTML in memory. |
| * The workaround is to block the default CTRL-N and F5 handling by IE when the URL is about:blank. |
| */ |
| OleAutomation auto = new OleAutomation(this); |
| int[] rgdispid = auto.getIDsOfNames(new String[] { "LocationURL" }); //$NON-NLS-1$ |
| Variant pVarResult = auto.getProperty(rgdispid[0]); |
| auto.dispose(); |
| int result = COM.S_FALSE; |
| if (pVarResult != null) { |
| if (pVarResult.getType() == OLE.VT_BSTR) { |
| String url = pVarResult.getString(); |
| if (url.equals(Browser.ABOUT_BLANK)) { |
| MSG msg = new MSG(); |
| OS.MoveMemory(msg, lpMsg, MSG.sizeof); |
| if (msg.message == OS.WM_KEYDOWN && msg.wParam == OS.VK_F5) result = COM.S_OK; |
| if (msg.message == OS.WM_KEYDOWN && msg.wParam == OS.VK_N && OS.GetKeyState (OS.VK_CONTROL) < 0) result = COM.S_OK; |
| } |
| } |
| pVarResult.dispose(); |
| } |
| return result; |
| } |
| |
| int TranslateUrl(int dwTranslate, int pchURLIn, int ppchURLOut) { |
| return COM.E_NOTIMPL; |
| } |
| |
| int UpdateUI() { |
| return COM.E_NOTIMPL; |
| } |
| |
| /* IDocHostShowUI */ |
| |
| int ShowMessage(int hwnd, int lpstrText, int lpstrCaption, int dwType, int lpstrHelpFile, int dwHelpContext, int plResult) { |
| /* |
| * Feature on IE. When IE navigates to a website that contains an ActiveX that is prevented from |
| * being executed, IE displays a message "Your current security settings prohibit running ActiveX |
| * controls on this page ...". The workaround is to selectively block this alert as indicated |
| * in the MSDN article "WebBrowser customization". |
| */ |
| /* resource identifier in shdoclc.dll for window caption "Your current security settings prohibit |
| * running ActiveX controls on this page ..." |
| */ |
| int IDS_MESSAGE_BOX_CAPTION = 8033; |
| if (lpstrText != 0) { |
| TCHAR lpLibFileName = new TCHAR (0, "SHDOCLC.DLL", true); //$NON-NLS-1$ |
| int hModule = OS.LoadLibrary(lpLibFileName); |
| if (hModule != 0) { |
| /* |
| * Note. lpstrText is a LPOLESTR, i.e. a null terminated unicode string LPWSTR, i.e. a WCHAR*. |
| * It is not a BSTR. A BSTR is a null terminated unicode string that contains its length |
| * at the beginning. |
| */ |
| int cnt = OS.wcslen(lpstrText); |
| char[] buffer = new char[cnt]; |
| /* |
| * Note. lpstrText is unicode on both unicode and ansi platforms. |
| * The nbr of chars is multiplied by the constant 2 and not by TCHAR.sizeof since |
| * TCHAR.sizeof returns 1 on ansi platforms. |
| */ |
| OS.MoveMemory(buffer, lpstrText, cnt * 2); |
| String text = new String(buffer); |
| /* provide a buffer large enough to hold the string to compare to and a null terminated character */ |
| int length = (OS.IsUnicode ? cnt : OS.WideCharToMultiByte (OS.CP_ACP, 0, buffer, cnt, 0, 0, null, null)) + 1; |
| |
| TCHAR lpBuffer = new TCHAR(0, length); |
| int result = OS.LoadString(hModule, IDS_MESSAGE_BOX_CAPTION, lpBuffer, length); |
| OS.FreeLibrary(hModule); |
| return result > 0 && text.equals(lpBuffer.toString(0, result)) ? COM.S_OK : COM.S_FALSE; |
| } |
| } |
| return COM.S_FALSE; |
| } |
| |
| /* Note. One of the arguments of ShowHelp is a POINT struct and not a pointer to a POINT struct. Because |
| * of the way Callback gets int parameters from a va_list of C arguments 2 integer arguments must be declared, |
| * ptMouse_x and ptMouse_y. Otherwise the Browser crashes when the user presses F1 to invoke |
| * the help. |
| */ |
| int ShowHelp(int hwnd, int pszHelpFile, int uCommand, int dwData, int ptMouse_x, int ptMouse_y, int pDispatchObjectHit) { |
| Browser browser = (Browser)getParent().getParent(); |
| Event event = new Event(); |
| event.type = SWT.Help; |
| event.display = getDisplay(); |
| event.widget = browser; |
| Shell shell = browser.getShell(); |
| Control control = browser; |
| do { |
| if (control.isListening(SWT.Help)) { |
| control.notifyListeners(SWT.Help, event); |
| break; |
| } |
| if (control == shell) break; |
| control = control.getParent(); |
| } while (true); |
| return COM.S_OK; |
| } |
| |
| /* IServiceProvider */ |
| |
| int QueryService(int guidService, int riid, int ppvObject) { |
| if (riid == 0 || ppvObject == 0) return COM.E_INVALIDARG; |
| GUID guid = new GUID(); |
| COM.MoveMemory(guid, riid, GUID.sizeof); |
| if (COM.IsEqualGUID(guid, COM.IIDIInternetSecurityManager)) { |
| COM.MoveMemory(ppvObject, new int[] {iInternetSecurityManager.getAddress()}, 4); |
| AddRef(); |
| return COM.S_OK; |
| } |
| COM.MoveMemory(ppvObject, new int[] {0}, 4); |
| return COM.E_NOINTERFACE; |
| } |
| |
| /* IInternetSecurityManager */ |
| |
| int SetSecuritySite(int pSite) { |
| return Browser.INET_E_DEFAULT_ACTION; |
| } |
| |
| int GetSecuritySite(int ppSite) { |
| return Browser.INET_E_DEFAULT_ACTION; |
| } |
| |
| int MapUrlToZone(int pwszUrl, int pdwZone, int dwFlags) { |
| /* |
| * Feature in IE 6 sp1. HTML rendered in memory |
| * does not enable local links but the exact same |
| * HTML document loaded through a local file is |
| * permitted to follow local links. The workaround is |
| * to return URLZONE_INTRANET instead of the default |
| * value URLZONE_LOCAL_MACHINE. |
| */ |
| COM.MoveMemory(pdwZone, new int[] {Browser.URLZONE_INTRANET}, 4); |
| return COM.S_OK; |
| } |
| |
| int GetSecurityId(int pwszUrl, int pbSecurityId, int pcbSecurityId, int dwReserved) { |
| return Browser.INET_E_DEFAULT_ACTION; |
| } |
| |
| int ProcessUrlAction(int pwszUrl, int dwAction, int pPolicy, int cbPolicy, int pContext, int cbContext, int dwFlags, int dwReserved) { |
| /* |
| * Feature in IE 6 sp1. HTML rendered in memory |
| * containing an OBJECT tag referring to a local file |
| * brings up a warning dialog asking the user whether |
| * it should proceed or not. The workaround is to |
| * set the policy to URLPOLICY_ALLOW in this case (dwAction |
| * value of 0x1406). |
| * |
| * Feature in IE. Security Patches and user settings |
| * affect the way the embedded web control behaves. The current |
| * approach is to consider the content trusted and allow |
| * all URLs by default. |
| */ |
| int policy = Browser.URLPOLICY_ALLOW; |
| /* |
| * Note. The URLACTION_JAVA flags refer to the applet tag that normally resolve to |
| * the Microsoft VM, not to the java OBJECT tag that resolves to the |
| * Sun plugin. Return URLPOLICY_JAVA_LOW to authorize applets instead of |
| * URLPOLICY_ALLOW that is interpreted as URLPOLICY_JAVA_PROHIBIT in this |
| * context. |
| */ |
| if (dwAction >= Browser.URLACTION_JAVA_MIN && dwAction <= Browser.URLACTION_JAVA_MAX) { |
| policy = Browser.URLPOLICY_JAVA_LOW; |
| } |
| /* |
| * Note. Some ActiveX plugins crash when executing |
| * inside the embedded explorer itself running into |
| * a JVM. The current workaround is to detect when |
| * such ActiveX is about to be started and refuse |
| * to execute it. |
| */ |
| if (dwAction == Browser.URLACTION_ACTIVEX_RUN) { |
| GUID guid = new GUID(); |
| COM.MoveMemory(guid, pContext, GUID.sizeof); |
| if (COM.IsEqualGUID(guid, COM.IIDJavaBeansBridge) || COM.IsEqualGUID(guid, COM.IIDShockwaveActiveXControl)) { |
| policy = Browser.URLPOLICY_DISALLOW; |
| } |
| } |
| if (cbPolicy >= 4) COM.MoveMemory(pPolicy, new int[] {policy}, 4); |
| return COM.S_OK; |
| } |
| |
| int QueryCustomPolicy(int pwszUrl, int guidKey, int ppPolicy, int pcbPolicy, int pContext, int cbContext, int dwReserved) { |
| return Browser.INET_E_DEFAULT_ACTION; |
| } |
| |
| int SetZoneMapping(int dwZone, int lpszPattern, int dwFlags) { |
| return Browser.INET_E_DEFAULT_ACTION; |
| } |
| |
| int GetZoneMappings(int dwZone, int ppenumString, int dwFlags) { |
| return COM.E_NOTIMPL; |
| } |
| |
| /* IOleCommandTarget */ |
| int QueryStatus(int pguidCmdGroup, int cCmds, int prgCmds, int pCmdText) { |
| return COM.E_NOTSUPPORTED; |
| } |
| |
| int Exec(int pguidCmdGroup, int nCmdID, int nCmdExecOpt, int pvaIn, int pvaOut) { |
| if (pguidCmdGroup != 0) { |
| GUID guid = new GUID(); |
| COM.MoveMemory(guid, pguidCmdGroup, GUID.sizeof); |
| |
| /* |
| * If a javascript error occurred then suppress IE's default script error dialog. |
| */ |
| if (COM.IsEqualGUID(guid, COM.CGID_DocHostCommandHandler)) { |
| if (nCmdID == OLECMDID_SHOWSCRIPTERROR) return COM.S_OK; |
| } |
| |
| /* |
| * Bug in Internet Explorer. OnToolBar TRUE is also fired when any of the |
| * address bar or menu bar are requested but not the tool bar. A workaround |
| * has been posted by a Microsoft developer on the public webbrowser_ctl |
| * newsgroup. The workaround is to implement the IOleCommandTarget interface |
| * to test the argument of an undocumented command. |
| */ |
| if (nCmdID == 1 && COM.IsEqualGUID(guid, COM.CGID_Explorer) && ((nCmdExecOpt & 0xFFFF) == 0xA)) { |
| Browser browser = (Browser)getParent().getParent(); |
| browser.toolBar = (nCmdExecOpt & 0xFFFF0000) != 0; |
| } |
| } |
| return COM.E_NOTSUPPORTED; |
| } |
| |
| } |