?? olecontrolsite.java
字號:
/******************************************************************************* * Copyright (c) 2000, 2003 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.ole.win32;import org.eclipse.swt.*;import org.eclipse.swt.internal.ole.win32.*;import org.eclipse.swt.graphics.*;import org.eclipse.swt.widgets.*;import org.eclipse.swt.internal.win32.*;/** * OleControlSite provides a site to manage an embedded ActiveX Control within a container. * * <p>In addition to the behaviour provided by OleClientSite, this object provides the following: * <ul> * <li>events from the ActiveX control * <li>notification of property changes from the ActiveX control * <li>simplified access to well known properties of the ActiveX Control (e.g. font, background color) * <li>expose ambient properties of the container to the ActiveX Control * </ul> * * <p>This object implements the OLE Interfaces IOleControlSite, IDispatch, and IPropertyNotifySink. * * <p>Note that although this class is a subclass of <code>Composite</code>, * it does not make sense to add <code>Control</code> children to it, * or set a layout on it. * </p><p> * <dl> * <dt><b>Styles</b> <dd>BORDER * <dt><b>Events</b> <dd>Dispose, Move, Resize * </dl> * */public class OleControlSite extends OleClientSite{ // interfaces for this container private COMObject iOleControlSite; private COMObject iDispatch; // supporting Property Change attributes private OlePropertyChangeSink olePropertyChangeSink; // supporting Event Sink attributes private OleEventSink[] oleEventSink = new OleEventSink[0]; private GUID[] oleEventSinkGUID = new GUID[0]; private int[] oleEventSinkIUnknown = new int[0]; // supporting information for the Control COM object private CONTROLINFO currentControlInfo; private int[] sitePropertyIds = new int[0]; private Variant[] sitePropertyValues = new Variant[0]; /** * Create an OleControlSite child widget using style bits * to select a particular look or set of properties. * * @param parent a composite widget; must be an OleFrame * @param style the bitwise OR'ing of widget styles * @param progID the unique program identifier which has been registered for this ActiveX Control; * the value of the ProgID key or the value of the VersionIndependentProgID key specified * in the registry for this Control (for example, the VersionIndependentProgID for * Internet Explorer is Shell.Explorer) * * @exception SWTError * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * <li>ERROR_ERROR_NULL_ARGUMENT when the parent is null * <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object * <li>ERROR_CANNOT_ACCESS_CLASSFACTORY when Class Factory could not be found * <li>ERROR_CANNOT_CREATE_LICENSED_OBJECT when failed to create a licensed OLE Object * <li>ERROR_INTERFACES_NOT_INITIALIZED when unable to create callbacks for OLE Interfaces</ul> * */public OleControlSite(Composite parent, int style, String progId) { super(parent, style); try { // check for licensing appClsid = getClassID(progId); if (appClsid == null) OLE.error(OLE.ERROR_INVALID_CLASSID); int licinfo = getLicenseInfo(appClsid); if (licinfo == 0) { // Open a storage object tempStorage = createTempStorage(); // Create ole object with storage object int[] address = new int[1]; int result = COM.OleCreate(appClsid, COM.IIDIUnknown, COM.OLERENDER_DRAW, null, 0, tempStorage.getAddress(), address); if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result); objIUnknown = new IUnknown(address[0]); } else { // Prepare the ClassFactory int[] ppvObject = new int[1]; try { int result = COM.CoGetClassObject(appClsid, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, 0, COM.IIDIClassFactory2, ppvObject); if (result != COM.S_OK) { OLE.error(OLE.ERROR_CANNOT_ACCESS_CLASSFACTORY, result); } IClassFactory2 classFactory = new IClassFactory2(ppvObject[0]); // Create Com Object ppvObject = new int[1]; result = classFactory.CreateInstanceLic(0, 0, COM.IIDIUnknown, licinfo, ppvObject); classFactory.Release(); if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_LICENSED_OBJECT, result); } finally { COM.SysFreeString(licinfo); } objIUnknown = new IUnknown(ppvObject[0]); // Prepare a storage medium ppvObject = new int[1]; if (objIUnknown.QueryInterface(COM.IIDIPersistStorage, ppvObject) == COM.S_OK) { IPersistStorage persist = new IPersistStorage(ppvObject[0]); tempStorage = createTempStorage(); persist.InitNew(tempStorage.getAddress()); persist.Release(); } } // Init sinks addObjectReferences(); // Init site properties setSiteProperty(COM.DISPID_AMBIENT_USERMODE, new Variant(true)); setSiteProperty(COM.DISPID_AMBIENT_UIDEAD, new Variant(false)); if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state= STATE_RUNNING; } catch (SWTError e) { dispose(); disposeCOMInterfaces(); throw e; } }/** * Adds the listener to receive events. * * @param eventID the id of the event * * @param listener the listener * * @exception SWTError * <ul><li>ERROR_NULL_ARGUMENT when listener is null</li></ul> */public void addEventListener(int eventID, OleListener listener) { if (listener == null) OLE.error (SWT.ERROR_NULL_ARGUMENT); GUID riid = getDefaultEventSinkGUID(objIUnknown); if (riid != null) { addEventListener(objIUnknown.getAddress(), riid, eventID, listener); } }static GUID getDefaultEventSinkGUID(IUnknown unknown) { // get Event Sink I/F from IProvideClassInfo2 int[] ppvObject = new int[1]; if (unknown.QueryInterface(COM.IIDIProvideClassInfo2, ppvObject) == COM.S_OK) { IProvideClassInfo2 pci2 = new IProvideClassInfo2(ppvObject[0]); GUID riid = new GUID(); int result = pci2.GetGUID(COM.GUIDKIND_DEFAULT_SOURCE_DISP_IID, riid); pci2.Release(); if (result == COM.S_OK) return riid; } // get Event Sink I/F from IProvideClassInfo if (unknown.QueryInterface(COM.IIDIProvideClassInfo, ppvObject) == COM.S_OK) { IProvideClassInfo pci = new IProvideClassInfo(ppvObject[0]); int[] ppTI = new int[1]; int[] ppEI = new int[1]; int result = pci.GetClassInfo(ppTI); pci.Release(); if (result == COM.S_OK && ppTI[0] != 0) { ITypeInfo classInfo = new ITypeInfo(ppTI[0]); int[] ppTypeAttr = new int[1]; result = classInfo.GetTypeAttr(ppTypeAttr); if (result == COM.S_OK && ppTypeAttr[0] != 0) { TYPEATTR typeAttribute = new TYPEATTR(); COM.MoveMemory(typeAttribute, ppTypeAttr[0], TYPEATTR.sizeof); classInfo.ReleaseTypeAttr(ppTypeAttr[0]); int implMask = COM.IMPLTYPEFLAG_FDEFAULT | COM.IMPLTYPEFLAG_FSOURCE | COM.IMPLTYPEFLAG_FRESTRICTED; int implBits = COM.IMPLTYPEFLAG_FDEFAULT | COM.IMPLTYPEFLAG_FSOURCE; for (int i = 0; i < typeAttribute.cImplTypes; i++) { int[] pImplTypeFlags = new int[1]; if (classInfo.GetImplTypeFlags(i, pImplTypeFlags) == COM.S_OK) { if ((pImplTypeFlags[0] & implMask) == implBits) { int[] pRefType = new int[1]; if (classInfo.GetRefTypeOfImplType(i, pRefType) == COM.S_OK) { classInfo.GetRefTypeInfo(pRefType[0], ppEI); } } } } } classInfo.Release(); if (ppEI[0] != 0) { ITypeInfo eventInfo = new ITypeInfo(ppEI[0]); ppTypeAttr = new int[1]; result = eventInfo.GetTypeAttr(ppTypeAttr); GUID riid = null; if (result == COM.S_OK && ppTypeAttr[0] != 0) { riid = new GUID(); COM.MoveMemory(riid, ppTypeAttr[0], GUID.sizeof); eventInfo.ReleaseTypeAttr(ppTypeAttr[0]); } eventInfo.Release(); return riid; } } } return null;}/** * Adds the listener to receive events. * * @since 2.0 * * @param automation the automation object that provides the event notification * * @param eventID the id of the event * * @param listener the listener * * @exception SWTError * <ul><li>ERROR_NULL_ARGUMENT when listener is null</li></ul> */public void addEventListener(OleAutomation automation, int eventID, OleListener listener) { if (listener == null || automation == null) OLE.error (SWT.ERROR_NULL_ARGUMENT); int address = automation.getAddress(); IUnknown unknown = new IUnknown(address); GUID riid = getDefaultEventSinkGUID(unknown); if (riid != null) { addEventListener(address, riid, eventID, listener); } }void addEventListener(int iunknown, GUID guid, int eventID, OleListener listener) { if (listener == null || iunknown == 0 || guid == null) OLE.error (SWT.ERROR_NULL_ARGUMENT); // have we connected to this kind of event sink before? int index = -1; for (int i = 0; i < oleEventSinkGUID.length; i++) { if (COM.IsEqualGUID(oleEventSinkGUID[i], guid)) { if (iunknown == oleEventSinkIUnknown[i]) { index = i; break; } } } if (index != -1) { oleEventSink[index].addListener(eventID, listener); } else { int oldLength = oleEventSink.length; OleEventSink[] newOleEventSink = new OleEventSink[oldLength + 1]; GUID[] newOleEventSinkGUID = new GUID[oldLength + 1]; int[] newOleEventSinkIUnknown = new int[oldLength + 1]; System.arraycopy(oleEventSink, 0, newOleEventSink, 0, oldLength); System.arraycopy(oleEventSinkGUID, 0, newOleEventSinkGUID, 0, oldLength); System.arraycopy(oleEventSinkIUnknown, 0, newOleEventSinkIUnknown, 0, oldLength); oleEventSink = newOleEventSink; oleEventSinkGUID = newOleEventSinkGUID; oleEventSinkIUnknown = newOleEventSinkIUnknown; oleEventSink[oldLength] = new OleEventSink(this, iunknown, guid); oleEventSinkGUID[oldLength] = guid; oleEventSinkIUnknown[oldLength] = iunknown; oleEventSink[oldLength].AddRef(); oleEventSink[oldLength].connect(); oleEventSink[oldLength].addListener(eventID, listener); }}protected void addObjectReferences() { super.addObjectReferences(); // Get property change notification from control connectPropertyChangeSink(); // Get access to the Control object int[] ppvObject = new int[1]; if (objIUnknown.QueryInterface(COM.IIDIOleControl, ppvObject) == COM.S_OK) { IOleControl objIOleControl = new IOleControl(ppvObject[0]); // ask the control for its info in case users // need to act on it currentControlInfo = new CONTROLINFO(); objIOleControl.GetControlInfo(currentControlInfo); objIOleControl.Release(); } }/** * Adds the listener to receive events. * * @param propertyID the identifier of the property * @param listener the listener * * @exception SWTError * <ul><li>ERROR_NULL_ARGUMENT when listener is null</li></ul> */public void addPropertyListener(int propertyID, OleListener listener) { if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); olePropertyChangeSink.addListener(propertyID, listener); }private void connectPropertyChangeSink() { olePropertyChangeSink = new OlePropertyChangeSink(this); olePropertyChangeSink.AddRef(); olePropertyChangeSink.connect(objIUnknown);}protected void createCOMInterfaces () { super.createCOMInterfaces(); // register each of the interfaces that this object implements iOleControlSite = new COMObject(new int[]{2, 0, 0, 0, 1, 1, 3, 2, 1, 0}){ 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 OnControlInfoChanged();} // method4 LockInPlaceActive - not implemented // method5 GetExtendedControl - not implemented // method6 TransformCoords - not implemented // method7 Translate Accelerator - not implemented public int method8(int[] args) {return OnFocus(args[0]);} // method9 ShowPropertyFrame - not implemented }; iDispatch = new COMObject(new int[]{2, 0, 0, 1, 3, 5, 8}){ 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();} // method3 GetTypeInfoCount - not implemented // method4 GetTypeInfo - not implemented // method5 GetIDsOfNames - not implemented public int method6(int[] args) {return Invoke(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);} };}private void disconnectEventSinks() { for (int i = 0; i < oleEventSink.length; i++) { OleEventSink sink = oleEventSink[i]; sink.disconnect(); sink.Release(); } oleEventSink = new OleEventSink[0]; oleEventSinkGUID = new GUID[0]; oleEventSinkIUnknown = new int[0];}private void disconnectPropertyChangeSink() { if (olePropertyChangeSink != null) { olePropertyChangeSink.disconnect(objIUnknown); olePropertyChangeSink.Release(); } olePropertyChangeSink = null;}protected void disposeCOMInterfaces() { super.disposeCOMInterfaces(); if (iOleControlSite != null) iOleControlSite.dispose(); iOleControlSite = null; if (iDispatch != null) iDispatch.dispose(); iDispatch = null;}public Color getBackground () { if (objIUnknown != null) { // !! We are getting the OLE_COLOR - should we change this to the COLORREF value? OleAutomation oleObject= new OleAutomation(this); Variant varBackColor = oleObject.getProperty(COM.DISPID_BACKCOLOR); oleObject.dispose(); if (varBackColor != null){ int[] colorRef = new int[1]; if (COM.OleTranslateColor(varBackColor.getInt(), getDisplay().hPalette, colorRef) == COM.S_OK) return Color.win32_new(getDisplay(), colorRef[0]); } } return super.getBackground();}public Font getFont () { if (objIUnknown != null) { OleAutomation oleObject= new OleAutomation(this); Variant varDispFont = oleObject.getProperty(COM.DISPID_FONT); oleObject.dispose(); if (varDispFont != null){ OleAutomation iDispFont = varDispFont.getAutomation();
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -