📄 browser.java
字号:
/******************************************************************************* * Copyright (c) 2003, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/package org.eclipse.swt.browser;import org.eclipse.swt.*;import org.eclipse.swt.graphics.*;import org.eclipse.swt.internal.ole.win32.*;import org.eclipse.swt.internal.win32.*;import org.eclipse.swt.ole.win32.*;import org.eclipse.swt.widgets.*;/** * Instances of this class implement the browser user interface * metaphor. It allows the user to visualize and navigate through * HTML documents. * <p> * Note that although this class is a subclass of <code>Composite</code>, * it does not make sense to set a layout on it. * </p><p> * IMPORTANT: This class is <em>not</em> intended to be subclassed. * </p> * * @since 3.0 */public class Browser extends Composite { OleFrame frame; OleControlSite site; OleAutomation auto; boolean back; boolean forward; Point location; Point size; int globalDispatch; String html; /* External Listener management */ CloseWindowListener[] closeWindowListeners = new CloseWindowListener[0]; LocationListener[] locationListeners = new LocationListener[0]; OpenWindowListener[] openWindowListeners = new OpenWindowListener[0]; ProgressListener[] progressListeners = new ProgressListener[0]; StatusTextListener[] statusTextListeners = new StatusTextListener[0]; TitleListener[] titleListeners = new TitleListener[0]; VisibilityWindowListener[] visibilityWindowListeners = new VisibilityWindowListener[0]; static final int BeforeNavigate2 = 0xfa; static final int CommandStateChange = 0x69; static final int DocumentComplete = 0x103; static final int NavigateComplete2 = 0xfc; static final int NewWindow2 = 0xfb; static final int OnVisible = 0xfe; static final int ProgressChange = 0x6c; static final int RegisterAsBrowser = 0x228; static final int StatusTextChange = 0x66; static final int TitleChange = 0x71; static final int WindowClosing = 0x107; static final int WindowSetHeight = 0x10b; static final int WindowSetLeft = 0x108; static final int WindowSetTop = 0x109; static final int WindowSetWidth = 0x10a; static final short CSC_NAVIGATEFORWARD = 1; static final short CSC_NAVIGATEBACK = 2; static final int INET_E_DEFAULT_ACTION = 0x800C0011; static final int URLPOLICY_ALLOW = 0x00; static final int URLPOLICY_DISALLOW = 0x03; static final int URLZONE_LOCAL_MACHINE = 0; static final int URLZONE_INTRANET = 1; static final int URLACTION_ACTIVEX_MIN = 0x00001200; static final int URLACTION_ACTIVEX_MAX = 0x000013ff; static final int URLACTION_JAVA_MIN = 0x00001C00; static final int URLPOLICY_JAVA_LOW = 0x00030000; static final int URLACTION_JAVA_MAX = 0x00001Cff; static final int DISPID_AMBIENT_DLCONTROL = -5512; static final int DLCTL_DLIMAGES = 0x00000010; static final int DLCTL_VIDEOS = 0x00000020; static final int DLCTL_BGSOUNDS = 0x00000040; static final int DLCTL_NO_SCRIPTS = 0x00000080; static final int DLCTL_NO_JAVA = 0x00000100; static final int DLCTL_NO_RUNACTIVEXCTLS = 0x00000200; static final int DLCTL_NO_DLACTIVEXCTLS = 0x00000400; static final int DLCTL_DOWNLOADONLY = 0x00000800; static final int DLCTL_NO_FRAMEDOWNLOAD = 0x00001000; static final int DLCTL_RESYNCHRONIZE = 0x00002000; static final int DLCTL_PRAGMA_NO_CACHE = 0x00004000; static final int DLCTL_FORCEOFFLINE = 0x10000000; static final int DLCTL_NO_CLIENTPULL = 0x20000000; static final int DLCTL_SILENT = 0x40000000; static final String ABOUT_BLANK = "about:blank"; //$NON-NLS-1$ static final String URL_CAB = ".cab"; //$NON-NLS-1$ static final String URL_DIRECTOR = "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab"; //$NON-NLS-1$ static final String URL_JAVA = "http://java.sun.com/products/plugin/autodl/jinstall"; //$NON-NLS-1$ static final String URL_JAVA_15 = "http://java.sun.com/update"; //$NON-NLS-1$ /* Package Name */ static final String PACKAGE_PREFIX = "org.eclipse.swt.browser."; //$NON-NLS-1$/** * Constructs a new instance of this class given its parent * and a style value describing its behavior and appearance. * <p> * The style value is either one of the style constants defined in * class <code>SWT</code> which is applicable to instances of this * class, or must be built by <em>bitwise OR</em>'ing together * (that is, using the <code>int</code> "|" operator) two or more * of those <code>SWT</code> style constants. The class description * lists the style constants that are applicable to the class. * Style bits are also inherited from superclasses. * </p> * * @param parent a widget which will be the parent of the new instance (cannot be null) * @param style the style of widget to construct * * @exception IllegalArgumentException <ul> * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> * </ul> * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> * </ul> * @exception SWTError <ul> * <li>ERROR_NO_HANDLES if a handle could not be obtained for browser creation</li> * </ul> * * @see #getStyle * * @since 3.0 */public Browser(Composite parent, int style) { super(parent, style); frame = new OleFrame(this, SWT.NONE); try { site = new WebSite(frame, SWT.NONE, "Shell.Explorer"); //$NON-NLS-1$ } catch (SWTException e) { dispose(); SWT.error(SWT.ERROR_NO_HANDLES); } site.doVerb(OLE.OLEIVERB_INPLACEACTIVATE); auto = new OleAutomation(site); addListener(SWT.Dispose, new Listener() { public void handleEvent(Event e) { if (auto != null) auto.dispose(); auto = null; } }); addListener(SWT.Resize, new Listener() { public void handleEvent(Event e) { frame.setBounds(getClientArea()); } }); OleListener listener = new OleListener() { public void handleEvent(OleEvent event) { switch (event.type) { case BeforeNavigate2 : { Variant varResult = event.arguments[1]; String url = varResult.getString(); LocationEvent newEvent = new LocationEvent(Browser.this); newEvent.display = getDisplay(); newEvent.widget = Browser.this; newEvent.location = url; newEvent.doit = true; for (int i = 0; i < locationListeners.length; i++) locationListeners[i].changing(newEvent); Variant cancel = event.arguments[6]; if (cancel != null) { int pCancel = cancel.getByRef(); COM.MoveMemory(pCancel, new short[]{newEvent.doit ? COM.VARIANT_FALSE : COM.VARIANT_TRUE}, 2); } break; } case CommandStateChange : { boolean enabled = false; Variant varResult = event.arguments[0]; int command = varResult.getInt(); varResult = event.arguments[1]; enabled = varResult.getBoolean(); switch (command) { case CSC_NAVIGATEBACK : back = enabled; break; case CSC_NAVIGATEFORWARD : forward = enabled; break; } break; } case DocumentComplete: { Variant varResult = event.arguments[0]; IDispatch dispatch = varResult.getDispatch(); varResult = event.arguments[1]; String url = varResult.getString(); if (html != null && url.equals(ABOUT_BLANK)) { int charCount = html.length(); char[] chars = new char[charCount]; html.getChars(0, charCount, chars, 0); html = null; int byteCount = OS.WideCharToMultiByte(OS.CP_UTF8, 0, chars, charCount, null, 0, null, null); /* * Note. Internet Explorer appears to treat the data loaded with * nsIPersistStreamInit.Load as if it were encoded using the default * local charset. There does not seem to be an API to set the * desired charset explicitely in this case. The fix is to * prepend the UTF-8 Byte Order Mark signature to the data. */ byte[] UTF8BOM = {(byte)0xEF, (byte)0xBB, (byte)0xBF}; int hGlobal = OS.GlobalAlloc(OS.GMEM_FIXED, UTF8BOM.length + byteCount); if (hGlobal != 0) { OS.MoveMemory(hGlobal, UTF8BOM, UTF8BOM.length); OS.WideCharToMultiByte(OS.CP_UTF8, 0, chars, charCount, hGlobal + UTF8BOM.length, byteCount, null, null); int[] ppstm = new int[1]; /* * Note. CreateStreamOnHGlobal is called with the flag fDeleteOnRelease. * If the call succeeds the buffer hGlobal is freed automatically * when the IStream object is released. If the call fails, free the buffer * hGlobal. */ if (OS.CreateStreamOnHGlobal(hGlobal, true, ppstm) == OS.S_OK) { int[] rgdispid = auto.getIDsOfNames(new String[] {"Document"}); //$NON-NLS-1$ Variant pVarResult = auto.getProperty(rgdispid[0]); IDispatch dispatchDocument = pVarResult.getDispatch(); int[] ppvObject = new int[1]; int result = dispatchDocument.QueryInterface(COM.IIDIPersistStreamInit, ppvObject); if (result == OS.S_OK) { IPersistStreamInit persistStreamInit = new IPersistStreamInit(ppvObject[0]); if (persistStreamInit.InitNew() == OS.S_OK) { persistStreamInit.Load(ppstm[0]); } persistStreamInit.Release(); } pVarResult.dispose(); /* * This code is intentionally commented. The IDispatch obtained from a Variant * did not increase the reference count for the enclosed interface. */ //dispatchDocument.Release(); IUnknown stream = new IUnknown(ppstm[0]); stream.Release(); } else { OS.GlobalFree(hGlobal); } } } else { Variant variant = new Variant(auto); IDispatch top = variant.getDispatch(); LocationEvent locationEvent = new LocationEvent(Browser.this); locationEvent.display = getDisplay(); locationEvent.widget = Browser.this; locationEvent.location = url; locationEvent.top = top.getAddress() == dispatch.getAddress(); for (int i = 0; i < locationListeners.length; i++) locationListeners[i].changed(locationEvent); /* * This code is intentionally commented. A Variant constructed from an * OleAutomation object does not increase its reference count. The IDispatch * obtained from this Variant did not increase the reference count for the * OleAutomation instance either. */ //top.Release(); //variant.dispose(); /* * Note. The completion of the page loading is detected as * described in the MSDN article "Determine when a page is * done loading in WebBrowser Control". */ if (globalDispatch != 0 && dispatch.getAddress() == globalDispatch) { /* final document complete */ globalDispatch = 0; ProgressEvent progressEvent = new ProgressEvent(Browser.this); progressEvent.display = getDisplay(); progressEvent.widget = Browser.this; for (int i = 0; i < progressListeners.length; i++) progressListeners[i].completed(progressEvent); } } /* * This code is intentionally commented. This IDispatch was received * as an argument from the OleEvent and it will be disposed along with * the other arguments. */ //dispatch.Release(); break; } case NavigateComplete2: { Variant varResult = event.arguments[0]; IDispatch dispatch = varResult.getDispatch(); if (globalDispatch == 0) globalDispatch = dispatch.getAddress(); break; } case NewWindow2 : { WindowEvent newEvent = new WindowEvent(Browser.this); newEvent.display = getDisplay(); newEvent.widget = Browser.this; for (int i = 0; i < openWindowListeners.length; i++) openWindowListeners[i].open(newEvent); Browser browser = newEvent.browser; boolean doit = browser != null && !browser.isDisposed(); if (doit) { Variant variant = new Variant(browser.auto); IDispatch iDispatch = variant.getDispatch(); Variant ppDisp = event.arguments[0]; int byref = ppDisp.getByRef(); if (byref != 0) COM.MoveMemory(byref, new int[] {iDispatch.getAddress()}, 4); /* * This code is intentionally commented. A Variant constructed from an * OleAutomation object does not increase its reference count. The IDispatch * obtained from this Variant did not increase the reference count for the * OleAutomation instance either. */ //variant.dispose(); //iDispatch.Release(); } Variant cancel = event.arguments[1]; int pCancel = cancel.getByRef(); COM.MoveMemory(pCancel, new short[]{doit ? COM.VARIANT_FALSE : COM.VARIANT_TRUE}, 2); break; } case OnVisible : { Variant arg1 = event.arguments[0]; boolean visible = arg1.getBoolean(); WindowEvent newEvent = new WindowEvent(Browser.this); newEvent.display = getDisplay(); newEvent.widget = Browser.this; if (visible) { for (int i = 0; i < visibilityWindowListeners.length; i++) { newEvent.location = location; newEvent.size = size; visibilityWindowListeners[i].show(newEvent); location = null; size = null; } } else { for (int i = 0; i < visibilityWindowListeners.length; i++) visibilityWindowListeners[i].hide(newEvent); } break; } case ProgressChange : { Variant arg1 = event.arguments[0]; int nProgress = arg1.getType() != OLE.VT_I4 ? 0 : arg1.getInt(); // may be -1 Variant arg2 = event.arguments[1]; int nProgressMax = arg2.getType() != OLE.VT_I4 ? 0 : arg2.getInt(); ProgressEvent newEvent = new ProgressEvent(Browser.this); newEvent.display = getDisplay(); newEvent.widget = Browser.this; newEvent.current = nProgress; newEvent.total = nProgressMax; if (nProgress != -1) { for (int i = 0; i < progressListeners.length; i++) progressListeners[i].changed(newEvent); } break; } case StatusTextChange : { Variant arg1 = event.arguments[0]; if (arg1.getType() == OLE.VT_BSTR) { String text = arg1.getString(); StatusTextEvent newEvent = new StatusTextEvent(Browser.this); newEvent.display = getDisplay(); newEvent.widget = Browser.this; newEvent.text = text; for (int i = 0; i < statusTextListeners.length; i++) statusTextListeners[i].changed(newEvent); } break; } case TitleChange : { Variant arg1 = event.arguments[0]; if (arg1.getType() == OLE.VT_BSTR) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -