Mercurial > projects > dwt-win
annotate dwt/ole/win32/OleClientSite.d @ 341:f403c83322c3 default tip
fix: thx torhu
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 08 Nov 2009 20:58:32 +0100 |
parents | 8a2a24a30ea9 |
children |
rev | line source |
---|---|
97 | 1 /******************************************************************************* |
246 | 2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
97 | 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 | |
98 | 10 * Port to the D programming language: |
11 * Frank Benoit <benoit@tionex.de> | |
97 | 12 *******************************************************************************/ |
13 module dwt.ole.win32.OleClientSite; | |
14 | |
15 import dwt.dwthelper.File; | |
16 import dwt.dwthelper.FileInputStream; | |
17 import dwt.dwthelper.FileOutputStream; | |
18 import dwt.dwthelper.utils; | |
19 | |
20 import dwt.DWT; | |
21 import dwt.DWTException; | |
22 import dwt.graphics.Point; | |
23 import dwt.graphics.Rectangle; | |
24 import dwt.internal.Compatibility; | |
25 // import dwt.internal.ole.win32.CAUUID; | |
26 // import dwt.internal.ole.win32.COM; | |
27 // import dwt.internal.ole.win32.COMObject; | |
28 // import dwt.internal.ole.win32.GUID; | |
29 // import dwt.internal.ole.win32.IDispatch; | |
30 // import dwt.internal.ole.win32.IMoniker; | |
31 // import dwt.internal.ole.win32.IOleCommandTarget; | |
32 // import dwt.internal.ole.win32.IOleDocument; | |
33 // import dwt.internal.ole.win32.IOleDocumentView; | |
34 // import dwt.internal.ole.win32.IOleInPlaceObject; | |
35 // import dwt.internal.ole.win32.IOleLink; | |
36 // import dwt.internal.ole.win32.IOleObject; | |
37 // import dwt.internal.ole.win32.IPersist; | |
38 // import dwt.internal.ole.win32.IPersistStorage; | |
39 // import dwt.internal.ole.win32.ISpecifyPropertyPages; | |
40 // import dwt.internal.ole.win32.IStorage; | |
41 // import dwt.internal.ole.win32.IStream; | |
42 // import dwt.internal.ole.win32.IUnknown; | |
43 // import dwt.internal.ole.win32.IViewObject2; | |
44 // import dwt.internal.ole.win32.OLECMD; | |
45 // import dwt.internal.ole.win32.OLEINPLACEFRAMEINFO; | |
46 import dwt.internal.win32.OS; | |
98 | 47 import dwt.internal.ole.win32.extras; |
48 import dwt.internal.ole.win32.OAIDL; | |
49 import dwt.internal.ole.win32.OLEIDL; | |
50 import dwt.internal.ole.win32.OBJIDL; | |
51 import dwt.internal.ole.win32.DOCOBJ; | |
52 import dwt.internal.ole.win32.COM; | |
53 import dwt.internal.ole.win32.ifs; | |
97 | 54 |
55 import dwt.widgets.Composite; | |
56 import dwt.widgets.Event; | |
57 import dwt.widgets.Listener; | |
58 import dwt.widgets.Menu; | |
59 import dwt.widgets.Shell; | |
60 | |
98 | 61 import dwt.ole.win32.OleFrame; |
62 import dwt.ole.win32.Variant; | |
63 import dwt.ole.win32.OLE; | |
64 | |
97 | 65 |
66 /** | |
67 * OleClientSite provides a site to manage an embedded OLE Document within a container. | |
68 * | |
69 * <p>The OleClientSite provides the following capabilities: | |
70 * <ul> | |
71 * <li>creates the in-place editor for a blank document or opening an existing OLE Document | |
72 * <li>lays the editor out | |
73 * <li>provides a mechanism for activating and deactivating the Document | |
74 * <li>provides a mechanism for saving changes made to the document | |
75 * </ul> | |
76 * | |
77 * <p>This object implements the OLE Interfaces IUnknown, IOleClientSite, IAdviseSink, | |
78 * IOleInPlaceSite | |
79 * | |
80 * <p>Note that although this class is a subclass of <code>Composite</code>, | |
81 * it does not make sense to add <code>Control</code> children to it, | |
82 * or set a layout on it. | |
83 * </p><p> | |
84 * <dl> | |
85 * <dt><b>Styles</b> <dd>BORDER | |
86 * <dt><b>Events</b> <dd>Dispose, Move, Resize | |
87 * </dl> | |
88 * | |
246 | 89 * @see <a href="http://www.eclipse.org/swt/snippets/#ole">OLE and ActiveX snippets</a> |
90 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Examples: OLEExample, OleWebBrowser</a> | |
97 | 91 */ |
92 public class OleClientSite : Composite { | |
93 | |
94 // Interfaces for this Ole Client Container | |
98 | 95 private _IUnknownImpl iUnknown; |
96 private _IOleClientSiteImpl iOleClientSite; | |
97 private _IAdviseSinkImpl iAdviseSink; | |
98 private _IOleInPlaceSiteImpl iOleInPlaceSite; | |
99 private _IOleDocumentSiteImpl iOleDocumentSite; | |
97 | 100 |
98 | 101 protected GUID* appClsid; |
102 private GUID* objClsid; | |
97 | 103 private int refCount; |
104 | |
105 // References to the associated Frame. | |
98 | 106 package OleFrame frame; |
97 | 107 |
108 // Access to the embedded/linked Ole Object | |
98 | 109 protected IUnknown objIUnknown; |
110 protected IOleObject objIOleObject; | |
111 protected IViewObject2 objIViewObject2; | |
97 | 112 protected IOleInPlaceObject objIOleInPlaceObject; |
98 | 113 protected IOleCommandTarget objIOleCommandTarget; |
114 protected IOleDocumentView objDocumentView; | |
97 | 115 |
116 // Related storage information | |
117 protected IStorage tempStorage; // IStorage interface of the receiver | |
118 | |
119 // Internal state and style information | |
120 private int aspect; // the display aspect of the embedded object, e.g., DvaspectContent or DvaspectIcon | |
121 private int type; // Indicates the type of client that can be supported inside this container | |
122 private bool isStatic; // Indicates item's display is static, i.e., a bitmap, metafile, etc. | |
123 | |
98 | 124 private RECT borderWidths; |
125 private RECT indent; | |
97 | 126 private bool inUpdate = false; |
127 private bool inInit = true; | |
128 private bool inDispose = false; | |
129 | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
130 private static const String WORDPROGID = "Word.Document"; //$NON-NLS-1$ |
97 | 131 |
132 private Listener listener; | |
133 | |
98 | 134 enum{ |
135 STATE_NONE = 0, | |
136 STATE_RUNNING = 1, | |
137 STATE_INPLACEACTIVE = 2, | |
138 STATE_UIACTIVE = 3, | |
139 STATE_ACTIVE = 4, | |
140 } | |
97 | 141 int state = STATE_NONE; |
142 | |
98 | 143 protected this(Composite parent, int style) { |
97 | 144 /* |
145 * NOTE: this constructor should never be used by itself because it does | |
146 * not create an Ole Object | |
147 */ | |
148 super(parent, style); | |
149 | |
150 createCOMInterfaces(); | |
151 | |
152 // install the Ole Frame for this Client Site | |
153 while (parent !is null) { | |
284
bb89fd34ec82
Fix for OLE functionality. Thanks to Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
154 if ( auto aframe = cast(OleFrame)parent){ |
bb89fd34ec82
Fix for OLE functionality. Thanks to Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
155 frame = aframe; |
97 | 156 break; |
157 } | |
158 parent = parent.getParent(); | |
159 } | |
98 | 160 if (frame is null) OLE.error (__FILE__, __LINE__, DWT.ERROR_INVALID_ARGUMENT); |
97 | 161 frame.AddRef(); |
162 | |
163 aspect = COM.DVASPECT_CONTENT; | |
164 type = COM.OLEEMBEDDED; | |
165 isStatic = false; | |
166 | |
98 | 167 listener = new class() Listener { |
97 | 168 public void handleEvent(Event e) { |
169 switch (e.type) { | |
170 case DWT.Resize : | |
171 case DWT.Move : onResize(e); break; | |
172 case DWT.Dispose : onDispose(e); break; | |
173 case DWT.FocusIn: onFocusIn(e); break; | |
174 case DWT.FocusOut: onFocusOut(e); break; | |
175 case DWT.Paint: onPaint(e); break; | |
176 case DWT.Traverse: onTraverse(e); break; | |
177 case DWT.KeyDown: /* required for traversal */ break; | |
178 default : | |
98 | 179 OLE.error (__FILE__, __LINE__, DWT.ERROR_NOT_IMPLEMENTED); |
97 | 180 } |
181 } | |
182 }; | |
183 | |
184 frame.addListener(DWT.Resize, listener); | |
185 frame.addListener(DWT.Move, listener); | |
186 addListener(DWT.Dispose, listener); | |
187 addListener(DWT.FocusIn, listener); | |
188 addListener(DWT.FocusOut, listener); | |
189 addListener(DWT.Paint, listener); | |
190 addListener(DWT.Traverse, listener); | |
191 addListener(DWT.KeyDown, listener); | |
192 } | |
193 /** | |
194 * Create an OleClientSite child widget using the OLE Document type associated with the | |
195 * specified file. The OLE Document type is determined either through header information in the file | |
196 * or through a Registry entry for the file extension. Use style bits to select a particular look | |
197 * or set of properties. | |
198 * | |
199 * @param parent a composite widget; must be an OleFrame | |
200 * @param style the bitwise OR'ing of widget styles | |
201 * @param file the file that is to be opened in this OLE Document | |
202 * | |
203 * @exception IllegalArgumentException | |
204 * <ul><li>ERROR_NULL_ARGUMENT when the parent is null | |
205 * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame</ul> | |
206 * @exception DWTException | |
207 * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread | |
208 * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object | |
209 * <li>ERROR_CANNOT_OPEN_FILE when failed to open file | |
210 * <li>ERROR_INTERFACE_NOT_FOUND when unable to create callbacks for OLE Interfaces | |
211 * <li>ERROR_INVALID_CLASSID | |
212 * </ul> | |
213 */ | |
98 | 214 public this(Composite parent, int style, File file) { |
97 | 215 this(parent, style); |
216 try { | |
217 | |
218 if (file is null || file.isDirectory() || !file.exists()) | |
98 | 219 OLE.error (__FILE__, __LINE__, OLE.ERROR_INVALID_ARGUMENT); |
97 | 220 |
221 // Is there an associated CLSID? | |
222 appClsid = new GUID(); | |
98 | 223 TCHAR* fileName = StrToTCHARz( 0, file.getAbsolutePath() ); |
97 | 224 int result = COM.GetClassFile(fileName, appClsid); |
225 if (result !is COM.S_OK) | |
98 | 226 OLE.error (__FILE__, __LINE__, OLE.ERROR_INVALID_CLASSID, result); |
97 | 227 // associated CLSID may not be installed on this machine |
228 if (getProgramID() is null) | |
98 | 229 OLE.error (__FILE__, __LINE__, OLE.ERROR_INVALID_CLASSID, result); |
97 | 230 |
231 // Open a temporary storage object | |
232 tempStorage = createTempStorage(); | |
233 | |
234 // Create ole object with storage object | |
98 | 235 result = COM.OleCreateFromFile(appClsid, fileName, &COM.IIDIUnknown, COM.OLERENDER_DRAW, null, null, tempStorage, cast(void**)&objIUnknown); |
97 | 236 if (result !is COM.S_OK) |
98 | 237 OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); |
97 | 238 |
239 // Init sinks | |
240 addObjectReferences(); | |
241 | |
98 | 242 if (COM.OleRun(objIUnknown) is OLE.S_OK) state = STATE_RUNNING; |
97 | 243 } catch (DWTException e) { |
244 dispose(); | |
245 disposeCOMInterfaces(); | |
246 throw e; | |
247 } | |
248 } | |
249 /** | |
250 * Create an OleClientSite child widget to edit a blank document using the specified OLE Document | |
251 * application. Use style bits to select a particular look or set of properties. | |
252 * | |
253 * @param parent a composite widget; must be an OleFrame | |
254 * @param style the bitwise OR'ing of widget styles | |
255 * @param progId the unique program identifier of am OLE Document application; | |
256 * the value of the ProgID key or the value of the VersionIndependentProgID key specified | |
257 * in the registry for the desired OLE Document (for example, the VersionIndependentProgID | |
258 * for Word is Word.Document) | |
259 * | |
260 * @exception IllegalArgumentException | |
261 *<ul> | |
262 * <li>ERROR_NULL_ARGUMENT when the parent is null | |
263 * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame | |
264 *</ul> | |
265 * @exception DWTException | |
266 * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread | |
267 * <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID | |
268 * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object | |
269 * </ul> | |
270 */ | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
271 public this(Composite parent, int style, String progId) { |
97 | 272 this(parent, style); |
273 try { | |
274 appClsid = getClassID(progId); | |
275 if (appClsid is null) | |
98 | 276 OLE.error (__FILE__, __LINE__, OLE.ERROR_INVALID_CLASSID); |
97 | 277 |
278 // Open a temporary storage object | |
279 tempStorage = createTempStorage(); | |
280 | |
281 // Create ole object with storage object | |
98 | 282 HRESULT result = COM.OleCreate(appClsid, &COM.IIDIUnknown, COM.OLERENDER_DRAW, null, null, tempStorage, cast(void**)&objIUnknown); |
97 | 283 if (result !is COM.S_OK) |
98 | 284 OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); |
97 | 285 |
286 // Init sinks | |
287 addObjectReferences(); | |
288 | |
98 | 289 if (COM.OleRun(objIUnknown) is OLE.S_OK) state = STATE_RUNNING; |
97 | 290 |
291 } catch (DWTException e) { | |
292 dispose(); | |
293 disposeCOMInterfaces(); | |
294 throw e; | |
295 } | |
296 } | |
297 /** | |
298 * Create an OleClientSite child widget to edit the specified file using the specified OLE Document | |
299 * application. Use style bits to select a particular look or set of properties. | |
300 * <p> | |
301 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
302 * API for <code>OleClientSite</code>. It is marked public only so that it | |
303 * can be shared within the packages provided by DWT. It is not | |
304 * available on all platforms, and should never be called from | |
305 * application code. | |
306 * </p> | |
307 * @param parent a composite widget; must be an OleFrame | |
308 * @param style the bitwise OR'ing of widget styles | |
309 * @param progId the unique program identifier of am OLE Document application; | |
310 * the value of the ProgID key or the value of the VersionIndependentProgID key specified | |
311 * in the registry for the desired OLE Document (for example, the VersionIndependentProgID | |
312 * for Word is Word.Document) | |
313 * @param file the file that is to be opened in this OLE Document | |
314 * | |
315 * @exception IllegalArgumentException | |
316 * <ul><li>ERROR_NULL_ARGUMENT when the parent is null | |
317 * <li>ERROR_INVALID_ARGUMENT when the parent is not an OleFrame</ul> | |
318 * @exception DWTException | |
319 * <ul><li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread | |
320 * <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID | |
321 * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object | |
322 * <li>ERROR_CANNOT_OPEN_FILE when failed to open file | |
323 * </ul> | |
324 */ | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
325 public this(Composite parent, int style, String progId, File file) { |
97 | 326 this(parent, style); |
327 try { | |
98 | 328 if (file is null || file.isDirectory() || !file.exists()) OLE.error (__FILE__, __LINE__, OLE.ERROR_INVALID_ARGUMENT); |
97 | 329 appClsid = getClassID(progId); |
98 | 330 if (appClsid is null) OLE.error (__FILE__, __LINE__, OLE.ERROR_INVALID_CLASSID); |
97 | 331 |
332 // Are we opening this file with the preferred OLE object? | |
98 | 333 wchar* fileName = StrToWCHARz(file.getAbsolutePath()); |
334 GUID* fileClsid = new GUID(); | |
97 | 335 COM.GetClassFile(fileName, fileClsid); |
336 | |
337 if (COM.IsEqualGUID(appClsid, fileClsid)){ | |
338 // Using the same application that created file, therefore, use default mechanism. | |
339 tempStorage = createTempStorage(); | |
340 // Create ole object with storage object | |
98 | 341 HRESULT result = COM.OleCreateFromFile(appClsid, fileName, &COM.IIDIUnknown, COM.OLERENDER_DRAW, null, null, tempStorage, cast(void**)&objIUnknown); |
342 if (result !is COM.S_OK) OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); | |
97 | 343 } else { |
344 // Not using the same application that created file, therefore, copy from original file to a new storage file | |
345 IStorage storage = null; | |
346 if (COM.StgIsStorageFile(fileName) is COM.S_OK) { | |
347 int mode = COM.STGM_READ | COM.STGM_TRANSACTED | COM.STGM_SHARE_EXCLUSIVE; | |
98 | 348 HRESULT result = COM.StgOpenStorage(fileName, null, mode, null, 0, &storage); //Does an AddRef if successful |
349 if (result !is COM.S_OK) OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_OPEN_FILE, result); | |
97 | 350 } else { |
351 // Original file is not a Storage file so copy contents to a stream in a new storage file | |
352 int mode = COM.STGM_READWRITE | COM.STGM_DIRECT | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_CREATE; | |
98 | 353 HRESULT result = COM.StgCreateDocfile(null, mode | COM.STGM_DELETEONRELEASE, 0, &storage); // Increments ref count if successful |
354 if (result !is COM.S_OK) OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_OPEN_FILE, result); | |
97 | 355 // Create a stream on the storage object. |
356 // Word does not follow the standard and does not use "CONTENTS" as the name of | |
357 // its primary stream | |
98 | 358 wchar* streamName = StrToWCHARz("CONTENTS"); //$NON-NLS-1$ |
359 GUID* wordGUID = getClassID(WORDPROGID); | |
97 | 360 if (wordGUID !is null && COM.IsEqualGUID(appClsid, wordGUID)) streamName = "WordDocument"; //$NON-NLS-1$ |
98 | 361 IStream stream; |
362 result = storage.CreateStream(streamName, mode, 0, 0, &stream); // Increments ref count if successful | |
97 | 363 if (result !is COM.S_OK) { |
364 storage.Release(); | |
98 | 365 OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_OPEN_FILE, result); |
97 | 366 } |
367 try { | |
368 // Copy over data in file to named stream | |
369 FileInputStream fileInput = new FileInputStream(file); | |
370 int increment = 1024*4; | |
371 byte[] buffer = new byte[increment]; | |
372 int count = 0; | |
373 while((count = fileInput.read(buffer)) > 0){ | |
98 | 374 auto pv = COM.CoTaskMemAlloc(count); |
375 OS.MoveMemory(pv, buffer.ptr, count); | |
97 | 376 result = stream.Write(pv, count, null) ; |
377 COM.CoTaskMemFree(pv); | |
378 if (result !is COM.S_OK) { | |
379 fileInput.close(); | |
380 stream.Release(); | |
381 storage.Release(); | |
98 | 382 OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_OPEN_FILE, result); |
97 | 383 } |
384 } | |
385 fileInput.close(); | |
386 stream.Commit(COM.STGC_DEFAULT); | |
387 stream.Release(); | |
388 } catch (IOException err) { | |
389 stream.Release(); | |
390 storage.Release(); | |
98 | 391 OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_OPEN_FILE); |
97 | 392 } |
393 } | |
394 | |
395 // Open a temporary storage object | |
396 tempStorage = createTempStorage(); | |
397 // Copy over contents of file | |
98 | 398 HRESULT result = storage.CopyTo(0, null, null, tempStorage); |
97 | 399 storage.Release(); |
98 | 400 if (result !is COM.S_OK) OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_OPEN_FILE, result); |
97 | 401 |
402 // create ole client | |
98 | 403 result = COM.CoCreateInstance(appClsid, null, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, &COM.IIDIUnknown, cast(void**)&objIUnknown); |
404 if (result !is COM.S_OK) OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); | |
97 | 405 // get the persistent storage of the ole client |
98 | 406 IPersistStorage iPersistStorage; |
407 result = objIUnknown.QueryInterface(&COM.IIDIPersistStorage, cast(void**)&iPersistStorage); | |
408 if (result !is COM.S_OK) OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); | |
97 | 409 // load the contents of the file into the ole client site |
98 | 410 result = iPersistStorage.Load(tempStorage); |
97 | 411 iPersistStorage.Release(); |
98 | 412 if (result !is COM.S_OK)OLE.error (__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); |
97 | 413 } |
414 | |
415 // Init sinks | |
416 addObjectReferences(); | |
417 | |
98 | 418 if (COM.OleRun(objIUnknown) is OLE.S_OK) state = STATE_RUNNING; |
97 | 419 |
420 } catch (DWTException e) { | |
421 dispose(); | |
422 disposeCOMInterfaces(); | |
423 throw e; | |
424 } | |
425 } | |
426 protected void addObjectReferences() { | |
427 // | |
98 | 428 IPersist objIPersist; |
429 if (objIUnknown.QueryInterface(&COM.IIDIPersist, cast(void**)&objIPersist) is COM.S_OK) { | |
430 GUID* tempid = new GUID(); | |
97 | 431 if (objIPersist.GetClassID(tempid) is COM.S_OK) |
432 objClsid = tempid; | |
433 objIPersist.Release(); | |
434 } | |
435 | |
436 // | |
98 | 437 HRESULT result = objIUnknown.QueryInterface(&COM.IIDIViewObject2, cast(void**)&objIViewObject2); |
97 | 438 if (result !is COM.S_OK) |
98 | 439 OLE.error (__FILE__, __LINE__, OLE.ERROR_INTERFACE_NOT_FOUND, result); |
440 objIViewObject2.SetAdvise(aspect, 0, iAdviseSink); | |
97 | 441 |
442 // | |
98 | 443 result = objIUnknown.QueryInterface(&COM.IIDIOleObject, cast(void**)&objIOleObject); |
97 | 444 if (result !is COM.S_OK) |
98 | 445 OLE.error (__FILE__, __LINE__, OLE.ERROR_INTERFACE_NOT_FOUND, result); |
446 objIOleObject.SetClientSite(iOleClientSite); | |
447 uint pdwConnection; | |
448 objIOleObject.Advise(iAdviseSink, &pdwConnection); | |
97 | 449 objIOleObject.SetHostNames("main", "main"); //$NON-NLS-1$ //$NON-NLS-2$ |
450 | |
451 // Notify the control object that it is embedded in an OLE container | |
98 | 452 COM.OleSetContainedObject(objIUnknown, true); |
97 | 453 |
454 // Is OLE object linked or embedded? | |
98 | 455 IOleLink objIOleLink; |
456 if (objIUnknown.QueryInterface(&COM.IIDIOleLink, cast(void**)&objIOleLink) is COM.S_OK) { | |
457 IMoniker objIMoniker; | |
458 if (objIOleLink.GetSourceMoniker(&objIMoniker) is COM.S_OK) { | |
97 | 459 objIMoniker.Release(); |
460 type = COM.OLELINKED; | |
461 objIOleLink.BindIfRunning(); | |
462 } else { | |
463 isStatic = true; | |
464 } | |
465 objIOleLink.Release(); | |
466 } | |
467 } | |
468 protected int AddRef() { | |
469 refCount++; | |
470 return refCount; | |
471 } | |
472 private int CanInPlaceActivate() { | |
473 if (aspect is COM.DVASPECT_CONTENT && type is COM.OLEEMBEDDED) | |
474 return COM.S_OK; | |
475 | |
476 return COM.S_FALSE; | |
477 } | |
478 private int ContextSensitiveHelp(int fEnterMode) { | |
479 return COM.S_OK; | |
480 } | |
481 protected void createCOMInterfaces() { | |
98 | 482 iUnknown = new _IUnknownImpl(this); |
483 iOleClientSite = new _IOleClientSiteImpl(this); | |
484 iAdviseSink = new _IAdviseSinkImpl(this); | |
485 iOleInPlaceSite = new _IOleInPlaceSiteImpl(this); | |
486 iOleDocumentSite = new _IOleDocumentSiteImpl(this); | |
97 | 487 } |
488 protected IStorage createTempStorage() { | |
98 | 489 IStorage tmpStorage; |
97 | 490 int grfMode = COM.STGM_READWRITE | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_DELETEONRELEASE; |
98 | 491 HRESULT result = COM.StgCreateDocfile(null, grfMode, 0, &tmpStorage); |
492 if (result !is COM.S_OK) OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_FILE, result); | |
493 return (tmpStorage); | |
97 | 494 } |
495 /** | |
496 * Deactivates an active in-place object and discards the object's undo state. | |
497 */ | |
498 public void deactivateInPlaceClient() { | |
499 if (objIOleInPlaceObject !is null) { | |
500 objIOleInPlaceObject.InPlaceDeactivate(); | |
501 } | |
502 } | |
503 private void deleteTempStorage() { | |
504 //Destroy this item's contents in the temp root IStorage. | |
505 if (tempStorage !is null){ | |
506 tempStorage.Release(); | |
507 } | |
508 tempStorage = null; | |
509 } | |
510 protected void disposeCOMInterfaces() { | |
511 iUnknown = null; | |
512 iOleClientSite = null; | |
513 iAdviseSink = null; | |
514 iOleInPlaceSite = null; | |
515 iOleDocumentSite = null; | |
516 } | |
517 /** | |
518 * Requests that the OLE Document or ActiveX Control perform an action; actions are almost always | |
519 * changes to the activation state. | |
520 * | |
521 * @param verb the operation that is requested. This is one of the OLE.OLEIVERB_ values | |
522 * | |
523 * @return an HRESULT value indicating the success of the operation request; OLE.S_OK indicates | |
524 * success | |
525 */ | |
526 public int doVerb(int verb) { | |
527 // Not all OLE clients (for example PowerPoint) can be set into the running state in the constructor. | |
528 // The fix is to ensure that the client is in the running state before invoking any verb on it. | |
529 if (state is STATE_NONE) { | |
98 | 530 if (COM.OleRun(objIUnknown) is OLE.S_OK) state = STATE_RUNNING; |
97 | 531 } |
532 if (state is STATE_NONE || isStatic) | |
533 return COM.E_FAIL; | |
534 | |
535 // See PR: 1FV9RZW | |
98 | 536 RECT rect; |
537 OS.GetClientRect(handle, &rect); | |
538 int result = objIOleObject.DoVerb(verb, null, iOleClientSite, 0, handle, &rect); | |
97 | 539 |
540 if (state !is STATE_RUNNING && inInit) { | |
541 updateStorage(); | |
542 inInit = false; | |
543 } | |
544 return result; | |
545 } | |
546 /** | |
547 * Asks the OLE Document or ActiveX Control to execute a command from a standard | |
548 * list of commands. The OLE Document or ActiveX Control must support the IOleCommandTarget | |
549 * interface. The OLE Document or ActiveX Control does not have to support all the commands | |
550 * in the standard list. To check if a command is supported, you can call queryStatus with | |
551 * the cmdID. | |
552 * | |
553 * @param cmdID the ID of a command; these are the OLE.OLECMDID_ values - a small set of common | |
554 * commands | |
555 * @param options the optional flags; these are the OLE.OLECMDEXECOPT_ values | |
556 * @param in the argument for the command | |
557 * @param out the return value of the command | |
558 * | |
559 * @return an HRESULT value; OLE.S_OK is returned if successful | |
560 * | |
561 */ | |
98 | 562 public int exec(int cmdID, int options, Variant pvaIn, Variant pvaOut) { |
97 | 563 |
564 if (objIOleCommandTarget is null) { | |
98 | 565 if (objIUnknown.QueryInterface(&COM.IIDIOleCommandTarget, cast(void**)&objIOleCommandTarget) !is COM.S_OK) |
97 | 566 return OLE.ERROR_INTERFACE_NOT_FOUND; |
567 } | |
568 | |
98 | 569 VARIANT* pIn = null; |
570 VARIANT* pOut = null; | |
571 | |
572 if(pvaIn){ | |
573 pIn = new VARIANT(); | |
574 pvaIn.getData(pIn); | |
97 | 575 } |
98 | 576 if(pvaOut){ |
577 pOut = new VARIANT(); | |
578 pvaOut.getData(pOut); | |
97 | 579 } |
580 | |
98 | 581 HRESULT result = objIOleCommandTarget.Exec(null, cmdID, options, pIn, pOut); |
97 | 582 |
98 | 583 if(pIn) { |
584 COM.VariantClear(pIn); | |
97 | 585 } |
98 | 586 |
587 if(pOut) { | |
588 pvaOut.setData(pOut); | |
589 COM.VariantClear(pOut); | |
97 | 590 } |
591 | |
592 return result; | |
593 } | |
594 IDispatch getAutomationObject() { | |
98 | 595 IDispatch ppvObject; |
596 if (objIUnknown.QueryInterface(&COM.IIDIDispatch, cast(void**)&ppvObject) !is COM.S_OK) | |
97 | 597 return null; |
98 | 598 return ppvObject; |
97 | 599 } |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
600 protected GUID* getClassID(String clientName) { |
97 | 601 // create a GUID struct to hold the result |
98 | 602 GUID* guid = new GUID(); |
97 | 603 |
604 // create a null terminated array of char | |
98 | 605 wchar* buffer = null; |
97 | 606 if (clientName !is null) { |
98 | 607 buffer = StrToWCHARz(clientName);; |
97 | 608 } |
609 if (COM.CLSIDFromProgID(buffer, guid) !is COM.S_OK){ | |
98 | 610 HRESULT result = COM.CLSIDFromString(buffer, guid); |
97 | 611 if (result !is COM.S_OK) return null; |
612 } | |
613 return guid; | |
614 } | |
98 | 615 |
616 private HRESULT GetContainer(IOleContainer* ppContainer) { | |
97 | 617 /* Simple containers that do not support links to their embedded |
618 * objects probably do not need to implement this method. Instead, | |
619 * they can return E_NOINTERFACE and set ppContainer to NULL. | |
620 */ | |
98 | 621 if (ppContainer !is null) |
622 *ppContainer = null; | |
97 | 623 return COM.E_NOINTERFACE; |
624 } | |
98 | 625 |
626 private SIZE* getExtent() { | |
627 SIZE* sizel = new SIZE(); | |
97 | 628 // get the current size of the embedded OLENatives object |
629 if (objIOleObject !is null) { | |
98 | 630 if ( objIViewObject2 !is null && !COM.OleIsRunning(objIOleObject)) { |
97 | 631 objIViewObject2.GetExtent(aspect, -1, null, sizel); |
632 } else { | |
633 objIOleObject.GetExtent(aspect, sizel); | |
634 } | |
635 } | |
636 return xFormHimetricToPixels(sizel); | |
637 } | |
246 | 638 /** |
639 * Returns the indent value that would be used to compute the clipping area | |
640 * of the active X object. | |
641 * | |
642 * NOTE: The indent value is no longer being used by the client site. | |
643 * | |
644 * @return the rectangle representing the indent | |
645 */ | |
97 | 646 public Rectangle getIndent() { |
647 return new Rectangle(indent.left, indent.right, indent.top, indent.bottom); | |
648 } | |
649 /** | |
650 * Returns the program ID of the OLE Document or ActiveX Control. | |
651 * | |
652 * @return the program ID of the OLE Document or ActiveX Control | |
653 */ | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
654 public String getProgramID(){ |
97 | 655 if (appClsid !is null){ |
98 | 656 wchar* hMem; |
657 if (COM.ProgIDFromCLSID(appClsid, &hMem) is COM.S_OK) { | |
97 | 658 int length = OS.GlobalSize(hMem); |
98 | 659 auto ptr = OS.GlobalLock(hMem); |
660 wchar[] buffer = new wchar[length]; | |
661 COM.MoveMemory(buffer.ptr, ptr, length); | |
97 | 662 OS.GlobalUnlock(hMem); |
663 OS.GlobalFree(hMem); | |
664 | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
665 String result = WCHARzToStr(buffer.ptr); |
97 | 666 // remove null terminator |
98 | 667 //int index = result.indexOf("\0"); |
668 return result;//.substring(0, index); | |
97 | 669 } |
670 } | |
671 return null; | |
672 } | |
98 | 673 int ActivateMe(IOleDocumentView pViewToActivate) { |
674 if (pViewToActivate is null) { | |
675 void* ppvObject; | |
676 if (objIUnknown.QueryInterface(&COM.IIDIOleDocument, &ppvObject) !is COM.S_OK) return COM.E_FAIL; | |
677 IOleDocument objOleDocument = cast(IOleDocument)ppvObject; | |
678 if (objOleDocument.CreateView(iOleInPlaceSite, null, 0, &objDocumentView) !is COM.S_OK) return COM.E_FAIL; | |
97 | 679 objOleDocument.Release(); |
680 } else { | |
98 | 681 objDocumentView = pViewToActivate; |
97 | 682 objDocumentView.AddRef(); |
98 | 683 objDocumentView.SetInPlaceSite(iOleInPlaceSite); |
97 | 684 } |
685 objDocumentView.UIActivate(1);//TRUE | |
98 | 686 RECT* rect = getRect(); |
97 | 687 objDocumentView.SetRect(rect); |
688 objDocumentView.Show(1);//TRUE | |
689 return COM.S_OK; | |
690 } | |
98 | 691 protected int GetWindow(HWND* phwnd) { |
692 if (phwnd is null) | |
97 | 693 return COM.E_INVALIDARG; |
694 if (frame is null) { | |
98 | 695 *phwnd = null; |
97 | 696 return COM.E_NOTIMPL; |
697 } | |
698 | |
699 // Copy the Window's handle into the memory passed in | |
98 | 700 *phwnd = frame.handle; |
97 | 701 return COM.S_OK; |
702 } | |
98 | 703 RECT* getRect() { |
97 | 704 Point location = this.getLocation(); |
705 Rectangle area = frame.getClientArea(); | |
98 | 706 RECT* rect = new RECT(); |
97 | 707 rect.left = location.x; |
708 rect.top = location.y; | |
709 rect.right = location.x + area.width - borderWidths.left - borderWidths.right; | |
710 rect.bottom = location.y + area.height - borderWidths.top - borderWidths.bottom; | |
711 return rect; | |
712 } | |
98 | 713 |
714 private int GetWindowContext(IOleInPlaceFrame* ppFrame, IOleInPlaceUIWindow* ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo) { | |
715 if (frame is null || ppFrame is null) | |
97 | 716 return COM.E_NOTIMPL; |
717 | |
718 // fill in frame handle | |
98 | 719 auto iOleInPlaceFrame = frame.getIOleInPlaceFrame(); |
720 *ppFrame = iOleInPlaceFrame; | |
97 | 721 frame.AddRef(); |
722 | |
723 // null out document handle | |
98 | 724 if (ppDoc !is null) *ppDoc = null; |
97 | 725 |
726 // fill in position and clipping info | |
98 | 727 RECT* rect = getRect(); |
728 if (lprcPosRect !is null) OS.MoveMemory(lprcPosRect, rect, RECT.sizeof); | |
729 if (lprcClipRect !is null) OS.MoveMemory(lprcClipRect, rect, RECT.sizeof); | |
97 | 730 |
731 // get frame info | |
98 | 732 OLEINPLACEFRAMEINFO* frameInfo = new OLEINPLACEFRAMEINFO(); |
97 | 733 frameInfo.cb = OLEINPLACEFRAMEINFO.sizeof; |
734 frameInfo.fMDIApp = 0; | |
735 frameInfo.hwndFrame = frame.handle; | |
736 Shell shell = getShell(); | |
737 Menu menubar = shell.getMenuBar(); | |
738 if (menubar !is null && !menubar.isDisposed()) { | |
98 | 739 auto hwnd = shell.handle; |
740 auto cAccel = OS.SendMessage(hwnd, OS.WM_APP, 0, 0); | |
97 | 741 if (cAccel !is 0) { |
98 | 742 auto hAccel = cast(HACCEL) OS.SendMessage(hwnd, OS.WM_APP+1, 0, 0); |
743 if (hAccel !is null) { | |
97 | 744 frameInfo.cAccelEntries = cAccel; |
745 frameInfo.haccel = hAccel; | |
746 } | |
747 } | |
748 } | |
749 COM.MoveMemory(lpFrameInfo, frameInfo, OLEINPLACEFRAMEINFO.sizeof); | |
750 | |
751 return COM.S_OK; | |
752 } | |
246 | 753 /** |
754 * Returns whether ole document is dirty by checking whether the content | |
755 * of the file representing the document is dirty. | |
756 * | |
757 * @return <code>true</code> if the document has been modified, | |
758 * <code>false</code> otherwise. | |
759 * @since 3.1 | |
760 */ | |
97 | 761 public bool isDirty() { |
762 /* | |
763 * Note: this method must return true unless it is absolutely clear that the | |
764 * contents of the Ole Document do not differ from the contents in the file | |
765 * on the file system. | |
766 */ | |
767 | |
768 // Get access to the persistent storage mechanism | |
98 | 769 IPersistStorage permStorage; |
770 if (objIOleObject.QueryInterface(&COM.IIDIPersistFile, cast(void**)&permStorage) !is COM.S_OK) | |
97 | 771 return true; |
772 // Are the contents of the permanent storage different from the file? | |
98 | 773 auto result = permStorage.IsDirty(); |
97 | 774 permStorage.Release(); |
775 if (result is COM.S_FALSE) return false; | |
776 return true; | |
777 } | |
778 public bool isFocusControl () { | |
779 checkWidget (); | |
98 | 780 auto focusHwnd = OS.GetFocus(); |
97 | 781 if (objIOleInPlaceObject is null) return (handle is focusHwnd); |
98 | 782 HWND phwnd; |
783 objIOleInPlaceObject.GetWindow(&phwnd); | |
784 while (focusHwnd !is null) { | |
785 if (phwnd is focusHwnd) return true; | |
97 | 786 focusHwnd = OS.GetParent(focusHwnd); |
787 } | |
788 return false; | |
789 } | |
790 private int OnClose() { | |
791 return COM.S_OK; | |
792 } | |
793 private int OnDataChange(int pFormatetc, int pStgmed) { | |
794 return COM.S_OK; | |
795 } | |
796 private void onDispose(Event e) { | |
797 inDispose = true; | |
798 if (state !is STATE_NONE) | |
799 doVerb(OLE.OLEIVERB_DISCARDUNDOSTATE); | |
800 deactivateInPlaceClient(); | |
801 releaseObjectInterfaces(); // Note, must release object interfaces before releasing frame | |
802 deleteTempStorage(); | |
803 | |
804 // remove listeners | |
805 removeListener(DWT.Dispose, listener); | |
806 removeListener(DWT.FocusIn, listener); | |
807 removeListener(DWT.Paint, listener); | |
808 removeListener(DWT.Traverse, listener); | |
809 removeListener(DWT.KeyDown, listener); | |
810 frame.removeListener(DWT.Resize, listener); | |
811 frame.removeListener(DWT.Move, listener); | |
812 | |
813 frame.Release(); | |
814 frame = null; | |
815 } | |
816 void onFocusIn(Event e) { | |
817 if (inDispose) return; | |
818 if (state !is STATE_UIACTIVE) doVerb(OLE.OLEIVERB_SHOW); | |
819 if (objIOleInPlaceObject is null) return; | |
820 if (isFocusControl()) return; | |
98 | 821 HWND phwnd; |
822 objIOleInPlaceObject.GetWindow(&phwnd); | |
823 if (phwnd is null) return; | |
824 OS.SetFocus(phwnd); | |
97 | 825 } |
826 void onFocusOut(Event e) { | |
827 } | |
828 private int OnInPlaceActivate() { | |
829 state = STATE_INPLACEACTIVE; | |
830 frame.setCurrentDocument(this); | |
831 if (objIOleObject is null) | |
832 return COM.S_OK; | |
833 int[] ppvObject = new int[1]; | |
98 | 834 if (objIOleObject.QueryInterface(&COM.IIDIOleInPlaceObject, cast(void**)&objIOleInPlaceObject) is COM.S_OK) { |
835 //objIOleInPlaceObject = new IOleInPlaceObject(ppvObject[0]); | |
97 | 836 } |
837 return COM.S_OK; | |
838 } | |
839 private int OnInPlaceDeactivate() { | |
840 if (objIOleInPlaceObject !is null) objIOleInPlaceObject.Release(); | |
841 objIOleInPlaceObject = null; | |
842 state = STATE_RUNNING; | |
843 redraw(); | |
844 Shell shell = getShell(); | |
845 if (isFocusControl() || frame.isFocusControl()) { | |
846 shell.traverse(DWT.TRAVERSE_TAB_NEXT); | |
847 } | |
848 return COM.S_OK; | |
849 } | |
98 | 850 private int OnPosRectChange(LPRECT lprcPosRect) { |
97 | 851 Point size = getSize(); |
852 setExtent(size.x, size.y); | |
853 return COM.S_OK; | |
854 } | |
855 private void onPaint(Event e) { | |
856 if (state is STATE_RUNNING || state is STATE_INPLACEACTIVE) { | |
98 | 857 SIZE* size = getExtent(); |
97 | 858 Rectangle area = getClientArea(); |
98 | 859 RECT* rect = new RECT(); |
97 | 860 if (getProgramID().startsWith("Excel.Sheet")) { //$NON-NLS-1$ |
861 rect.left = area.x; rect.right = area.x + (area.height * size.cx / size.cy); | |
862 rect.top = area.y; rect.bottom = area.y + area.height; | |
863 } else { | |
864 rect.left = area.x; rect.right = area.x + size.cx; | |
865 rect.top = area.y; rect.bottom = area.y + size.cy; | |
866 } | |
867 | |
98 | 868 auto pArea = cast(RECT*)OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, RECT.sizeof); |
97 | 869 OS.MoveMemory(pArea, rect, RECT.sizeof); |
98 | 870 COM.OleDraw(objIUnknown, aspect, e.gc.handle, pArea); |
97 | 871 OS.GlobalFree(pArea); |
872 } | |
873 } | |
874 private void onResize(Event e) { | |
875 Rectangle area = frame.getClientArea(); | |
876 setBounds(borderWidths.left, | |
877 borderWidths.top, | |
878 area.width - borderWidths.left - borderWidths.right, | |
879 area.height - borderWidths.top - borderWidths.bottom); | |
880 | |
881 setObjectRects(); | |
882 } | |
883 private void OnSave() { | |
884 } | |
885 private int OnShowWindow(int fShow) { | |
886 return COM.S_OK; | |
887 } | |
888 private int OnUIActivate() { | |
889 if (objIOleInPlaceObject is null) return COM.E_FAIL; | |
890 state = STATE_UIACTIVE; | |
98 | 891 HWND phwnd; |
892 if (objIOleInPlaceObject.GetWindow(&phwnd) is COM.S_OK) { | |
893 OS.SetWindowPos(phwnd, cast(HWND)OS.HWND_TOP, 0, 0, 0, 0, OS.SWP_NOSIZE | OS.SWP_NOMOVE); | |
97 | 894 } |
895 return COM.S_OK; | |
896 } | |
897 private int OnUIDeactivate(int fUndoable) { | |
898 // currently, we are ignoring the fUndoable flag | |
899 if (frame is null || frame.isDisposed()) return COM.S_OK; | |
900 state = STATE_INPLACEACTIVE; | |
98 | 901 frame.SetActiveObject(null, null); |
97 | 902 redraw(); |
903 Shell shell = getShell(); | |
904 if (isFocusControl() || frame.isFocusControl()) { | |
905 shell.traverse(DWT.TRAVERSE_TAB_NEXT); | |
906 } | |
907 Menu menubar = shell.getMenuBar(); | |
908 if (menubar is null || menubar.isDisposed()) | |
909 return COM.S_OK; | |
910 | |
98 | 911 auto shellHandle = shell.handle; |
97 | 912 OS.SetMenu(shellHandle, menubar.handle); |
98 | 913 return COM.OleSetMenuDescriptor(null, shellHandle, null, null, null); |
97 | 914 } |
915 private void onTraverse(Event event) { | |
916 switch (event.detail) { | |
917 case DWT.TRAVERSE_ESCAPE: | |
918 case DWT.TRAVERSE_RETURN: | |
919 case DWT.TRAVERSE_TAB_NEXT: | |
920 case DWT.TRAVERSE_TAB_PREVIOUS: | |
921 case DWT.TRAVERSE_PAGE_NEXT: | |
922 case DWT.TRAVERSE_PAGE_PREVIOUS: | |
923 case DWT.TRAVERSE_MNEMONIC: | |
924 event.doit = true; | |
925 break; | |
162
619faee45ef6
add missing default cases
Thomas Graber <d4rkdragon@gmail.com>
parents:
98
diff
changeset
|
926 default: |
97 | 927 } |
928 } | |
929 private int OnViewChange(int dwAspect, int lindex) { | |
930 return COM.S_OK; | |
931 } | |
98 | 932 protected int QueryInterface(REFIID riid, void ** ppvObject) { |
97 | 933 |
98 | 934 if (riid is null || ppvObject is null) |
97 | 935 return COM.E_NOINTERFACE; |
284
bb89fd34ec82
Fix for OLE functionality. Thanks to Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
936 GUID oGuid = *riid; |
bb89fd34ec82
Fix for OLE functionality. Thanks to Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
937 GUID* guid = &oGuid; |
bb89fd34ec82
Fix for OLE functionality. Thanks to Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
938 //COM.MoveMemory(guid, riid, GUID.sizeof); |
97 | 939 |
98 | 940 if (COM.IsEqualGUID(guid, &COM.IIDIUnknown)) { |
941 *ppvObject = cast(void*)cast(IUnknown)iUnknown; | |
97 | 942 AddRef(); |
943 return COM.S_OK; | |
944 } | |
98 | 945 if (COM.IsEqualGUID(guid, &COM.IIDIAdviseSink)) { |
946 *ppvObject = cast(void*)cast(IAdviseSink)iAdviseSink; | |
97 | 947 AddRef(); |
948 return COM.S_OK; | |
949 } | |
98 | 950 if (COM.IsEqualGUID(guid, &COM.IIDIOleClientSite)) { |
951 *ppvObject = cast(void*)cast(IOleClientSite)iOleClientSite; | |
97 | 952 AddRef(); |
953 return COM.S_OK; | |
954 } | |
98 | 955 if (COM.IsEqualGUID(guid, &COM.IIDIOleInPlaceSite)) { |
956 *ppvObject = cast(void*)cast(IOleInPlaceSite)iOleInPlaceSite; | |
97 | 957 AddRef(); |
958 return COM.S_OK; | |
959 } | |
98 | 960 if (COM.IsEqualGUID(guid, &COM.IIDIOleDocumentSite )) { |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
961 String progID = getProgramID(); |
97 | 962 if (!progID.startsWith("PowerPoint")) { //$NON-NLS-1$ |
98 | 963 *ppvObject = cast(void*)cast(IOleDocumentSite)iOleDocumentSite; |
97 | 964 AddRef(); |
965 return COM.S_OK; | |
966 } | |
967 } | |
98 | 968 *ppvObject = null; |
97 | 969 return COM.E_NOINTERFACE; |
970 } | |
971 /** | |
972 * Returns the status of the specified command. The status is any bitwise OR'd combination of | |
973 * SWTOLE.OLECMDF_SUPPORTED, SWTOLE.OLECMDF_ENABLED, SWTOLE.OLECMDF_LATCHED, SWTOLE.OLECMDF_NINCHED. | |
974 * You can query the status of a command before invoking it with OleClientSite.exec. The | |
975 * OLE Document or ActiveX Control must support the IOleCommandTarget to make use of this method. | |
976 * | |
977 * @param cmd the ID of a command; these are the OLE.OLECMDID_ values - a small set of common | |
978 * commands | |
979 * | |
980 * @return the status of the specified command or 0 if unable to query the OLE Object; these are the | |
981 * OLE.OLECMDF_ values | |
982 */ | |
983 public int queryStatus(int cmd) { | |
984 | |
985 if (objIOleCommandTarget is null) { | |
98 | 986 if (objIUnknown.QueryInterface(&COM.IIDIOleCommandTarget, cast(void**)&objIOleCommandTarget) !is COM.S_OK) |
97 | 987 return 0; |
988 } | |
989 | |
98 | 990 OLECMD* olecmd = new OLECMD(); |
97 | 991 olecmd.cmdID = cmd; |
992 | |
98 | 993 auto result = objIOleCommandTarget.QueryStatus(null, 1, olecmd, null); |
97 | 994 |
995 if (result !is COM.S_OK) return 0; | |
996 | |
997 return olecmd.cmdf; | |
998 } | |
999 protected int Release() { | |
1000 refCount--; | |
1001 | |
1002 if (refCount is 0) { | |
1003 disposeCOMInterfaces(); | |
1004 } | |
1005 return refCount; | |
1006 } | |
1007 protected void releaseObjectInterfaces() { | |
1008 | |
246 | 1009 if (objIOleInPlaceObject !is null) |
97 | 1010 objIOleInPlaceObject.Release(); |
1011 objIOleInPlaceObject = null; | |
1012 | |
1013 if (objIOleObject !is null) { | |
1014 objIOleObject.Close(COM.OLECLOSE_NOSAVE); | |
1015 objIOleObject.Release(); | |
1016 } | |
1017 objIOleObject = null; | |
1018 | |
1019 if (objDocumentView !is null){ | |
1020 objDocumentView.Release(); | |
1021 } | |
1022 objDocumentView = null; | |
1023 | |
1024 if (objIViewObject2 !is null) { | |
98 | 1025 objIViewObject2.SetAdvise(aspect, 0, null); |
97 | 1026 objIViewObject2.Release(); |
1027 } | |
1028 objIViewObject2 = null; | |
1029 | |
1030 if (objIOleCommandTarget !is null) | |
1031 objIOleCommandTarget.Release(); | |
1032 objIOleCommandTarget = null; | |
1033 | |
1034 if (objIUnknown !is null){ | |
1035 objIUnknown.Release(); | |
1036 } | |
1037 objIUnknown = null; | |
1038 | |
1039 COM.CoFreeUnusedLibraries(); | |
1040 } | |
246 | 1041 /** |
1042 * Saves the document to the specified file and includes OLE specific information if specified. | |
1043 * This method must <b>only</b> be used for files that have an OLE Storage format. For example, | |
1044 * a word file edited with Word.Document should be saved using this method because there is | |
1045 * formating information that should be stored in the OLE specific Storage format. | |
1046 * | |
1047 * @param file the file to which the changes are to be saved | |
1048 * @param includeOleInfo the flag to indicate whether OLE specific information should be saved. | |
1049 * | |
1050 * @return true if the save was successful | |
1051 */ | |
97 | 1052 public bool save(File file, bool includeOleInfo) { |
1053 if (includeOleInfo) | |
1054 return saveToStorageFile(file); | |
1055 return saveToTraditionalFile(file); | |
1056 } | |
98 | 1057 private bool saveFromContents(IStream address, File file) { |
97 | 1058 |
1059 bool success = false; | |
1060 | |
98 | 1061 IStream tempContents = address; |
97 | 1062 tempContents.AddRef(); |
1063 | |
1064 try { | |
1065 FileOutputStream writer = new FileOutputStream(file); | |
1066 | |
1067 int increment = 1024 * 4; | |
98 | 1068 LPVOID pv = COM.CoTaskMemAlloc(increment); |
1069 uint pcbWritten; | |
1070 while (tempContents.Read(pv, increment, &pcbWritten) is COM.S_OK && pcbWritten > 0) { | |
1071 byte[] buffer = new byte[ pcbWritten]; | |
1072 OS.MoveMemory(buffer.ptr, pv, pcbWritten); | |
97 | 1073 writer.write(buffer); // Note: if file does not exist, this will create the file the |
1074 // first time it is called | |
1075 success = true; | |
1076 } | |
1077 COM.CoTaskMemFree(pv); | |
1078 | |
1079 writer.close(); | |
1080 | |
1081 } catch (IOException err) { | |
1082 } | |
1083 | |
1084 tempContents.Release(); | |
1085 | |
1086 return success; | |
1087 } | |
98 | 1088 private bool saveFromOle10Native(IStream address, File file) { |
97 | 1089 |
1090 bool success = false; | |
1091 | |
98 | 1092 IStream tempContents = address; |
97 | 1093 tempContents.AddRef(); |
1094 | |
1095 // The "\1Ole10Native" stream contains a DWORD header whose value is the length | |
1096 // of the native data that follows. | |
98 | 1097 LPVOID pv = COM.CoTaskMemAlloc(4); |
1098 uint size; | |
1099 auto rc = tempContents.Read(pv, 4, null); | |
300
acf6957f2344
OLE fixes, thanks to Enzo Petrelli.
Frank Benoit <benoit@tionex.de>
parents:
284
diff
changeset
|
1100 OS.MoveMemory(&size, pv, 4); |
97 | 1101 COM.CoTaskMemFree(pv); |
98 | 1102 if (rc is COM.S_OK && size > 0) { |
97 | 1103 |
1104 // Read the data | |
98 | 1105 byte[] buffer = new byte[size]; |
1106 pv = COM.CoTaskMemAlloc(size); | |
1107 rc = tempContents.Read(pv, size, null); | |
1108 OS.MoveMemory(buffer.ptr, pv, size); | |
97 | 1109 COM.CoTaskMemFree(pv); |
1110 | |
1111 // open the file and write data into it | |
1112 try { | |
1113 FileOutputStream writer = new FileOutputStream(file); | |
1114 writer.write(buffer); // Note: if file does not exist, this will create the file | |
1115 writer.close(); | |
1116 | |
1117 success = true; | |
1118 } catch (IOException err) { | |
1119 } | |
1120 } | |
1121 tempContents.Release(); | |
1122 | |
1123 return success; | |
1124 } | |
1125 private int SaveObject() { | |
1126 | |
1127 updateStorage(); | |
1128 | |
1129 return COM.S_OK; | |
1130 } | |
1131 /** | |
1132 * Saves the document to the specified file and includes OLE specific information. This method | |
1133 * must <b>only</b> be used for files that have an OLE Storage format. For example, a word file | |
1134 * edited with Word.Document should be saved using this method because there is formating information | |
1135 * that should be stored in the OLE specific Storage format. | |
1136 * | |
1137 * @param file the file to which the changes are to be saved | |
1138 * | |
1139 * @return true if the save was successful | |
1140 */ | |
1141 private bool saveToStorageFile(File file) { | |
1142 // The file will be saved using the formating of the current application - this | |
1143 // may not be the format of the application that was originally used to create the file | |
1144 // e.g. if an Excel file is opened in Word, the Word application will save the file in the | |
1145 // Word format | |
1146 // Note: if the file already exists, some applications will not overwrite the file | |
1147 // In these cases, you should delete the file first (probably save the contents of the file in case the | |
1148 // save fails) | |
1149 if (file is null || file.isDirectory()) return false; | |
1150 if (!updateStorage()) return false; | |
1151 | |
1152 // get access to the persistent storage mechanism | |
98 | 1153 IPersistStorage permStorage; |
1154 if (objIOleObject.QueryInterface(&COM.IIDIPersistStorage, cast(void**)&permStorage) !is COM.S_OK) return false; | |
97 | 1155 try { |
98 | 1156 IStorage storage; |
1157 wchar* path = StrToWCHARz(file.getAbsolutePath()); | |
97 | 1158 int mode = COM.STGM_TRANSACTED | COM.STGM_READWRITE | COM.STGM_SHARE_EXCLUSIVE | COM.STGM_CREATE; |
98 | 1159 int result = COM.StgCreateDocfile(path, mode, 0, &storage); //Does an AddRef if successful |
97 | 1160 if (result !is COM.S_OK) return false; |
1161 try { | |
98 | 1162 if (COM.OleSave(permStorage, storage, false) is COM.S_OK) { |
97 | 1163 if (storage.Commit(COM.STGC_DEFAULT) is COM.S_OK) { |
1164 return true; | |
1165 } | |
1166 } | |
1167 } finally { | |
1168 storage.Release(); | |
1169 } | |
1170 } finally { | |
1171 permStorage.Release(); | |
1172 } | |
1173 return false; | |
1174 } | |
1175 /** | |
1176 * Saves the document to the specified file. This method must be used for | |
1177 * files that do not have an OLE Storage format. For example, a bitmap file edited with MSPaint | |
1178 * should be saved using this method because bitmap is a standard format that does not include any | |
1179 * OLE specific data. | |
1180 * | |
1181 * @param file the file to which the changes are to be saved | |
1182 * | |
1183 * @return true if the save was successful | |
1184 */ | |
1185 private bool saveToTraditionalFile(File file) { | |
1186 // Note: if the file already exists, some applications will not overwrite the file | |
1187 // In these cases, you should delete the file first (probably save the contents of the file in case the | |
1188 // save fails) | |
1189 if (file is null || file.isDirectory()) | |
1190 return false; | |
1191 if (!updateStorage()) | |
1192 return false; | |
1193 | |
98 | 1194 IStream stream; |
97 | 1195 // Look for a CONTENTS stream |
98 | 1196 if (tempStorage.OpenStream(("CONTENTS"w).ptr, null, COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE, 0, &stream) is COM.S_OK) //$NON-NLS-1$ |
1197 return saveFromContents(stream, file); | |
97 | 1198 |
1199 // Look for Ole 1.0 object stream | |
98 | 1200 if (tempStorage.OpenStream(("\1Ole10Native"w).ptr, null, COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE, 0, &stream) is COM.S_OK) //$NON-NLS-1$ |
1201 return saveFromOle10Native(stream, file); | |
97 | 1202 |
1203 return false; | |
1204 } | |
1205 private int Scroll(int scrollExtant) { | |
1206 return COM.S_OK; | |
1207 } | |
98 | 1208 void setBorderSpace(RECT* newBorderwidth) { |
1209 borderWidths = *newBorderwidth; | |
97 | 1210 // readjust size and location of client site |
1211 Rectangle area = frame.getClientArea(); | |
1212 setBounds(borderWidths.left, borderWidths.top, | |
1213 area.width - borderWidths.left - borderWidths.right, | |
1214 area.height - borderWidths.top - borderWidths.bottom); | |
1215 setObjectRects(); | |
1216 } | |
1217 private void setExtent(int width, int height){ | |
1218 // Resize the width and height of the embedded/linked OLENatives object | |
1219 // to the specified values. | |
1220 | |
1221 if (objIOleObject is null || isStatic || inUpdate) return; | |
98 | 1222 SIZE* currentExtent = getExtent(); |
97 | 1223 if (width is currentExtent.cx && height is currentExtent.cy) return; |
1224 | |
98 | 1225 SIZE* newExtent = new SIZE(); |
97 | 1226 newExtent.cx = width; newExtent.cy = height; |
1227 newExtent = xFormPixelsToHimetric(newExtent); | |
1228 | |
1229 // Get the server running first, then do a SetExtent, then show it | |
98 | 1230 bool alreadyRunning = cast(bool) COM.OleIsRunning(objIOleObject); |
97 | 1231 if (!alreadyRunning) |
98 | 1232 COM.OleRun(objIOleObject); |
97 | 1233 |
1234 if (objIOleObject.SetExtent(aspect, newExtent) is COM.S_OK){ | |
1235 inUpdate = true; | |
1236 objIOleObject.Update(); | |
1237 inUpdate = false; | |
1238 if (!alreadyRunning) | |
1239 // Close server if it wasn't already running upon entering this method. | |
1240 objIOleObject.Close(COM.OLECLOSE_SAVEIFDIRTY); | |
1241 } | |
1242 } | |
246 | 1243 /** |
1244 * The indent value is no longer being used by the client site. | |
1245 * | |
1246 * @param newIndent the rectangle representing the indent amount | |
1247 */ | |
97 | 1248 public void setIndent(Rectangle newIndent) { |
1249 indent.left = newIndent.x; | |
1250 indent.right = newIndent.width; | |
1251 indent.top = newIndent.y; | |
1252 indent.bottom = newIndent.height; | |
1253 } | |
1254 private void setObjectRects() { | |
1255 if (objIOleInPlaceObject is null) return; | |
1256 // size the object to fill the available space | |
1257 // leave a border | |
98 | 1258 RECT* rect = getRect(); |
97 | 1259 objIOleInPlaceObject.SetObjectRects(rect, rect); |
1260 } | |
1261 | |
1262 private int ShowObject() { | |
1263 /* Tells the container to position the object so it is visible to | |
1264 * the user. This method ensures that the container itself is | |
1265 * visible and not minimized. | |
1266 */ | |
1267 return COM.S_OK; | |
1268 } | |
1269 /** | |
1270 * Displays a dialog with the property information for this OLE Object. The OLE Document or | |
1271 * ActiveX Control must support the ISpecifyPropertyPages interface. | |
1272 * | |
1273 * @param title the name that will appear in the titlebar of the dialog | |
1274 */ | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
162
diff
changeset
|
1275 public void showProperties(String title) { |
97 | 1276 |
1277 // Get the Property Page information from the OLE Object | |
98 | 1278 ISpecifyPropertyPages objISPP; |
1279 if (objIUnknown.QueryInterface(&COM.IIDISpecifyPropertyPages, cast(void**)&objISPP) !is COM.S_OK) return; | |
1280 CAUUID* caGUID = new CAUUID(); | |
1281 auto result = objISPP.GetPages(caGUID); | |
97 | 1282 objISPP.Release(); |
1283 if (result !is COM.S_OK) return; | |
1284 | |
1285 // create a frame in which to display the pages | |
98 | 1286 wchar* chTitle = null; |
97 | 1287 if (title !is null) { |
98 | 1288 chTitle = StrToWCHARz(title); |
97 | 1289 } |
98 | 1290 result = COM.OleCreatePropertyFrame(frame.handle, 10, 10, chTitle, 1, &objIUnknown, caGUID.cElems, caGUID.pElems, COM.LOCALE_USER_DEFAULT, 0, null); |
97 | 1291 |
1292 // free the property page information | |
1293 COM.CoTaskMemFree(caGUID.pElems); | |
1294 } | |
1295 private bool updateStorage() { | |
1296 | |
1297 if (tempStorage is null) return false; | |
1298 | |
98 | 1299 IPersistStorage iPersistStorage; |
1300 if (objIUnknown.QueryInterface(&COM.IIDIPersistStorage, cast(void**)&iPersistStorage) !is COM.S_OK) return false; | |
97 | 1301 |
98 | 1302 auto result = COM.OleSave(iPersistStorage, tempStorage, true); |
97 | 1303 |
1304 if (result !is COM.S_OK){ | |
1305 // OleSave will fail for static objects, so do what OleSave does. | |
98 | 1306 COM.WriteClassStg(tempStorage, objClsid); |
1307 result = iPersistStorage.Save(tempStorage, true); | |
97 | 1308 } |
1309 | |
1310 tempStorage.Commit(COM.STGC_DEFAULT); | |
98 | 1311 result = iPersistStorage.SaveCompleted(null); |
97 | 1312 iPersistStorage.Release(); |
1313 | |
1314 return true; | |
1315 } | |
98 | 1316 private SIZE* xFormHimetricToPixels(SIZE* aSize) { |
97 | 1317 // Return a new Size which is the pixel transformation of a |
1318 // size in HIMETRIC units. | |
1319 | |
98 | 1320 auto hDC = OS.GetDC(null); |
97 | 1321 int xppi = OS.GetDeviceCaps(hDC, 88); // logical pixels/inch in x |
1322 int yppi = OS.GetDeviceCaps(hDC, 90); // logical pixels/inch in y | |
98 | 1323 OS.ReleaseDC(null, hDC); |
97 | 1324 int cx = Compatibility.round(aSize.cx * xppi, 2540); // 2540 HIMETRIC units per inch |
1325 int cy = Compatibility.round(aSize.cy * yppi, 2540); | |
98 | 1326 SIZE* size = new SIZE(); |
97 | 1327 size.cx = cx; |
1328 size.cy = cy; | |
1329 return size; | |
1330 } | |
98 | 1331 private SIZE* xFormPixelsToHimetric(SIZE* aSize) { |
97 | 1332 // Return a new size which is the HIMETRIC transformation of a |
1333 // size in pixel units. | |
1334 | |
98 | 1335 auto hDC = OS.GetDC(null); |
97 | 1336 int xppi = OS.GetDeviceCaps(hDC, 88); // logical pixels/inch in x |
1337 int yppi = OS.GetDeviceCaps(hDC, 90); // logical pixels/inch in y | |
98 | 1338 OS.ReleaseDC(null, hDC); |
97 | 1339 int cx = Compatibility.round(aSize.cx * 2540, xppi); // 2540 HIMETRIC units per inch |
1340 int cy = Compatibility.round(aSize.cy * 2540, yppi); | |
98 | 1341 SIZE* size = new SIZE(); |
97 | 1342 size.cx = cx; |
1343 size.cy = cy; | |
1344 return size; | |
1345 } | |
1346 } | |
98 | 1347 |
1348 class _IAdviseSinkImpl : IAdviseSink { | |
1349 | |
1350 OleClientSite parent; | |
1351 this(OleClientSite p) { parent = p; } | |
1352 extern (Windows): | |
1353 // interface of IUnknown | |
1354 HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } | |
1355 ULONG AddRef() { return parent.AddRef(); } | |
1356 ULONG Release() { return parent.Release(); } | |
1357 | |
1358 // interface of IAdviseSink | |
340
8a2a24a30ea9
Fix compile error on dmd 1.049. Thanks Torhu
Frank Benoit <benoit@tionex.de>
parents:
300
diff
changeset
|
1359 void OnDataChange(FORMATETC *pFormatetc,STGMEDIUM *pStgmed) { } |
8a2a24a30ea9
Fix compile error on dmd 1.049. Thanks Torhu
Frank Benoit <benoit@tionex.de>
parents:
300
diff
changeset
|
1360 void OnViewChange(DWORD dwAspect, LONG lindex) { } |
8a2a24a30ea9
Fix compile error on dmd 1.049. Thanks Torhu
Frank Benoit <benoit@tionex.de>
parents:
300
diff
changeset
|
1361 void OnRename(IMoniker pmk) { } |
8a2a24a30ea9
Fix compile error on dmd 1.049. Thanks Torhu
Frank Benoit <benoit@tionex.de>
parents:
300
diff
changeset
|
1362 void OnSave() { } |
8a2a24a30ea9
Fix compile error on dmd 1.049. Thanks Torhu
Frank Benoit <benoit@tionex.de>
parents:
300
diff
changeset
|
1363 void OnClose() { } |
98 | 1364 } |
1365 | |
1366 class _IOleClientSiteImpl : IOleClientSite { | |
1367 | |
1368 OleClientSite parent; | |
1369 this(OleClientSite p) { parent = p; } | |
1370 extern (Windows): | |
1371 // interface of IUnknown | |
1372 HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } | |
1373 ULONG AddRef() { return parent.AddRef(); } | |
1374 ULONG Release() { return parent.Release(); } | |
1375 | |
1376 // interface of IOleClientSite | |
1377 HRESULT SaveObject() { if(parent) parent.updateStorage(); return COM.S_OK; } | |
1378 HRESULT GetMoniker( DWORD dwAssign, DWORD dwWhichMoniker, IMoniker * ppmk ) {return COM.E_NOTIMPL; } | |
1379 HRESULT GetContainer( IOleContainer* ppContainer ) { return parent.GetContainer(ppContainer);} | |
1380 HRESULT ShowObject() { | |
1381 /* Tells the container to position the object so it is visible to | |
1382 * the user. This method ensures that the container itself is | |
1383 * visible and not minimized. | |
1384 */ | |
1385 return COM.S_OK; | |
1386 } | |
1387 HRESULT OnShowWindow(BOOL fShow ) {return COM.S_OK; } | |
1388 HRESULT RequestNewObjectLayout() {return COM.E_NOTIMPL; } | |
1389 } | |
1390 | |
1391 class _IOleDocumentSiteImpl : IOleDocumentSite { | |
1392 | |
1393 OleClientSite parent; | |
1394 this(OleClientSite p) { parent = p; } | |
1395 extern (Windows): | |
1396 // interface of IUnknown | |
1397 HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } | |
1398 ULONG AddRef() { return parent.AddRef(); } | |
1399 ULONG Release() { return parent.Release(); } | |
1400 | |
1401 // interface of IOleDocumentSite | |
1402 HRESULT ActivateMe(IOleDocumentView pViewToActivate) { return parent.ActivateMe(pViewToActivate);} | |
1403 } | |
1404 | |
1405 class _IOleInPlaceSiteImpl : IOleInPlaceSite { | |
1406 OleClientSite parent; | |
1407 this(OleClientSite p) { parent = p; } | |
1408 extern (Windows): | |
1409 // interface of IUnknown | |
1410 HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } | |
1411 ULONG AddRef() { return parent.AddRef(); } | |
1412 ULONG Release() { return parent.Release(); } | |
1413 | |
1414 // interface of IOleWindow | |
1415 HRESULT GetWindow( HWND* phwnd ) { return parent.GetWindow(phwnd); } | |
1416 HRESULT ContextSensitiveHelp( BOOL fEnterMode ) {return COM.S_OK; } | |
1417 | |
1418 // interface of IOleInPlaceSite | |
1419 HRESULT CanInPlaceActivate() { return parent.CanInPlaceActivate();} | |
1420 HRESULT OnInPlaceActivate() { return parent.OnInPlaceActivate(); } | |
1421 HRESULT OnUIActivate() { return parent.OnUIActivate(); } | |
1422 HRESULT GetWindowContext( IOleInPlaceFrame * ppFrame, IOleInPlaceUIWindow * ppDoc, LPRECT lprcPosRect, LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo ) { | |
1423 return parent.GetWindowContext(ppFrame, ppDoc, lprcPosRect, lprcClipRect, lpFrameInfo); | |
1424 } | |
1425 HRESULT Scroll( SIZE scrollExtant ) {return COM.S_OK; } | |
1426 HRESULT OnUIDeactivate( BOOL fUndoable ) { return parent.OnUIDeactivate(fUndoable);} | |
1427 HRESULT OnInPlaceDeactivate() { return parent.OnInPlaceDeactivate();} | |
1428 HRESULT DiscardUndoState() {return COM.E_NOTIMPL; } | |
1429 HRESULT DeactivateAndUndo() {return COM.E_NOTIMPL; } | |
1430 HRESULT OnPosRectChange( LPCRECT lprcPosRect) { return parent.OnPosRectChange(lprcPosRect);} | |
1431 } | |
1432 | |
1433 class _IUnknownImpl : IUnknown | |
1434 { | |
1435 | |
1436 OleClientSite parent; | |
1437 this(OleClientSite p) { parent = p; } | |
1438 extern (Windows): | |
1439 // interface of IUnknown | |
1440 HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } | |
1441 ULONG AddRef() { return parent.AddRef(); } | |
1442 ULONG Release() { return parent.Release(); } | |
1443 } | |
1444 | |
1445 | |
1446 | |
1447 |