KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > ole > win32 > OleClientSite


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.ole.win32;
12
13 import java.io.File JavaDoc;
14 import java.io.FileOutputStream JavaDoc;
15 import java.io.FileInputStream JavaDoc;
16 import java.io.IOException JavaDoc;
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.internal.Compatibility;
19 import org.eclipse.swt.internal.ole.win32.*;
20 import org.eclipse.swt.graphics.*;
21 import org.eclipse.swt.widgets.*;
22 import org.eclipse.swt.internal.win32.*;
23 /**
24  * OleClientSite provides a site to manage an embedded OLE Document within a container.
25  *
26  * <p>The OleClientSite provides the following capabilities:
27  * <ul>
28  * <li>creates the in-place editor for a blank document or opening an existing OLE Document
29  * <li>lays the editor out
30  * <li>provides a mechanism for activating and deactivating the Document
31  * <li>provides a mechanism for saving changes made to the document
32  * </ul>
33  *
34  * <p>This object implements the OLE Interfaces IUnknown, IOleClientSite, IAdviseSink,
35  * IOleInPlaceSite
36  *
37  * <p>Note that although this class is a subclass of <code>Composite</code>,
38  * it does not make sense to add <code>Control</code> children to it,
39  * or set a layout on it.
40  * </p><p>
41  * <dl>
42  * <dt><b>Styles</b> <dd>BORDER
43  * <dt><b>Events</b> <dd>Dispose, Move, Resize
44  * </dl>
45  *
46  */

47 public class OleClientSite extends Composite {
48         
49     // Interfaces for this Ole Client Container
50
private COMObject iUnknown;
51     private COMObject iOleClientSite;
52     private COMObject iAdviseSink;
53     private COMObject iOleInPlaceSite;
54     private COMObject iOleDocumentSite;
55
56     protected GUID appClsid;
57     private GUID objClsid;
58     private int refCount;
59     
60     // References to the associated Frame.
61
protected OleFrame frame;
62     
63     // Access to the embedded/linked Ole Object
64
protected IUnknown objIUnknown;
65     protected IOleObject objIOleObject;
66     protected IViewObject2 objIViewObject2;
67     protected IOleInPlaceObject objIOleInPlaceObject;
68     protected IOleCommandTarget objIOleCommandTarget;
69     protected IOleDocumentView objDocumentView;
70            
71     // Related storage information
72
protected IStorage tempStorage; // IStorage interface of the receiver
73

74     // Internal state and style information
75
private int aspect; // the display aspect of the embedded object, e.g., DvaspectContent or DvaspectIcon
76
private int type; // Indicates the type of client that can be supported inside this container
77
private boolean isStatic; // Indicates item's display is static, i.e., a bitmap, metafile, etc.
78

79     private RECT borderWidths = new RECT();
80     private RECT indent = new RECT();
81     private boolean inUpdate = false;
82     private boolean inInit = true;
83     private boolean inDispose = false;
84         
85     private static final String JavaDoc WORDPROGID = "Word.Document"; //$NON-NLS-1$
86

87     private Listener listener;
88     
89     static final int STATE_NONE = 0;
90     static final int STATE_RUNNING = 1;
91     static final int STATE_INPLACEACTIVE = 2;
92     static final int STATE_UIACTIVE = 3;
93     static final int STATE_ACTIVE = 4;
94     int state = STATE_NONE;
95     
96 protected OleClientSite(Composite parent, int style) {
97     /*
98      * NOTE: this constructor should never be used by itself because it does
99      * not create an Ole Object
100      */

101     super(parent, style);
102     
103     createCOMInterfaces();
104     
105     // install the Ole Frame for this Client Site
106
while (parent != null) {
107         if (parent instanceof OleFrame){
108             frame = (OleFrame)parent;
109             break;
110         }
111         parent = parent.getParent();
112     }
113     if (frame == null) OLE.error(SWT.ERROR_INVALID_ARGUMENT);
114     frame.AddRef();
115     
116     aspect = COM.DVASPECT_CONTENT;
117     type = COM.OLEEMBEDDED;
118     isStatic = false;
119
120     listener = new Listener() {
121         public void handleEvent(Event e) {
122             switch (e.type) {
123             case SWT.Resize :
124             case SWT.Move : onResize(e); break;
125             case SWT.Dispose : onDispose(e); break;
126             case SWT.FocusIn: onFocusIn(e); break;
127             case SWT.FocusOut: onFocusOut(e); break;
128             case SWT.Paint: onPaint(e); break;
129             case SWT.Traverse: onTraverse(e); break;
130             case SWT.KeyDown: /* required for traversal */ break;
131             default :
132                 OLE.error(SWT.ERROR_NOT_IMPLEMENTED);
133             }
134         }
135     };
136
137     frame.addListener(SWT.Resize, listener);
138     frame.addListener(SWT.Move, listener);
139     addListener(SWT.Dispose, listener);
140     addListener(SWT.FocusIn, listener);
141     addListener(SWT.FocusOut, listener);
142     addListener(SWT.Paint, listener);
143     addListener(SWT.Traverse, listener);
144     addListener(SWT.KeyDown, listener);
145 }
146 /**
147  * Create an OleClientSite child widget using the OLE Document type associated with the
148  * specified file. The OLE Document type is determined either through header information in the file
149  * or through a Registry entry for the file extension. Use style bits to select a particular look
150  * or set of properties.
151  *
152  * @param parent a composite widget; must be an OleFrame
153  * @param style the bitwise OR'ing of widget styles
154  * @param file the file that is to be opened in this OLE Document
155  *
156  * @exception IllegalArgumentException
157  * <ul><li>ERROR_NULL_ARGUMENT when the parent is null
158  * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame</ul>
159  * @exception SWTException
160  * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
161  * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object
162  * <li>ERROR_CANNOT_OPEN_FILE when failed to open file
163  * <li>ERROR_INTERFACE_NOT_FOUND when unable to create callbacks for OLE Interfaces
164  * <li>ERROR_INVALID_CLASSID
165  * </ul>
166  */

167 public OleClientSite(Composite parent, int style, File JavaDoc file) {
168     this(parent, style);
169     try {
170
171         if (file == null || file.isDirectory() || !file.exists())
172             OLE.error(OLE.ERROR_INVALID_ARGUMENT);
173             
174         // Is there an associated CLSID?
175
appClsid = new GUID();
176         char[] fileName = (file.getAbsolutePath()+"\0").toCharArray();
177         int result = COM.GetClassFile(fileName, appClsid);
178         if (result != COM.S_OK)
179             OLE.error(OLE.ERROR_INVALID_CLASSID, result);
180         // associated CLSID may not be installed on this machine
181
if (getProgramID() == null)
182             OLE.error(OLE.ERROR_INVALID_CLASSID, result);
183             
184         // Open a temporary storage object
185
tempStorage = createTempStorage();
186
187         // Create ole object with storage object
188
int[] address = new int[1];
189         result = COM.OleCreateFromFile(appClsid, fileName, COM.IIDIUnknown, COM.OLERENDER_DRAW, null, 0, tempStorage.getAddress(), address);
190         if (result != COM.S_OK)
191             OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
192
193         objIUnknown = new IUnknown(address[0]);
194         
195         // Init sinks
196
addObjectReferences();
197         
198         if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state = STATE_RUNNING;
199     } catch (SWTException e) {
200         dispose();
201         disposeCOMInterfaces();
202         throw e;
203     }
204 }
205 /**
206  * Create an OleClientSite child widget to edit a blank document using the specified OLE Document
207  * application. Use style bits to select a particular look or set of properties.
208  *
209  * @param parent a composite widget; must be an OleFrame
210  * @param style the bitwise OR'ing of widget styles
211  * @param progId the unique program identifier of am OLE Document application;
212  * the value of the ProgID key or the value of the VersionIndependentProgID key specified
213  * in the registry for the desired OLE Document (for example, the VersionIndependentProgID
214  * for Word is Word.Document)
215  *
216  * @exception IllegalArgumentException
217  *<ul>
218  * <li>ERROR_NULL_ARGUMENT when the parent is null
219  * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame
220  *</ul>
221  * @exception SWTException
222  * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
223  * <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID
224  * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object
225  * </ul>
226  */

227 public OleClientSite(Composite parent, int style, String JavaDoc progId) {
228     this(parent, style);
229     try {
230         appClsid = getClassID(progId);
231         if (appClsid == null)
232             OLE.error(OLE.ERROR_INVALID_CLASSID);
233             
234         // Open a temporary storage object
235
tempStorage = createTempStorage();
236     
237         // Create ole object with storage object
238
int[] address = new int[1];
239         int result = COM.OleCreate(appClsid, COM.IIDIUnknown, COM.OLERENDER_DRAW, null, 0, tempStorage.getAddress(), address);
240         if (result != COM.S_OK)
241             OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
242
243         objIUnknown = new IUnknown(address[0]);
244
245         // Init sinks
246
addObjectReferences();
247
248         if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state = STATE_RUNNING;
249         
250     } catch (SWTException e) {
251         dispose();
252         disposeCOMInterfaces();
253         throw e;
254     }
255 }
256 /**
257  * Create an OleClientSite child widget to edit the specified file using the specified OLE Document
258  * application. Use style bits to select a particular look or set of properties.
259  * <p>
260  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
261  * API for <code>OleClientSite</code>. It is marked public only so that it
262  * can be shared within the packages provided by SWT. It is not
263  * available on all platforms, and should never be called from
264  * application code.
265  * </p>
266  * @param parent a composite widget; must be an OleFrame
267  * @param style the bitwise OR'ing of widget styles
268  * @param progId the unique program identifier of am OLE Document application;
269  * the value of the ProgID key or the value of the VersionIndependentProgID key specified
270  * in the registry for the desired OLE Document (for example, the VersionIndependentProgID
271  * for Word is Word.Document)
272  * @param file the file that is to be opened in this OLE Document
273  *
274  * @exception IllegalArgumentException
275  * <ul><li>ERROR_NULL_ARGUMENT when the parent is null
276  * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame</ul>
277  * @exception SWTException
278  * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
279  * <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID
280  * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object
281  * <li>ERROR_CANNOT_OPEN_FILE when failed to open file
282  * </ul>
283  */

284 public OleClientSite(Composite parent, int style, String JavaDoc progId, File JavaDoc file) {
285     this(parent, style);
286     try {
287         if (file == null || file.isDirectory() || !file.exists()) OLE.error(OLE.ERROR_INVALID_ARGUMENT);
288         appClsid = getClassID(progId);
289         if (appClsid == null) OLE.error(OLE.ERROR_INVALID_CLASSID);
290         
291         // Are we opening this file with the preferred OLE object?
292
char[] fileName = (file.getAbsolutePath()+"\0").toCharArray();
293         GUID fileClsid = new GUID();
294         COM.GetClassFile(fileName, fileClsid);
295     
296         if (COM.IsEqualGUID(appClsid, fileClsid)){
297             // Using the same application that created file, therefore, use default mechanism.
298
tempStorage = createTempStorage();
299             // Create ole object with storage object
300
int[] address = new int[1];
301             int result = COM.OleCreateFromFile(appClsid, fileName, COM.IIDIUnknown, COM.OLERENDER_DRAW, null, 0, tempStorage.getAddress(), address);
302             if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
303             objIUnknown = new IUnknown(address[0]);
304         } else {
305             // Not using the same application that created file, therefore, copy from original file to a new storage file
306
IStorage storage = null;
307             if (COM.StgIsStorageFile(fileName) == COM.S_OK) {
308                 int[] address = new int[1];
309                 int mode = COM.STGM_READ | COM.STGM_TRANSACTED | COM.STGM_SHARE_EXCLUSIVE;
310                 int result = COM.StgOpenStorage(fileName, 0, mode, 0, 0, address); //Does an AddRef if successful
311
if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result);
312                 storage = new IStorage(address[0]);
313             } else {
314                 // Original file is not a Storage file so copy contents to a stream in a new storage file
315
int[] address = new int[1];
316                 int mode = COM.STGM_READWRITE | COM.STGM_DIRECT | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_CREATE;
317                 int result = COM.StgCreateDocfile(null, mode | COM.STGM_DELETEONRELEASE, 0, address); // Increments ref count if successful
318
if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result);
319                 storage = new IStorage(address[0]);
320                 // Create a stream on the storage object.
321
// Word does not follow the standard and does not use "CONTENTS" as the name of
322
// its primary stream
323
String JavaDoc streamName = "CONTENTS"; //$NON-NLS-1$
324
GUID wordGUID = getClassID(WORDPROGID);
325                 if (wordGUID != null && COM.IsEqualGUID(appClsid, wordGUID)) streamName = "WordDocument"; //$NON-NLS-1$
326
address = new int[1];
327                 result = storage.CreateStream(streamName, mode, 0, 0, address); // Increments ref count if successful
328
if (result != COM.S_OK) {
329                     storage.Release();
330                     OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result);
331                 }
332                 IStream stream = new IStream(address[0]);
333                 try {
334                     // Copy over data in file to named stream
335
FileInputStream JavaDoc fileInput = new FileInputStream JavaDoc(file);
336                     int increment = 1024*4;
337                     byte[] buffer = new byte[increment];
338                     int count = 0;
339                     while((count = fileInput.read(buffer)) > 0){
340                         int pv = COM.CoTaskMemAlloc(count);
341                         OS.MoveMemory(pv, buffer, count);
342                         result = stream.Write(pv, count, null) ;
343                         COM.CoTaskMemFree(pv);
344                         if (result != COM.S_OK) {
345                             fileInput.close();
346                             stream.Release();
347                             storage.Release();
348                             OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result);
349                         }
350                     }
351                     fileInput.close();
352                     stream.Commit(COM.STGC_DEFAULT);
353                     stream.Release();
354                 } catch (IOException JavaDoc err) {
355                     stream.Release();
356                     storage.Release();
357                     OLE.error(OLE.ERROR_CANNOT_OPEN_FILE);
358                 }
359             }
360             
361             // Open a temporary storage object
362
tempStorage = createTempStorage();
363             // Copy over contents of file
364
int result = storage.CopyTo(0, null, null, tempStorage.getAddress());
365             storage.Release();
366             if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result);
367
368             // create ole client
369
int[] ppv = new int[1];
370             result = COM.CoCreateInstance(appClsid, 0, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, COM.IIDIUnknown, ppv);
371             if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
372             objIUnknown = new IUnknown(ppv[0]);
373             // get the persistent storage of the ole client
374
ppv = new int[1];
375             result = objIUnknown.QueryInterface(COM.IIDIPersistStorage, ppv);
376             if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
377             IPersistStorage iPersistStorage = new IPersistStorage(ppv[0]);
378             // load the contents of the file into the ole client site
379
result = iPersistStorage.Load(tempStorage.getAddress());
380             iPersistStorage.Release();
381             if (result != COM.S_OK)OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
382         }
383         
384         // Init sinks
385
addObjectReferences();
386         
387         if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state = STATE_RUNNING;
388         
389     } catch (SWTException e) {
390         dispose();
391         disposeCOMInterfaces();
392         throw e;
393     }
394 }
395 protected void addObjectReferences() {
396     //
397
int[] ppvObject = new int[1];
398     if (objIUnknown.QueryInterface(COM.IIDIPersist, ppvObject) == COM.S_OK) {
399         IPersist objIPersist = new IPersist(ppvObject[0]);
400         GUID tempid = new GUID();
401         if (objIPersist.GetClassID(tempid) == COM.S_OK)
402             objClsid = tempid;
403         objIPersist.Release();
404     }
405     
406     //
407
ppvObject = new int[1];
408     int result = objIUnknown.QueryInterface(COM.IIDIViewObject2, ppvObject);
409     if (result != COM.S_OK)
410         OLE.error(OLE.ERROR_INTERFACE_NOT_FOUND, result);
411     objIViewObject2 = new IViewObject2(ppvObject[0]);
412     objIViewObject2.SetAdvise(aspect, 0, iAdviseSink.getAddress());
413
414     //
415
ppvObject = new int[1];
416     result = objIUnknown.QueryInterface(COM.IIDIOleObject, ppvObject);
417     if (result != COM.S_OK)
418         OLE.error(OLE.ERROR_INTERFACE_NOT_FOUND, result);
419     objIOleObject = new IOleObject(ppvObject[0]);
420     objIOleObject.SetClientSite(iOleClientSite.getAddress());
421     int[] pdwConnection = new int[1];
422     objIOleObject.Advise(iAdviseSink.getAddress(), pdwConnection);
423     objIOleObject.SetHostNames("main", "main"); //$NON-NLS-1$ //$NON-NLS-2$
424

425     // Notify the control object that it is embedded in an OLE container
426
COM.OleSetContainedObject(objIUnknown.getAddress(), true);
427
428     // Is OLE object linked or embedded?
429
ppvObject = new int[1];
430     if (objIUnknown.QueryInterface(COM.IIDIOleLink, ppvObject) == COM.S_OK) {
431         IOleLink objIOleLink = new IOleLink(ppvObject[0]);
432         int[] ppmk = new int[1];
433         if (objIOleLink.GetSourceMoniker(ppmk) == COM.S_OK) {
434             IMoniker objIMoniker = new IMoniker(ppmk[0]);
435             objIMoniker.Release();
436             type = COM.OLELINKED;
437             objIOleLink.BindIfRunning();
438         } else {
439             isStatic = true;
440         }
441         objIOleLink.Release();
442     }
443 }
444 protected int AddRef() {
445     refCount++;
446     return refCount;
447 }
448 private int CanInPlaceActivate() {
449     if (aspect == COM.DVASPECT_CONTENT && type == COM.OLEEMBEDDED)
450         return COM.S_OK;
451         
452     return COM.S_FALSE;
453 }
454 private int ContextSensitiveHelp(int fEnterMode) {
455     return COM.S_OK;
456 }
457 protected void createCOMInterfaces() {
458     
459     iUnknown = new COMObject(new int[]{2, 0, 0}){
460         public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
461         public int method1(int[] args) {return AddRef();}
462         public int method2(int[] args) {return Release();}
463     };
464     
465     iOleClientSite = new COMObject(new int[]{2, 0, 0, 0, 3, 1, 0, 1, 0}){
466         public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
467         public int method1(int[] args) {return AddRef();}
468         public int method2(int[] args) {return Release();}
469         public int method3(int[] args) {return SaveObject();}
470         // method4 GetMoniker - not implemented
471
public int method5(int[] args) {return GetContainer(args[0]);}
472         public int method6(int[] args) {return ShowObject();}
473         public int method7(int[] args) {return OnShowWindow(args[0]);}
474         // method8 RequestNewObjectLayout - not implemented
475
};
476     
477     iAdviseSink = new COMObject(new int[]{2, 0, 0, 2, 2, 1, 0, 0}){
478         public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
479         public int method1(int[] args) {return AddRef();}
480         public int method2(int[] args) {return Release();}
481         public int method3(int[] args) {return OnDataChange(args[0], args[1]);}
482         public int method4(int[] args) {return OnViewChange(args[0], args[1]);}
483         //method5 OnRename - not implemented
484
public int method6(int[] args) {OnSave();return 0;}
485         public int method7(int[] args) {return OnClose();}
486     };
487     
488     iOleInPlaceSite = new COMObject(new int[]{2, 0, 0, 1, 1, 0, 0, 0, 5, 1, 1, 0, 0, 0, 1}){
489         public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
490         public int method1(int[] args) {return AddRef();}
491         public int method2(int[] args) {return Release();}
492         public int method3(int[] args) {return GetWindow(args[0]);}
493         public int method4(int[] args) {return ContextSensitiveHelp(args[0]);}
494         public int method5(int[] args) {return CanInPlaceActivate();}
495         public int method6(int[] args) {return OnInPlaceActivate();}
496         public int method7(int[] args) {return OnUIActivate();}
497         public int method8(int[] args) {return GetWindowContext(args[0], args[1], args[2], args[3], args[4]);}
498         public int method9(int[] args) {return Scroll(args[0]);}
499         public int method10(int[] args) {return OnUIDeactivate(args[0]);}
500         public int method11(int[] args) {return OnInPlaceDeactivate();}
501         // method12 DiscardUndoState - not implemented
502
// method13 DeactivateAndUndoChange - not implemented
503
public int method14(int[] args) {return OnPosRectChange(args[0]);}
504     };
505     
506     iOleDocumentSite = new COMObject(new int[]{2, 0, 0, 1}){
507         public int method0(int[] args) {return QueryInterface(args[0], args[1]);}
508         public int method1(int[] args) {return AddRef();}
509         public int method2(int[] args) {return Release();}
510         public int method3(int[] args) {return ActivateMe(args[0]);}
511     };
512 }
513 protected IStorage createTempStorage() {
514     int[] tempStorage = new int[1];
515     int grfMode = COM.STGM_READWRITE | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_DELETEONRELEASE;
516     int result = COM.StgCreateDocfile(null, grfMode, 0, tempStorage);
517     if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_FILE, result);
518     return new IStorage(tempStorage[0]);
519 }
520 /**
521  * Deactivates an active in-place object and discards the object's undo state.
522  */

523 public void deactivateInPlaceClient() {
524     if (objIOleInPlaceObject != null) {
525         objIOleInPlaceObject.InPlaceDeactivate();
526     }
527 }
528 private void deleteTempStorage() {
529     //Destroy this item's contents in the temp root IStorage.
530
if (tempStorage != null){
531         tempStorage.Release();
532     }
533     tempStorage = null;
534 }
535 protected void disposeCOMInterfaces() {
536     if (iUnknown != null)
537         iUnknown.dispose();
538     iUnknown = null;
539     
540     if (iOleClientSite != null)
541     iOleClientSite.dispose();
542     iOleClientSite = null;
543     
544     if (iAdviseSink != null)
545         iAdviseSink.dispose();
546     iAdviseSink = null;
547     
548     if (iOleInPlaceSite != null)
549         iOleInPlaceSite.dispose();
550     iOleInPlaceSite = null;
551     
552     if (iOleDocumentSite != null)
553         iOleDocumentSite.dispose();
554     iOleDocumentSite = null;
555 }
556 /**
557  * Requests that the OLE Document or ActiveX Control perform an action; actions are almost always
558  * changes to the activation state.
559  *
560  * @param verb the operation that is requested. This is one of the OLE.OLEIVERB_ values
561  *
562  * @return an HRESULT value indicating the success of the operation request; OLE.S_OK indicates
563  * success
564  */

565 public int doVerb(int verb) {
566     // Not all OLE clients (for example PowerPoint) can be set into the running state in the constructor.
567
// The fix is to ensure that the client is in the running state before invoking any verb on it.
568
if (state == STATE_NONE) {
569         if (COM.OleRun(objIUnknown.getAddress()) == OLE.S_OK) state = STATE_RUNNING;
570     }
571     if (state == STATE_NONE || isStatic)
572         return COM.E_FAIL;
573     
574     // See PR: 1FV9RZW
575
RECT rect = new RECT();
576     OS.GetClientRect(handle, rect);
577     int result = objIOleObject.DoVerb(verb, null, iOleClientSite.getAddress(), 0, handle, rect);
578
579     if (state != STATE_RUNNING && inInit) {
580         updateStorage();
581         inInit = false;
582     }
583     return result;
584 }
585 /**
586  * Asks the OLE Document or ActiveX Control to execute a command from a standard
587  * list of commands. The OLE Document or ActiveX Control must support the IOleCommandTarget
588  * interface. The OLE Document or ActiveX Control does not have to support all the commands
589  * in the standard list. To check if a command is supported, you can call queryStatus with
590  * the cmdID.
591  *
592  * @param cmdID the ID of a command; these are the OLE.OLECMDID_ values - a small set of common
593  * commands
594  * @param options the optional flags; these are the OLE.OLECMDEXECOPT_ values
595  * @param in the argument for the command
596  * @param out the return value of the command
597  *
598  * @return an HRESULT value; OLE.S_OK is returned if successful
599  *
600  */

601 public int exec(int cmdID, int options, Variant in, Variant out) {
602     
603     if (objIOleCommandTarget == null) {
604         int[] address = new int[1];
605         if (objIUnknown.QueryInterface(COM.IIDIOleCommandTarget, address) != COM.S_OK)
606             return OLE.ERROR_INTERFACE_NOT_FOUND;
607         objIOleCommandTarget = new IOleCommandTarget(address[0]);
608     }
609     
610     int inAddress = 0;
611     if (in != null){
612         inAddress = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, Variant.sizeof);
613         in.getData(inAddress);
614     }
615     int outAddress = 0;
616     if (out != null){
617         outAddress = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, Variant.sizeof);
618         out.getData(outAddress);
619     }
620         
621     int result = objIOleCommandTarget.Exec(null, cmdID, options, inAddress, outAddress);
622     
623     if (inAddress != 0){
624         COM.VariantClear(inAddress);
625         OS.GlobalFree(inAddress);
626     }
627     if (outAddress != 0) {
628         out.setData(outAddress);
629         COM.VariantClear(outAddress);
630         OS.GlobalFree(outAddress);
631     }
632         
633     return result;
634 }
635 IDispatch getAutomationObject() {
636     int[] ppvObject = new int[1];
637     if (objIUnknown.QueryInterface(COM.IIDIDispatch, ppvObject) != COM.S_OK)
638         return null;
639     return new IDispatch(ppvObject[0]);
640 }
641 protected GUID getClassID(String JavaDoc clientName) {
642     // create a GUID struct to hold the result
643
GUID guid = new GUID();
644
645     // create a null terminated array of char
646
char[] buffer = null;
647     if (clientName != null) {
648         int count = clientName.length();
649         buffer = new char[count + 1];
650         clientName.getChars(0, count, buffer, 0);
651     }
652     if (COM.CLSIDFromProgID(buffer, guid) != COM.S_OK){
653         int result = COM.CLSIDFromString(buffer, guid);
654         if (result != COM.S_OK) return null;
655     }
656     return guid;
657 }
658 private int GetContainer(int ppContainer) {
659     /* Simple containers that do not support links to their embedded
660      * objects probably do not need to implement this method. Instead,
661      * they can return E_NOINTERFACE and set ppContainer to NULL.
662      */

663     if (ppContainer != 0)
664         COM.MoveMemory(ppContainer, new int[]{0}, 4);
665     return COM.E_NOINTERFACE;
666 }
667 private SIZE getExtent() {
668     SIZE sizel = new SIZE();
669     // get the current size of the embedded OLENatives object
670
if (objIOleObject != null) {
671         if ( objIViewObject2 != null && !COM.OleIsRunning(objIOleObject.getAddress())) {
672             objIViewObject2.GetExtent(aspect, -1, null, sizel);
673         } else {
674             objIOleObject.GetExtent(aspect, sizel);
675         }
676     }
677     return xFormHimetricToPixels(sizel);
678 }
679 public Rectangle getIndent() {
680     return new Rectangle(indent.left, indent.right, indent.top, indent.bottom);
681 }
682 /**
683  * Returns the program ID of the OLE Document or ActiveX Control.
684  *
685  * @return the program ID of the OLE Document or ActiveX Control
686  */

687 public String JavaDoc getProgramID(){
688     if (appClsid != null){
689         int[] lplpszProgID = new int[1];
690         if (COM.ProgIDFromCLSID(appClsid, lplpszProgID) == COM.S_OK) {
691             int hMem = lplpszProgID[0];
692             int length = OS.GlobalSize(hMem);
693             int ptr = OS.GlobalLock(hMem);
694             char[] buffer = new char[length];
695             COM.MoveMemory(buffer, ptr, length);
696             OS.GlobalUnlock(hMem);
697             OS.GlobalFree(hMem);
698
699             String JavaDoc result = new String JavaDoc(buffer);
700             // remove null terminator
701
int index = result.indexOf("\0");
702             return result.substring(0, index);
703         }
704     }
705     return null;
706 }
707 int ActivateMe(int pViewToActivate) {
708     if (pViewToActivate == 0) {
709         int[] ppvObject = new int[1];
710         if (objIUnknown.QueryInterface(COM.IIDIOleDocument, ppvObject) != COM.S_OK) return COM.E_FAIL;
711         IOleDocument objOleDocument = new IOleDocument(ppvObject[0]);
712         if (objOleDocument.CreateView(iOleInPlaceSite.getAddress(), 0, 0, ppvObject) != COM.S_OK) return COM.E_FAIL;
713         objOleDocument.Release();
714         objDocumentView = new IOleDocumentView(ppvObject[0]);
715     } else {
716         objDocumentView = new IOleDocumentView(pViewToActivate);
717         objDocumentView.AddRef();
718         objDocumentView.SetInPlaceSite(iOleInPlaceSite.getAddress());
719     }
720     objDocumentView.UIActivate(1);//TRUE
721
RECT rect = getRect();
722     objDocumentView.SetRect(rect);
723     objDocumentView.Show(1);//TRUE
724
return COM.S_OK;
725 }
726 protected int GetWindow(int phwnd) {
727     if (phwnd == 0)
728         return COM.E_INVALIDARG;
729     if (frame == null) {
730         COM.MoveMemory(phwnd, new int[] {0}, 4);
731         return COM.E_NOTIMPL;
732     }
733     
734     // Copy the Window's handle into the memory passed in
735
COM.MoveMemory(phwnd, new int[] {frame.handle}, 4);
736     return COM.S_OK;
737 }
738 RECT getRect() {
739     Point location = this.getLocation();
740     Rectangle area = frame.getClientArea();
741     RECT rect = new RECT();
742     rect.left = location.x;
743     rect.top = location.y;
744     rect.right = location.x + area.width - borderWidths.left - borderWidths.right;
745     rect.bottom = location.y + area.height - borderWidths.top - borderWidths.bottom;
746     return rect;
747 }
748 private int GetWindowContext(int ppFrame, int ppDoc, int lprcPosRect, int lprcClipRect, int lpFrameInfo) {
749     if (frame == null || ppFrame == 0)
750         return COM.E_NOTIMPL;
751
752     // fill in frame handle
753
int iOleInPlaceFrame = frame.getIOleInPlaceFrame();
754     COM.MoveMemory(ppFrame, new int[] {iOleInPlaceFrame}, 4);
755     frame.AddRef();
756
757     // null out document handle
758
if (ppDoc != 0) COM.MoveMemory(ppDoc, new int[] {0}, 4);
759
760     // fill in position and clipping info
761
RECT rect = getRect();
762     if (lprcPosRect != 0) OS.MoveMemory(lprcPosRect, rect, RECT.sizeof);
763     if (lprcClipRect != 0) OS.MoveMemory(lprcClipRect, rect, RECT.sizeof);
764
765     // get frame info
766
OLEINPLACEFRAMEINFO frameInfo = new OLEINPLACEFRAMEINFO();
767     frameInfo.cb = OLEINPLACEFRAMEINFO.sizeof;
768     frameInfo.fMDIApp = 0;
769     frameInfo.hwndFrame = frame.handle;
770     Shell shell = getShell();
771     Menu menubar = shell.getMenuBar();
772     if (menubar != null && !menubar.isDisposed()) {
773         int hwnd = shell.handle;
774         int cAccel = OS.SendMessage(hwnd, OS.WM_APP, 0, 0);
775         if (cAccel != 0) {
776             int hAccel = OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0);
777             if (hAccel != 0) {
778                 frameInfo.cAccelEntries = cAccel;
779                 frameInfo.haccel = hAccel;
780             }
781         }
782     }
783     COM.MoveMemory(lpFrameInfo, frameInfo, OLEINPLACEFRAMEINFO.sizeof);
784     
785     return COM.S_OK;
786 }
787 public boolean isDirty() {
788     /*
789      * Note: this method must return true unless it is absolutely clear that the
790      * contents of the Ole Document do not differ from the contents in the file
791      * on the file system.
792      */

793     
794     // Get access to the persistent storage mechanism
795
int[] address = new int[1];
796     if (objIOleObject.QueryInterface(COM.IIDIPersistFile, address) != COM.S_OK)
797         return true;
798     IPersistStorage permStorage = new IPersistStorage(address[0]);
799     // Are the contents of the permanent storage different from the file?
800
int result = permStorage.IsDirty();
801     permStorage.Release();
802     if (result == COM.S_FALSE) return false;
803     return true;
804 }
805 public boolean isFocusControl () {
806     checkWidget ();
807     int focusHwnd = OS.GetFocus();
808     if (objIOleInPlaceObject == null) return (handle == focusHwnd);
809     int[] phwnd = new int[1];
810     objIOleInPlaceObject.GetWindow(phwnd);
811     while (focusHwnd != 0) {
812         if (phwnd[0] == focusHwnd) return true;
813         focusHwnd = OS.GetParent(focusHwnd);
814     }
815     return false;
816 }
817 private int OnClose() {
818     return COM.S_OK;
819 }
820 private int OnDataChange(int pFormatetc, int pStgmed) {
821     return COM.S_OK;
822 }
823 private void onDispose(Event e) {
824     inDispose = true;
825     if (state != STATE_NONE)
826         doVerb(OLE.OLEIVERB_DISCARDUNDOSTATE);
827     deactivateInPlaceClient();
828     releaseObjectInterfaces(); // Note, must release object interfaces before releasing frame
829
deleteTempStorage();
830     
831     // remove listeners
832
removeListener(SWT.Dispose, listener);
833     removeListener(SWT.FocusIn, listener);
834     removeListener(SWT.Paint, listener);
835     removeListener(SWT.Traverse, listener);
836     removeListener(SWT.KeyDown, listener);
837     frame.removeListener(SWT.Resize, listener);
838     frame.removeListener(SWT.Move, listener);
839     
840     frame.Release();
841     frame = null;
842 }
843 void onFocusIn(Event e) {
844     if (inDispose) return;
845     if (state != STATE_UIACTIVE) doVerb(OLE.OLEIVERB_SHOW);
846     if (objIOleInPlaceObject == null) return;
847     if (isFocusControl()) return;
848     int[] phwnd = new int[1];
849     objIOleInPlaceObject.GetWindow(phwnd);
850     if (phwnd[0] == 0) return;
851     OS.SetFocus(phwnd[0]);
852 }
853 void onFocusOut(Event e) {
854 }
855 private int OnInPlaceActivate() {
856     state = STATE_INPLACEACTIVE;
857     frame.setCurrentDocument(this);
858     if (objIOleObject == null)
859         return COM.S_OK;
860     int[] ppvObject = new int[1];
861     if (objIOleObject.QueryInterface(COM.IIDIOleInPlaceObject, ppvObject) == COM.S_OK) {
862         objIOleInPlaceObject = new IOleInPlaceObject(ppvObject[0]);
863     }
864     return COM.S_OK;
865 }
866 private int OnInPlaceDeactivate() {
867     if (objIOleInPlaceObject != null) objIOleInPlaceObject.Release();
868     objIOleInPlaceObject = null;
869     state = STATE_RUNNING;
870     redraw();
871     Shell shell = getShell();
872     if (isFocusControl() || frame.isFocusControl()) {
873         shell.traverse(SWT.TRAVERSE_TAB_NEXT);
874     }
875     return COM.S_OK;
876 }
877 private int OnPosRectChange(int lprcPosRect) {
878     Point size = getSize();
879     setExtent(size.x, size.y);
880     return COM.S_OK;
881 }
882 private void onPaint(Event e) {
883     if (state == STATE_RUNNING || state == STATE_INPLACEACTIVE) {
884         SIZE size = getExtent();
885         Rectangle area = getClientArea();
886         RECT rect = new RECT();
887         if (getProgramID().startsWith("Excel.Sheet")) { //$NON-NLS-1$
888
rect.left = area.x; rect.right = area.x + (area.height * size.cx / size.cy);
889             rect.top = area.y; rect.bottom = area.y + area.height;
890         } else {
891             rect.left = area.x; rect.right = area.x + size.cx;
892             rect.top = area.y; rect.bottom = area.y + size.cy;
893         }
894         
895         int pArea = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, RECT.sizeof);
896         OS.MoveMemory(pArea, rect, RECT.sizeof);
897         COM.OleDraw(objIUnknown.getAddress(), aspect, e.gc.handle, pArea);
898         OS.GlobalFree(pArea);
899     }
900 }
901 private void onResize(Event e) {
902     Rectangle area = frame.getClientArea();
903     setBounds(borderWidths.left,
904               borderWidths.top,
905               area.width - borderWidths.left - borderWidths.right,
906               area.height - borderWidths.top - borderWidths.bottom);
907
908     setObjectRects();
909 }
910 private void OnSave() {
911 }
912 private int OnShowWindow(int fShow) {
913     return COM.S_OK;
914 }
915 private int OnUIActivate() {
916     if (objIOleInPlaceObject == null) return COM.E_FAIL;
917     state = STATE_UIACTIVE;
918     int[] phwnd = new int[1];
919     if (objIOleInPlaceObject.GetWindow(phwnd) == COM.S_OK) {
920         OS.SetWindowPos(phwnd[0], OS.HWND_TOP, 0, 0, 0, 0, OS.SWP_NOSIZE | OS.SWP_NOMOVE);
921     }
922     return COM.S_OK;
923 }
924 private int OnUIDeactivate(int fUndoable) {
925     // currently, we are ignoring the fUndoable flag
926
if (frame == null || frame.isDisposed()) return COM.S_OK;
927     state = STATE_INPLACEACTIVE;
928     frame.SetActiveObject(0,0);
929     redraw();
930     Shell shell = getShell();
931     if (isFocusControl() || frame.isFocusControl()) {
932         shell.traverse(SWT.TRAVERSE_TAB_NEXT);
933     }
934     Menu menubar = shell.getMenuBar();
935     if (menubar == null || menubar.isDisposed())
936         return COM.S_OK;
937         
938     int shellHandle = shell.handle;
939     OS.SetMenu(shellHandle, menubar.handle);
940     return COM.OleSetMenuDescriptor(0, shellHandle, 0, 0, 0);
941 }
942 private void onTraverse(Event event) {
943     switch (event.detail) {
944         case SWT.TRAVERSE_ESCAPE:
945         case SWT.TRAVERSE_RETURN:
946         case SWT.TRAVERSE_TAB_NEXT:
947         case SWT.TRAVERSE_TAB_PREVIOUS:
948         case SWT.TRAVERSE_PAGE_NEXT:
949         case SWT.TRAVERSE_PAGE_PREVIOUS:
950         case SWT.TRAVERSE_MNEMONIC:
951             event.doit = true;
952             break;
953     }
954 }
955 private int OnViewChange(int dwAspect, int lindex) {
956     return COM.S_OK;
957 }
958 protected int QueryInterface(int riid, int ppvObject) {
959
960     if (riid == 0 || ppvObject == 0)
961         return COM.E_NOINTERFACE;
962     GUID guid = new GUID();
963     COM.MoveMemory(guid, riid, GUID.sizeof);
964
965     if (COM.IsEqualGUID(guid, COM.IIDIUnknown)) {
966         COM.MoveMemory(ppvObject, new int[] {iUnknown.getAddress()}, 4);
967         AddRef();
968         return COM.S_OK;
969     }
970     if (COM.IsEqualGUID(guid, COM.IIDIAdviseSink)) {
971         COM.MoveMemory(ppvObject, new int[] {iAdviseSink.getAddress()}, 4);
972         AddRef();
973         return COM.S_OK;
974     }
975     if (COM.IsEqualGUID(guid, COM.IIDIOleClientSite)) {
976         COM.MoveMemory(ppvObject, new int[] {iOleClientSite.getAddress()}, 4);
977         AddRef();
978         return COM.S_OK;
979     }
980     if (COM.IsEqualGUID(guid, COM.IIDIOleInPlaceSite)) {
981         COM.MoveMemory(ppvObject, new int[] {iOleInPlaceSite.getAddress()}, 4);
982         AddRef();
983         return COM.S_OK;
984     }
985     if (COM.IsEqualGUID(guid, COM.IIDIOleDocumentSite )) {
986         String JavaDoc progID = getProgramID();
987         if (!progID.startsWith("PowerPoint")) { //$NON-NLS-1$
988
COM.MoveMemory(ppvObject, new int[] {iOleDocumentSite.getAddress()}, 4);
989             AddRef();
990             return COM.S_OK;
991         }
992     }
993     COM.MoveMemory(ppvObject, new int[] {0}, 4);
994     return COM.E_NOINTERFACE;
995 }
996 /**
997  * Returns the status of the specified command. The status is any bitwise OR'd combination of
998  * SWTOLE.OLECMDF_SUPPORTED, SWTOLE.OLECMDF_ENABLED, SWTOLE.OLECMDF_LATCHED, SWTOLE.OLECMDF_NINCHED.
999  * You can query the status of a command before invoking it with OleClientSite.exec. The
1000 * OLE Document or ActiveX Control must support the IOleCommandTarget to make use of this method.
1001 *
1002 * @param cmd the ID of a command; these are the OLE.OLECMDID_ values - a small set of common
1003 * commands
1004 *
1005 * @return the status of the specified command or 0 if unable to query the OLE Object; these are the
1006 * OLE.OLECMDF_ values
1007 */

1008public int queryStatus(int cmd) {
1009    
1010    if (objIOleCommandTarget == null) {
1011        int[] address = new int[1];
1012        if (objIUnknown.QueryInterface(COM.IIDIOleCommandTarget, address) != COM.S_OK)
1013            return 0;
1014        objIOleCommandTarget = new IOleCommandTarget(address[0]);
1015    }
1016    
1017    OLECMD olecmd = new OLECMD();
1018    olecmd.cmdID = cmd;
1019    
1020    int result = objIOleCommandTarget.QueryStatus(null, 1, olecmd, null);
1021
1022    if (result != COM.S_OK) return 0;
1023
1024    return olecmd.cmdf;
1025}
1026protected int Release() {
1027    refCount--;
1028    
1029    if (refCount == 0) {
1030        disposeCOMInterfaces();
1031    }
1032    return refCount;
1033}
1034protected void releaseObjectInterfaces() {
1035
1036    if (objIOleInPlaceObject!= null)
1037        objIOleInPlaceObject.Release();
1038    objIOleInPlaceObject = null;
1039    
1040    if (objIOleObject != null) {
1041        objIOleObject.Close(COM.OLECLOSE_NOSAVE);
1042        objIOleObject.Release();
1043    }
1044    objIOleObject = null;
1045    
1046    if (objDocumentView != null){
1047        objDocumentView.Release();
1048    }
1049    objDocumentView = null;
1050    
1051    if (objIViewObject2 != null) {
1052        objIViewObject2.SetAdvise(aspect, 0, 0);
1053        objIViewObject2.Release();
1054    }
1055    objIViewObject2 = null;
1056    
1057    if (objIOleCommandTarget != null)
1058        objIOleCommandTarget.Release();
1059    objIOleCommandTarget = null;
1060        
1061    if (objIUnknown != null){
1062        objIUnknown.Release();
1063    }
1064    objIUnknown = null;
1065    
1066    COM.CoFreeUnusedLibraries();
1067}
1068public boolean save(File JavaDoc file, boolean includeOleInfo) {
1069    if (includeOleInfo)
1070        return saveToStorageFile(file);
1071    return saveToTraditionalFile(file);
1072}
1073private boolean saveFromContents(int address, File JavaDoc file) {
1074
1075    boolean success = false;
1076    
1077    IStream tempContents = new IStream(address);
1078    tempContents.AddRef();
1079
1080    try {
1081        FileOutputStream JavaDoc writer = new FileOutputStream JavaDoc(file);
1082        
1083        int increment = 1024 * 4;
1084        int pv = COM.CoTaskMemAlloc(increment);
1085        int[] pcbWritten = new int[1];
1086        while (tempContents.Read(pv, increment, pcbWritten) == COM.S_OK && pcbWritten[0] > 0) {
1087            byte[] buffer = new byte[ pcbWritten[0]];
1088            OS.MoveMemory(buffer, pv, pcbWritten[0]);
1089            writer.write(buffer); // Note: if file does not exist, this will create the file the
1090
// first time it is called
1091
success = true;
1092        }
1093        COM.CoTaskMemFree(pv);
1094            
1095        writer.close();
1096        
1097    } catch (IOException JavaDoc err) {
1098    }
1099
1100    tempContents.Release();
1101
1102    return success;
1103}
1104private boolean saveFromOle10Native(int address, File JavaDoc file) {
1105
1106    boolean success = false;
1107    
1108    IStream tempContents = new IStream(address);
1109    tempContents.AddRef();
1110    
1111    // The "\1Ole10Native" stream contains a DWORD header whose value is the length
1112
// of the native data that follows.
1113
int pv = COM.CoTaskMemAlloc(4);
1114    int[] size = new int[1];
1115    int rc = tempContents.Read(pv, 4, null);
1116    OS.MoveMemory(size, pv, 4);
1117    COM.CoTaskMemFree(pv);
1118    if (rc == COM.S_OK && size[0] > 0) {
1119        
1120        // Read the data
1121
byte[] buffer = new byte[size[0]];
1122        pv = COM.CoTaskMemAlloc(size[0]);
1123        rc = tempContents.Read(pv, size[0], null);
1124        OS.MoveMemory(buffer, pv, size[0]);
1125        COM.CoTaskMemFree(pv);
1126
1127        // open the file and write data into it
1128
try {
1129            FileOutputStream JavaDoc writer = new FileOutputStream JavaDoc(file);
1130            writer.write(buffer); // Note: if file does not exist, this will create the file
1131
writer.close();
1132
1133            success = true;
1134        } catch (IOException JavaDoc err) {
1135        }
1136    }
1137    tempContents.Release();
1138
1139    return success;
1140}
1141private int SaveObject() {
1142
1143    updateStorage();
1144        
1145    return COM.S_OK;
1146}
1147/**
1148 * Saves the document to the specified file and includes OLE specific information. This method
1149 * must <b>only</b> be used for files that have an OLE Storage format. For example, a word file
1150 * edited with Word.Document should be saved using this method because there is formating information
1151 * that should be stored in the OLE specific Storage format.
1152 *
1153 * @param file the file to which the changes are to be saved
1154 *
1155 * @return true if the save was successful
1156 */

1157private boolean saveToStorageFile(File JavaDoc file) {
1158    // The file will be saved using the formating of the current application - this
1159
// may not be the format of the application that was originally used to create the file
1160
// e.g. if an Excel file is opened in Word, the Word application will save the file in the
1161
// Word format
1162
// Note: if the file already exists, some applications will not overwrite the file
1163
// In these cases, you should delete the file first (probably save the contents of the file in case the
1164
// save fails)
1165
if (file == null || file.isDirectory()) return false;
1166    if (!updateStorage()) return false;
1167    
1168    // get access to the persistent storage mechanism
1169
int[] address = new int[1];
1170    if (objIOleObject.QueryInterface(COM.IIDIPersistStorage, address) != COM.S_OK) return false;
1171    IPersistStorage permStorage = new IPersistStorage(address[0]);
1172    try {
1173        address = new int[1];
1174        char[] path = (file.getAbsolutePath()+"\0").toCharArray();
1175        int mode = COM.STGM_TRANSACTED | COM.STGM_READWRITE | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_CREATE;
1176        int result = COM.StgCreateDocfile(path, mode, 0, address); //Does an AddRef if successful
1177
if (result != COM.S_OK) return false;
1178        IStorage storage = new IStorage(address[0]);
1179        try {
1180            if (COM.OleSave(permStorage.getAddress(), storage.getAddress(), false) == COM.S_OK) {
1181                if (storage.Commit(COM.STGC_DEFAULT) == COM.S_OK) {
1182                    return true;
1183                }
1184            }
1185        } finally {
1186            storage.Release();
1187        }
1188    } finally {
1189        permStorage.Release();
1190    }
1191    return false;
1192}
1193/**
1194 * Saves the document to the specified file. This method must be used for
1195 * files that do not have an OLE Storage format. For example, a bitmap file edited with MSPaint
1196 * should be saved using this method because bitmap is a standard format that does not include any
1197 * OLE specific data.
1198 *
1199 * @param file the file to which the changes are to be saved
1200 *
1201 * @return true if the save was successful
1202 */

1203private boolean saveToTraditionalFile(File JavaDoc file) {
1204    // Note: if the file already exists, some applications will not overwrite the file
1205
// In these cases, you should delete the file first (probably save the contents of the file in case the
1206
// save fails)
1207
if (file == null || file.isDirectory())
1208        return false;
1209    if (!updateStorage())
1210        return false;
1211    
1212    int[] address = new int[1];
1213    // Look for a CONTENTS stream
1214
if (tempStorage.OpenStream("CONTENTS", 0, COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE, 0, address) == COM.S_OK) //$NON-NLS-1$
1215
return saveFromContents(address[0], file);
1216        
1217    // Look for Ole 1.0 object stream
1218
if (tempStorage.OpenStream("\1Ole10Native", 0, COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE, 0, address) == COM.S_OK) //$NON-NLS-1$
1219
return saveFromOle10Native(address[0], file);
1220        
1221    return false;
1222}
1223private int Scroll(int scrollExtant) {
1224    return COM.S_OK;
1225}
1226void setBorderSpace(RECT newBorderwidth) {
1227    borderWidths = newBorderwidth;
1228    // readjust size and location of client site
1229
Rectangle area = frame.getClientArea();
1230    setBounds(borderWidths.left, borderWidths.top,
1231                area.width - borderWidths.left - borderWidths.right,
1232                area.height - borderWidths.top - borderWidths.bottom);
1233    setObjectRects();
1234}
1235private void setExtent(int width, int height){
1236    // Resize the width and height of the embedded/linked OLENatives object
1237
// to the specified values.
1238

1239    if (objIOleObject == null || isStatic || inUpdate) return;
1240    SIZE currentExtent = getExtent();
1241    if (width == currentExtent.cx && height == currentExtent.cy) return;
1242
1243    SIZE newExtent = new SIZE();
1244    newExtent.cx = width; newExtent.cy = height;
1245    newExtent = xFormPixelsToHimetric(newExtent);
1246    
1247   // Get the server running first, then do a SetExtent, then show it
1248
boolean alreadyRunning = COM.OleIsRunning(objIOleObject.getAddress());
1249    if (!alreadyRunning)
1250        COM.OleRun(objIOleObject.getAddress());
1251    
1252    if (objIOleObject.SetExtent(aspect, newExtent) == COM.S_OK){
1253        inUpdate = true;
1254        objIOleObject.Update();
1255        inUpdate = false;
1256        if (!alreadyRunning)
1257            // Close server if it wasn't already running upon entering this method.
1258
objIOleObject.Close(COM.OLECLOSE_SAVEIFDIRTY);
1259    }
1260}
1261public void setIndent(Rectangle newIndent) {
1262    indent = new RECT();
1263    indent.left = newIndent.x;
1264    indent.right = newIndent.width;
1265    indent.top = newIndent.y;
1266    indent.bottom = newIndent.height;
1267}
1268private void setObjectRects() {
1269    if (objIOleInPlaceObject == null) return;
1270    // size the object to fill the available space
1271
// leave a border
1272
RECT rect = getRect();
1273    objIOleInPlaceObject.SetObjectRects(rect, rect);
1274}
1275
1276private int ShowObject() {
1277    /* Tells the container to position the object so it is visible to
1278     * the user. This method ensures that the container itself is
1279     * visible and not minimized.
1280     */

1281    return COM.S_OK;
1282}
1283/**
1284 * Displays a dialog with the property information for this OLE Object. The OLE Document or
1285 * ActiveX Control must support the ISpecifyPropertyPages interface.
1286 *
1287 * @param title the name that will appear in the titlebar of the dialog
1288 */

1289public void showProperties(String JavaDoc title) {
1290
1291    // Get the Property Page information from the OLE Object
1292
int[] ppvObject = new int[1];
1293    if (objIUnknown.QueryInterface(COM.IIDISpecifyPropertyPages, ppvObject) != COM.S_OK) return;
1294    ISpecifyPropertyPages objISPP = new ISpecifyPropertyPages(ppvObject[0]);
1295    CAUUID caGUID = new CAUUID();
1296    int result = objISPP.GetPages(caGUID);
1297    objISPP.Release();
1298    if (result != COM.S_OK) return;
1299
1300    // create a frame in which to display the pages
1301
char[] chTitle = null;
1302    if (title != null) {
1303        chTitle = new char[title.length()];
1304        title.getChars(0, title.length(), chTitle, 0);
1305    }
1306    result = COM.OleCreatePropertyFrame(frame.handle, 10, 10, chTitle, 1, new int[] {objIUnknown.getAddress()}, caGUID.cElems, caGUID.pElems, COM.LOCALE_USER_DEFAULT, 0, 0);
1307
1308    // free the property page information
1309
COM.CoTaskMemFree(caGUID.pElems);
1310}
1311private boolean updateStorage() {
1312
1313    if (tempStorage == null) return false;
1314
1315    int[] ppv = new int[1];
1316    if (objIUnknown.QueryInterface(COM.IIDIPersistStorage, ppv) != COM.S_OK) return false;
1317    IPersistStorage iPersistStorage = new IPersistStorage(ppv[0]);
1318
1319    int result = COM.OleSave(iPersistStorage.getAddress(), tempStorage.getAddress(), true);
1320
1321    if (result != COM.S_OK){
1322        // OleSave will fail for static objects, so do what OleSave does.
1323
COM.WriteClassStg(tempStorage.getAddress(), objClsid);
1324        result = iPersistStorage.Save(tempStorage.getAddress(), true);
1325    }
1326    
1327    tempStorage.Commit(COM.STGC_DEFAULT);
1328    result = iPersistStorage.SaveCompleted(0);
1329    iPersistStorage.Release();
1330        
1331    return true;
1332}
1333private SIZE xFormHimetricToPixels(SIZE aSize) {
1334    // Return a new Size which is the pixel transformation of a
1335
// size in HIMETRIC units.
1336

1337    int hDC = OS.GetDC(0);
1338    int xppi = OS.GetDeviceCaps(hDC, 88); // logical pixels/inch in x
1339
int yppi = OS.GetDeviceCaps(hDC, 90); // logical pixels/inch in y
1340
OS.ReleaseDC(0, hDC);
1341    int cx = Compatibility.round(aSize.cx * xppi, 2540); // 2540 HIMETRIC units per inch
1342
int cy = Compatibility.round(aSize.cy * yppi, 2540);
1343    SIZE size = new SIZE();
1344    size.cx = cx;
1345    size.cy = cy;
1346    return size;
1347}
1348private SIZE xFormPixelsToHimetric(SIZE aSize) {
1349    // Return a new size which is the HIMETRIC transformation of a
1350
// size in pixel units.
1351

1352    int hDC = OS.GetDC(0);
1353    int xppi = OS.GetDeviceCaps(hDC, 88); // logical pixels/inch in x
1354
int yppi = OS.GetDeviceCaps(hDC, 90); // logical pixels/inch in y
1355
OS.ReleaseDC(0, hDC);
1356    int cx = Compatibility.round(aSize.cx * 2540, xppi); // 2540 HIMETRIC units per inch
1357
int cy = Compatibility.round(aSize.cy * 2540, yppi);
1358    SIZE size = new SIZE();
1359    size.cx = cx;
1360    size.cy = cy;
1361    return size;
1362}
1363}
1364
Popular Tags