?? oleclientsite.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 java.io.File;import java.io.FileOutputStream;import java.io.FileInputStream;import java.io.IOException;import org.eclipse.swt.*;import org.eclipse.swt.internal.Compatibility;import org.eclipse.swt.internal.ole.win32.*;import org.eclipse.swt.graphics.*;import org.eclipse.swt.widgets.*;import org.eclipse.swt.internal.win32.*;/** * OleClientSite provides a site to manage an embedded OLE Document within a container. * * <p>The OleClientSite provides the following capabilities: * <ul> * <li>creates the in-place editor for a blank document or opening an existing OLE Document * <li>lays the editor out * <li>provides a mechanism for activating and deactivating the Document * <li>provides a mechanism for saving changes made to the document * </ul> * * <p>This object implements the OLE Interfaces IUnknown, IOleClientSite, IAdviseSink, * IOleInPlaceSite * * <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 OleClientSite extends Composite { // Interfaces for this Ole Client Container private COMObject iUnknown; private COMObject iOleClientSite; private COMObject iAdviseSink; private COMObject iOleInPlaceSite; private COMObject iOleDocumentSite; protected GUID appClsid; private GUID objClsid; private int refCount; // References to the associated Frame. protected OleFrame frame; // Access to the embedded/linked Ole Object protected IUnknown objIUnknown; protected IOleObject objIOleObject; protected IViewObject2 objIViewObject2; protected IOleInPlaceObject objIOleInPlaceObject; protected IOleCommandTarget objIOleCommandTarget; protected IOleDocumentView objDocumentView; // Related storage information protected IStorage tempStorage; // IStorage interface of the receiver // Internal state and style information private int aspect; // the display aspect of the embedded object, e.g., DvaspectContent or DvaspectIcon private int type; // Indicates the type of client that can be supported inside this container private boolean isStatic; // Indicates item's display is static, i.e., a bitmap, metafile, etc. private RECT borderWidths = new RECT(); private RECT indent = new RECT(); private boolean inUpdate = false; private boolean inInit = true; private boolean inDispose = false; private static final String WORDPROGID = "Word.Document"; //$NON-NLS-1$ private Listener listener; static final int STATE_NONE = 0; static final int STATE_RUNNING = 1; static final int STATE_INPLACEACTIVE = 2; static final int STATE_UIACTIVE = 3; static final int STATE_ACTIVE = 4; int state = STATE_NONE; protected OleClientSite(Composite parent, int style) { /* * NOTE: this constructor should never be used by itself because it does * not create an Ole Object */ super(parent, style); createCOMInterfaces(); // install the Ole Frame for this Client Site while (parent != null) { if (parent instanceof OleFrame){ frame = (OleFrame)parent; break; } parent = parent.getParent(); } if (frame == null) OLE.error(SWT.ERROR_INVALID_ARGUMENT); frame.AddRef(); aspect = COM.DVASPECT_CONTENT; type = COM.OLEEMBEDDED; isStatic = false; listener = new Listener() { public void handleEvent(Event e) { switch (e.type) { case SWT.Resize : case SWT.Move : onResize(e); break; case SWT.Dispose : onDispose(e); break; case SWT.FocusIn: onFocusIn(e); break; case SWT.FocusOut: onFocusOut(e); break; case SWT.Paint: onPaint(e); break; case SWT.Traverse: onTraverse(e); break; case SWT.KeyDown: /* required for traversal */ break; default : OLE.error(SWT.ERROR_NOT_IMPLEMENTED); } } }; frame.addListener(SWT.Resize, listener); frame.addListener(SWT.Move, listener); addListener(SWT.Dispose, listener); addListener(SWT.FocusIn, listener); addListener(SWT.FocusOut, listener); addListener(SWT.Paint, listener); addListener(SWT.Traverse, listener); addListener(SWT.KeyDown, listener);}/** * Create an OleClientSite child widget using the OLE Document type associated with the * specified file. The OLE Document type is determined either through header information in the file * or through a Registry entry for the file extension. Use 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 file the file that is to be opened in this OLE Document * * @exception SWTError * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread * <li>ERROR_ERROR_NULL_ARGUMENT when the parent is null</ul> * @exception SWTError * <ul><li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame * <li>ERROR_CANNOT_OPEN_FILE when failed to open file * <li>ERROR_INTERFACES_NOT_INITIALIZED when unable to create callbacks for OLE Interfaces</ul> * */public OleClientSite(Composite parent, int style, File file) { this(parent, style); try { if (file == null || file.isDirectory() || !file.exists()) OLE.error(OLE.ERROR_INVALID_ARGUMENT); // Is there an associated CLSID? appClsid = new GUID(); char[] fileName = (file.getAbsolutePath()+"\0").toCharArray(); int result = COM.GetClassFile(fileName, appClsid); if (result != COM.S_OK) OLE.error(OLE.ERROR_INVALID_CLASSID, result); // associated CLSID may not be installed on this machine if (getProgramID() == null) OLE.error(OLE.ERROR_INVALID_CLASSID, result); // Open a temporary storage object tempStorage = createTempStorage(); // Create ole object with storage object int[] address = new int[1]; result = COM.OleCreateFromFile(appClsid, fileName, 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]); // Init sinks addObjectReferences(); if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state = STATE_RUNNING; } catch (SWTException e) { dispose(); disposeCOMInterfaces(); throw e; }}/** * Create an OleClientSite child widget to edit a blank document using the specified OLE Document * application. Use 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 of am OLE Document application; * the value of the ProgID key or the value of the VersionIndependentProgID key specified * in the registry for the desired OLE Document (for example, the VersionIndependentProgID * for Word is Word.Document) * * @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_INVALID_ARGUMENT when the parent is not an OleFrame * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object * <li>ERROR_INTERFACES_NOT_INITIALIZED when unable to create callbacks for OLE Interfaces</ul> * */public OleClientSite(Composite parent, int style, String progId) { this(parent, style); try { appClsid = getClassID(progId); if (appClsid == null) OLE.error(OLE.ERROR_INVALID_CLASSID); // Open a temporary 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]); // Init sinks addObjectReferences(); if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state = STATE_RUNNING; } catch (SWTException e) { dispose(); disposeCOMInterfaces(); throw e; }}/** * Create an OleClientSite child widget to edit the specified file using the specified OLE Document * application. Use style bits to select a particular look or set of properties. * <p> * <b>IMPORTANT:</b> This method is <em>not</em> part of the public * API for <code>OleClientSite</code>. It is marked public only so that it * can be shared within the packages provided by SWT. It is not * available on all platforms, and should never be called from * application code. * </p> * @param parent a composite widget; must be an OleFrame * @param style the bitwise OR'ing of widget styles * @param progID the unique program identifier of am OLE Document application; * the value of the ProgID key or the value of the VersionIndependentProgID key specified * in the registry for the desired OLE Document (for example, the VersionIndependentProgID * for Word is Word.Document) * @param file the file that is to be opened in this OLE Document * * @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_OPEN_FILE when failed to open file * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame * <li>ERROR_INTERFACES_NOT_INITIALIZED when unable to create callbacks for OLE Interfaces</ul> * */public OleClientSite(Composite parent, int style, String progId, File file) { this(parent, style); try { if (file == null || file.isDirectory() || !file.exists()) OLE.error(OLE.ERROR_INVALID_ARGUMENT); appClsid = getClassID(progId); // Are we opening this file with the preferred OLE object? char[] fileName = (file.getAbsolutePath()+"\0").toCharArray(); GUID fileClsid = new GUID(); COM.GetClassFile(fileName, fileClsid); if (COM.IsEqualGUID(appClsid, fileClsid)){ // Using the same application that created file, therefore, use default mechanism. tempStorage = createTempStorage(); // Create ole object with storage object int[] address = new int[1]; int result = COM.OleCreateFromFile(appClsid, fileName, 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 { // Not using the same application that created file, therefore, copy from original file to a new storage file IStorage storage = null; if (COM.StgIsStorageFile(fileName) == COM.S_OK) { int[] address = new int[1]; int mode = COM.STGM_READ | COM.STGM_TRANSACTED | COM.STGM_SHARE_EXCLUSIVE; int result = COM.StgOpenStorage(fileName, 0, mode, 0, 0, address); //Does an AddRef if successful if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result); storage = new IStorage(address[0]); } else { // Original file is not a Storage file so copy contents to a stream in a new storage file int[] address = new int[1]; int mode = COM.STGM_READWRITE | COM.STGM_DIRECT | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_CREATE; int result = COM.StgCreateDocfile(null, mode | COM.STGM_DELETEONRELEASE, 0, address); // Increments ref count if successful if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result); storage = new IStorage(address[0]); // Create a stream on the storage object. // Word does not follow the standard and does not use "CONTENTS" as the name of // its primary stream String streamName = "CONTENTS"; //$NON-NLS-1$ GUID wordGUID = getClassID(WORDPROGID); if (COM.IsEqualGUID(appClsid, wordGUID)) streamName = "WordDocument"; //$NON-NLS-1$ address = new int[1]; result = storage.CreateStream(streamName, mode, 0, 0, address); // Increments ref count if successful if (result != COM.S_OK) { storage.Release(); OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result); } IStream stream = new IStream(address[0]); try { // Copy over data in file to named stream FileInputStream fileInput = new FileInputStream(file); int increment = 1024*4; byte[] buffer = new byte[increment]; int count = 0; while((count = fileInput.read(buffer)) > 0){ int pv = COM.CoTaskMemAlloc(count); OS.MoveMemory(pv, buffer, count); result = stream.Write(pv, count, null) ; COM.CoTaskMemFree(pv); if (result != COM.S_OK) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -