Mercurial > projects > dwt-win
annotate dwt/ole/win32/OleControlSite.d @ 289:d17d33bea6d0
Fix: indirection typo, thanks Enzo Petrelli
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 21 Aug 2008 16:11:32 +0200 |
parents | bb89fd34ec82 |
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.OleControlSite; | |
14 | |
15 import dwt.DWT; | |
16 import dwt.DWTError; | |
17 import dwt.DWTException; | |
18 import dwt.graphics.Color; | |
19 import dwt.graphics.Font; | |
20 import dwt.graphics.FontData; | |
98 | 21 import dwt.graphics.Device; |
97 | 22 import dwt.internal.ole.win32.COM; |
98 | 23 import dwt.internal.ole.win32.COMTYPES; |
24 import dwt.internal.ole.win32.extras; | |
25 import dwt.internal.ole.win32.ifs; | |
26 import dwt.internal.ole.win32.OAIDL; | |
27 import dwt.internal.ole.win32.OBJIDL; | |
97 | 28 import dwt.internal.win32.OS; |
29 import dwt.widgets.Composite; | |
30 import dwt.widgets.Event; | |
31 | |
32 import dwt.ole.win32.OleClientSite; | |
98 | 33 import dwt.ole.win32.OleEventSink; |
34 import dwt.ole.win32.OlePropertyChangeSink; | |
35 import dwt.ole.win32.OleListener; | |
36 import dwt.ole.win32.OleAutomation; | |
37 import dwt.ole.win32.Variant; | |
38 import dwt.ole.win32.OLE; | |
97 | 39 |
98 | 40 import dwt.dwthelper.utils; |
41 | |
97 | 42 /** |
43 * OleControlSite provides a site to manage an embedded ActiveX Control within a container. | |
44 * | |
45 * <p>In addition to the behaviour provided by OleClientSite, this object provides the following: | |
46 * <ul> | |
47 * <li>events from the ActiveX control | |
48 * <li>notification of property changes from the ActiveX control | |
49 * <li>simplified access to well known properties of the ActiveX Control (e.g. font, background color) | |
50 * <li>expose ambient properties of the container to the ActiveX Control | |
51 * </ul> | |
52 * | |
53 * <p>This object implements the OLE Interfaces IOleControlSite, IDispatch, and IPropertyNotifySink. | |
54 * | |
55 * <p>Note that although this class is a subclass of <code>Composite</code>, | |
56 * it does not make sense to add <code>Control</code> children to it, | |
57 * or set a layout on it. | |
58 * </p><p> | |
59 * <dl> | |
60 * <dt><b>Styles</b> <dd>BORDER | |
61 * <dt><b>Events</b> <dd>Dispose, Move, Resize | |
62 * </dl> | |
63 * | |
246 | 64 * @see <a href="http://www.eclipse.org/swt/snippets/#ole">OLE and ActiveX snippets</a> |
65 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Examples: OLEExample, OleWebBrowser</a> | |
97 | 66 */ |
98 | 67 public class OleControlSite : OleClientSite |
97 | 68 { |
69 // interfaces for this container | |
98 | 70 private _IOleControlSiteImpl iOleControlSite; |
71 private _IDispatchImpl iDispatch; | |
97 | 72 |
73 // supporting Property Change attributes | |
74 private OlePropertyChangeSink olePropertyChangeSink; | |
75 | |
76 // supporting Event Sink attributes | |
98 | 77 private OleEventSink[] oleEventSink; |
78 private GUID*[] oleEventSinkGUID; | |
79 private IUnknown[] oleEventSinkIUnknown; | |
97 | 80 |
81 // supporting information for the Control COM object | |
98 | 82 private CONTROLINFO* currentControlInfo; |
83 private int[] sitePropertyIds; | |
84 private Variant[] sitePropertyValues; | |
97 | 85 |
86 // work around for IE destroying the caret | |
87 static int SWT_RESTORECARET; | |
88 | |
89 /** | |
90 * Create an OleControlSite child widget using style bits | |
91 * to select a particular look or set of properties. | |
92 * | |
93 * @param parent a composite widget; must be an OleFrame | |
94 * @param style the bitwise OR'ing of widget styles | |
95 * @param progId the unique program identifier which has been registered for this ActiveX Control; | |
96 * the value of the ProgID key or the value of the VersionIndependentProgID key specified | |
97 * in the registry for this Control (for example, the VersionIndependentProgID for | |
98 * Internet Explorer is Shell.Explorer) | |
99 * | |
246 | 100 * @exception IllegalArgumentException <ul> |
97 | 101 * <li>ERROR_NULL_ARGUMENT when the parent is null |
102 *</ul> | |
103 * @exception DWTException <ul> | |
104 * <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread | |
105 * <li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID | |
106 * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object | |
107 * <li>ERROR_CANNOT_ACCESS_CLASSFACTORY when Class Factory could not be found | |
108 * <li>ERROR_CANNOT_CREATE_LICENSED_OBJECT when failed to create a licensed OLE Object | |
109 * </ul> | |
110 */ | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
128
diff
changeset
|
111 public this(Composite parent, int style, String progId) { |
97 | 112 super(parent, style); |
113 try { | |
114 | |
115 // check for licensing | |
116 appClsid = getClassID(progId); | |
98 | 117 if (appClsid is null) OLE.error(__FILE__, __LINE__, OLE.ERROR_INVALID_CLASSID); |
97 | 118 |
98 | 119 BSTR licinfo = getLicenseInfo(appClsid); |
120 if (licinfo is null) { | |
97 | 121 |
122 // Open a storage object | |
123 tempStorage = createTempStorage(); | |
124 | |
125 // Create ole object with storage object | |
98 | 126 HRESULT result = COM.OleCreate(appClsid, &COM.IIDIUnknown, COM.OLERENDER_DRAW, null, null, tempStorage, cast(void**)&objIUnknown); |
97 | 127 if (result !is COM.S_OK) |
98 | 128 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_OBJECT, result); |
97 | 129 |
130 } else { | |
131 // Prepare the ClassFactory | |
132 try { | |
98 | 133 IClassFactory2 classFactory; |
134 HRESULT result = COM.CoGetClassObject(appClsid, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, null, &COM.IIDIClassFactory2, cast(void**)&classFactory); | |
97 | 135 if (result !is COM.S_OK) { |
98 | 136 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_ACCESS_CLASSFACTORY, result); |
97 | 137 } |
138 // Create Com Object | |
98 | 139 result = classFactory.CreateInstanceLic(null, null, &COM.IIDIUnknown, licinfo, cast(void**)&objIUnknown); |
97 | 140 classFactory.Release(); |
141 if (result !is COM.S_OK) | |
98 | 142 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CREATE_LICENSED_OBJECT, result); |
97 | 143 } finally { |
144 COM.SysFreeString(licinfo); | |
145 } | |
146 | |
147 // Prepare a storage medium | |
98 | 148 IPersistStorage persist; |
149 if (objIUnknown.QueryInterface(&COM.IIDIPersistStorage, cast(void**)&persist) is COM.S_OK) { | |
97 | 150 tempStorage = createTempStorage(); |
98 | 151 persist.InitNew(tempStorage); |
97 | 152 persist.Release(); |
153 } | |
154 } | |
155 | |
156 // Init sinks | |
157 addObjectReferences(); | |
158 | |
159 // Init site properties | |
160 setSiteProperty(COM.DISPID_AMBIENT_USERMODE, new Variant(true)); | |
161 setSiteProperty(COM.DISPID_AMBIENT_UIDEAD, new Variant(false)); | |
162 | |
98 | 163 if (COM.OleRun(objIUnknown) is OLE.S_OK) state= STATE_RUNNING; |
97 | 164 |
165 } catch (DWTError e) { | |
166 dispose(); | |
167 disposeCOMInterfaces(); | |
168 throw e; | |
169 } | |
170 } | |
171 /** | |
172 * Adds the listener to receive events. | |
173 * | |
174 * @param eventID the id of the event | |
175 * | |
176 * @param listener the listener | |
177 * | |
178 * @exception IllegalArgumentException <ul> | |
179 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
180 * </ul> | |
181 */ | |
182 public void addEventListener(int eventID, OleListener listener) { | |
98 | 183 if (listener is null) OLE.error (__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
184 GUID* riid = getDefaultEventSinkGUID(objIUnknown); | |
97 | 185 if (riid !is null) { |
98 | 186 addEventListener(objIUnknown, riid, eventID, listener); |
97 | 187 } |
188 } | |
98 | 189 |
190 | |
191 static GUID* getDefaultEventSinkGUID(IUnknown unknown) { | |
97 | 192 // get Event Sink I/F from IProvideClassInfo2 |
98 | 193 IProvideClassInfo2 pci2; |
194 if (unknown.QueryInterface(&COM.IIDIProvideClassInfo2, cast(void**)&pci2) is COM.S_OK) { | |
195 GUID* riid = new GUID(); | |
196 HRESULT result = pci2.GetGUID(COM.GUIDKIND_DEFAULT_SOURCE_DISP_IID, riid); | |
97 | 197 pci2.Release(); |
198 if (result is COM.S_OK) return riid; | |
199 } | |
200 | |
201 // get Event Sink I/F from IProvideClassInfo | |
98 | 202 IProvideClassInfo pci; |
203 if (unknown.QueryInterface(&COM.IIDIProvideClassInfo, cast(void**)&pci) is COM.S_OK) { | |
204 ITypeInfo classInfo; | |
205 ITypeInfo eventInfo; | |
206 HRESULT result = pci.GetClassInfo(&classInfo); | |
97 | 207 pci.Release(); |
208 | |
98 | 209 if (result is COM.S_OK && classInfo !is null) { |
210 TYPEATTR* typeAttribute; | |
211 result = classInfo.GetTypeAttr(&typeAttribute); | |
212 if (result is COM.S_OK && typeAttribute !is null) { | |
97 | 213 int implMask = COM.IMPLTYPEFLAG_FDEFAULT | COM.IMPLTYPEFLAG_FSOURCE | COM.IMPLTYPEFLAG_FRESTRICTED; |
214 int implBits = COM.IMPLTYPEFLAG_FDEFAULT | COM.IMPLTYPEFLAG_FSOURCE; | |
215 | |
98 | 216 for (uint i = 0; i < typeAttribute.cImplTypes; i++) { |
217 int pImplTypeFlags; | |
218 if (classInfo.GetImplTypeFlags(i, &pImplTypeFlags) is COM.S_OK) { | |
219 if ((pImplTypeFlags & implMask) is implBits) { | |
220 uint pRefType; | |
221 if (classInfo.GetRefTypeOfImplType(i, &pRefType) is COM.S_OK) { | |
222 classInfo.GetRefTypeInfo(pRefType, &eventInfo); | |
97 | 223 } |
224 } | |
225 } | |
226 } | |
98 | 227 classInfo.ReleaseTypeAttr(typeAttribute); |
97 | 228 } |
229 classInfo.Release(); | |
230 | |
98 | 231 if (eventInfo !is null) { |
232 TYPEATTR* ppTypeAttr; | |
233 result = eventInfo.GetTypeAttr(&ppTypeAttr); | |
234 GUID* riid = null; | |
235 if (result is COM.S_OK && ppTypeAttr !is null) { | |
97 | 236 riid = new GUID(); |
98 | 237 *riid = ppTypeAttr.guid; |
238 eventInfo.ReleaseTypeAttr(ppTypeAttr); | |
97 | 239 } |
240 eventInfo.Release(); | |
241 return riid; | |
242 } | |
243 } | |
244 } | |
245 return null; | |
246 } | |
247 | |
248 /** | |
249 * Adds the listener to receive events. | |
250 * | |
251 * @since 2.0 | |
252 * | |
253 * @param automation the automation object that provides the event notification | |
254 * @param eventID the id of the event | |
255 * @param listener the listener | |
256 * | |
257 * @exception IllegalArgumentException <ul> | |
258 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
259 * </ul> | |
260 */ | |
261 public void addEventListener(OleAutomation automation, int eventID, OleListener listener) { | |
98 | 262 if (listener is null || automation is null) OLE.error (__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
263 IUnknown unknown = automation.getAddress(); | |
264 GUID* riid = getDefaultEventSinkGUID(unknown); | |
97 | 265 if (riid !is null) { |
98 | 266 addEventListener(unknown, riid, eventID, listener); |
97 | 267 } |
268 | |
269 } | |
270 /** | |
271 * Adds the listener to receive events. | |
272 * | |
273 * @since 3.2 | |
274 * | |
275 * @param automation the automation object that provides the event notification | |
276 * @param eventSinkId the GUID of the event sink | |
277 * @param eventID the id of the event | |
278 * @param listener the listener | |
279 * | |
280 * @exception IllegalArgumentException <ul> | |
281 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
282 * </ul> | |
283 */ | |
212
ab60f3309436
reverted the char[] to String and use the an alias.
Frank Benoit <benoit@tionex.de>
parents:
128
diff
changeset
|
284 public void addEventListener(OleAutomation automation, String eventSinkId, int eventID, OleListener listener) { |
98 | 285 if (listener is null || automation is null || eventSinkId is null) OLE.error (__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
286 auto address = automation.getAddress(); | |
287 if (address is null) return; | |
288 wchar[] buffer = StrToWCHARs(0,eventSinkId,true); | |
289 GUID* guid = new GUID(); | |
290 if (COM.IIDFromString(buffer.ptr, guid) !is COM.S_OK) return; | |
97 | 291 addEventListener(address, guid, eventID, listener); |
292 } | |
293 | |
98 | 294 void addEventListener(IUnknown iunknown, GUID* guid, int eventID, OleListener listener) { |
295 if (listener is null || iunknown is null || guid is null) OLE.error (__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); | |
97 | 296 // have we connected to this kind of event sink before? |
297 int index = -1; | |
298 for (int i = 0; i < oleEventSinkGUID.length; i++) { | |
299 if (COM.IsEqualGUID(oleEventSinkGUID[i], guid)) { | |
300 if (iunknown is oleEventSinkIUnknown[i]) { | |
301 index = i; | |
302 break; | |
303 } | |
304 } | |
305 } | |
306 if (index !is -1) { | |
307 oleEventSink[index].addListener(eventID, listener); | |
308 } else { | |
309 int oldLength = oleEventSink.length; | |
310 | |
98 | 311 oleEventSink ~= new OleEventSink(this, iunknown, guid); |
312 oleEventSinkGUID ~= guid; | |
313 oleEventSinkIUnknown ~= iunknown; | |
314 | |
97 | 315 oleEventSink[oldLength].AddRef(); |
316 oleEventSink[oldLength].connect(); | |
317 oleEventSink[oldLength].addListener(eventID, listener); | |
318 | |
319 } | |
320 } | |
321 protected void addObjectReferences() { | |
322 | |
323 super.addObjectReferences(); | |
324 | |
325 // Get property change notification from control | |
326 connectPropertyChangeSink(); | |
327 | |
328 // Get access to the Control object | |
98 | 329 IOleControl objIOleControl; |
330 if (objIUnknown.QueryInterface(&COM.IIDIOleControl, cast(void**)&objIOleControl) is COM.S_OK) { | |
97 | 331 // ask the control for its info in case users |
332 // need to act on it | |
333 currentControlInfo = new CONTROLINFO(); | |
334 objIOleControl.GetControlInfo(currentControlInfo); | |
335 objIOleControl.Release(); | |
336 } | |
337 } | |
338 /** | |
339 * Adds the listener to receive events. | |
340 * | |
341 * @param propertyID the identifier of the property | |
342 * @param listener the listener | |
343 * | |
344 * @exception IllegalArgumentException <ul> | |
345 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
346 * </ul> | |
347 */ | |
348 public void addPropertyListener(int propertyID, OleListener listener) { | |
98 | 349 if (listener is null) DWT.error (__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
97 | 350 olePropertyChangeSink.addListener(propertyID, listener); |
351 } | |
352 | |
353 private void connectPropertyChangeSink() { | |
354 olePropertyChangeSink = new OlePropertyChangeSink(this); | |
355 olePropertyChangeSink.AddRef(); | |
356 olePropertyChangeSink.connect(objIUnknown); | |
357 } | |
358 protected void createCOMInterfaces () { | |
359 super.createCOMInterfaces(); | |
98 | 360 iOleControlSite = new _IOleControlSiteImpl(this); |
361 iDispatch = new _IDispatchImpl(this); | |
97 | 362 } |
363 private void disconnectEventSinks() { | |
364 | |
365 for (int i = 0; i < oleEventSink.length; i++) { | |
366 OleEventSink sink = oleEventSink[i]; | |
367 sink.disconnect(); | |
368 sink.Release(); | |
369 } | |
98 | 370 oleEventSink = null; |
371 oleEventSinkGUID = null; | |
372 oleEventSinkIUnknown = null; | |
97 | 373 } |
374 private void disconnectPropertyChangeSink() { | |
375 | |
376 if (olePropertyChangeSink !is null) { | |
377 olePropertyChangeSink.disconnect(objIUnknown); | |
378 olePropertyChangeSink.Release(); | |
379 } | |
380 olePropertyChangeSink = null; | |
381 } | |
382 protected void disposeCOMInterfaces() { | |
383 super.disposeCOMInterfaces(); | |
384 iOleControlSite = null; | |
385 iDispatch = null; | |
386 } | |
387 public Color getBackground () { | |
388 | |
389 if (objIUnknown !is null) { | |
390 // !! We are getting the OLE_COLOR - should we change this to the COLORREF value? | |
391 OleAutomation oleObject= new OleAutomation(this); | |
392 Variant varBackColor = oleObject.getProperty(COM.DISPID_BACKCOLOR); | |
393 oleObject.dispose(); | |
394 | |
395 if (varBackColor !is null){ | |
98 | 396 COLORREF colorRef; |
397 if (COM.OleTranslateColor(varBackColor.getInt(), getDisplay().hPalette, &colorRef) is COM.S_OK) | |
398 return Color.win32_new(getDisplay(), colorRef); | |
97 | 399 } |
400 } | |
401 | |
402 return super.getBackground(); | |
403 } | |
404 public Font getFont () { | |
405 | |
406 if (objIUnknown !is null) { | |
407 OleAutomation oleObject= new OleAutomation(this); | |
408 Variant varDispFont = oleObject.getProperty(COM.DISPID_FONT); | |
409 oleObject.dispose(); | |
410 | |
411 if (varDispFont !is null){ | |
412 OleAutomation iDispFont = varDispFont.getAutomation(); | |
413 Variant lfFaceName = iDispFont.getProperty(COM.DISPID_FONT_NAME); | |
414 Variant lfHeight = iDispFont.getProperty(COM.DISPID_FONT_SIZE); | |
415 Variant lfItalic = iDispFont.getProperty(COM.DISPID_FONT_ITALIC); | |
416 //Variant lfCharSet = iDispFont.getProperty(COM.DISPID_FONT_CHARSET); | |
417 Variant lfBold = iDispFont.getProperty(COM.DISPID_FONT_BOLD); | |
418 iDispFont.dispose(); | |
419 | |
420 if (lfFaceName !is null && | |
421 lfHeight !is null && | |
422 lfItalic !is null && | |
423 lfBold !is null){ | |
424 int style = 3 * lfBold.getInt() + 2 * lfItalic.getInt(); | |
98 | 425 Device dev = getShell().getDisplay(); |
426 Font font = new Font(dev, lfFaceName.getString(), lfHeight.getInt(), style); | |
97 | 427 return font; |
428 } | |
429 } | |
430 } | |
431 | |
432 return super.getFont(); | |
433 } | |
434 public Color getForeground () { | |
435 | |
436 if (objIUnknown !is null) { | |
437 // !! We are getting the OLE_COLOR - should we change this to the COLORREF value? | |
438 OleAutomation oleObject= new OleAutomation(this); | |
439 Variant varForeColor = oleObject.getProperty(COM.DISPID_FORECOLOR); | |
440 oleObject.dispose(); | |
441 | |
442 if (varForeColor !is null){ | |
98 | 443 COLORREF colorRef; |
444 if (COM.OleTranslateColor(varForeColor.getInt(), getDisplay().hPalette, &colorRef) is COM.S_OK) | |
445 return Color.win32_new(getDisplay(), colorRef); | |
97 | 446 } |
447 } | |
448 | |
449 return super.getForeground(); | |
450 } | |
98 | 451 protected BSTR getLicenseInfo(GUID* clsid) { |
452 IClassFactory2 classFactory; | |
453 if (COM.CoGetClassObject(clsid, COM.CLSCTX_INPROC_HANDLER | COM.CLSCTX_INPROC_SERVER, null, &COM.IIDIClassFactory2, cast(void**)&classFactory) !is COM.S_OK) { | |
454 return null; | |
97 | 455 } |
98 | 456 LICINFO licinfo; |
457 if (classFactory.GetLicInfo(&licinfo) !is COM.S_OK) { | |
97 | 458 classFactory.Release(); |
98 | 459 return null; |
97 | 460 } |
98 | 461 BSTR pBstrKey; |
462 if (licinfo.fRuntimeKeyAvail) { | |
463 if (classFactory.RequestLicKey(0, &pBstrKey) is COM.S_OK) { | |
97 | 464 classFactory.Release(); |
98 | 465 return pBstrKey; |
97 | 466 } |
467 } | |
468 classFactory.Release(); | |
98 | 469 return null; |
97 | 470 } |
471 /** | |
472 * | |
246 | 473 * Get the control site property specified by the dispIdMember, or |
474 * <code>null</code> if the dispId is not recognised. | |
97 | 475 * |
246 | 476 * @param dispId the dispId |
477 * | |
478 * @return the property value or <code>null</code> | |
479 * | |
97 | 480 * @since 2.1 |
481 */ | |
482 public Variant getSiteProperty(int dispId){ | |
483 for (int i = 0; i < sitePropertyIds.length; i++) { | |
484 if (sitePropertyIds[i] is dispId) { | |
485 return sitePropertyValues[i]; | |
486 } | |
487 } | |
488 return null; | |
489 } | |
98 | 490 protected HRESULT GetWindow(HWND* phwnd) { |
97 | 491 |
98 | 492 if (phwnd is null) |
97 | 493 return COM.E_INVALIDARG; |
494 if (frame is null) { | |
98 | 495 *phwnd = null; |
97 | 496 return COM.E_NOTIMPL; |
497 } | |
498 | |
499 // Copy the Window's handle into the memory passed in | |
98 | 500 *phwnd = handle; |
97 | 501 return COM.S_OK; |
502 } | |
98 | 503 |
504 private HRESULT Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD dwFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult,EXCEPINFO* pExcepInfo,UINT* pArgErr) { | |
505 int nullv = 0; | |
506 if (pVarResult is null || dwFlags !is COM.DISPATCH_PROPERTYGET) { | |
507 if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); | |
508 if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); | |
97 | 509 return COM.DISP_E_MEMBERNOTFOUND; |
510 } | |
511 Variant result = getSiteProperty(dispIdMember); | |
512 if (result !is null) { | |
98 | 513 if (pVarResult !is null) result.getData(pVarResult); |
97 | 514 return COM.S_OK; |
515 } | |
516 switch (dispIdMember) { | |
517 // indicate a false result | |
518 case COM.DISPID_AMBIENT_SUPPORTSMNEMONICS : | |
519 case COM.DISPID_AMBIENT_SHOWGRABHANDLES : | |
520 case COM.DISPID_AMBIENT_SHOWHATCHING : | |
98 | 521 if (pVarResult !is null) COM.MoveMemory(pVarResult, &nullv, 4); |
522 if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); | |
523 if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); | |
97 | 524 return COM.S_FALSE; |
525 | |
526 // not implemented | |
527 case COM.DISPID_AMBIENT_OFFLINEIFNOTCONNECTED : | |
528 case COM.DISPID_AMBIENT_BACKCOLOR : | |
529 case COM.DISPID_AMBIENT_FORECOLOR : | |
530 case COM.DISPID_AMBIENT_FONT : | |
531 case COM.DISPID_AMBIENT_LOCALEID : | |
532 case COM.DISPID_AMBIENT_SILENT : | |
533 case COM.DISPID_AMBIENT_MESSAGEREFLECT : | |
98 | 534 if (pVarResult !is null) COM.MoveMemory(pVarResult, &nullv, 4); |
535 if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); | |
536 if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); | |
97 | 537 return COM.E_NOTIMPL; |
538 | |
539 default : | |
98 | 540 if (pVarResult !is null) COM.MoveMemory(pVarResult, &nullv, 4); |
541 if (pExcepInfo !is null) COM.MoveMemory(pExcepInfo, &nullv, 4); | |
542 if (pArgErr !is null) COM.MoveMemory(pArgErr, &nullv, 4); | |
97 | 543 return COM.DISP_E_MEMBERNOTFOUND; |
544 } | |
545 } | |
546 private int OnControlInfoChanged() { | |
98 | 547 IOleControl objIOleControl; |
548 if (objIUnknown.QueryInterface(&COM.IIDIOleControl, cast(void**)&objIOleControl ) is COM.S_OK) { | |
97 | 549 // ask the control for its info in case users |
550 // need to act on it | |
551 currentControlInfo = new CONTROLINFO(); | |
552 objIOleControl.GetControlInfo(currentControlInfo); | |
553 objIOleControl.Release(); | |
554 } | |
555 return COM.S_OK; | |
556 } | |
557 void onFocusIn(Event e) { | |
558 if (objIOleInPlaceObject is null) return; | |
559 doVerb(OLE.OLEIVERB_UIACTIVATE); | |
560 if (isFocusControl()) return; | |
98 | 561 HWND phwnd; |
562 objIOleInPlaceObject.GetWindow(&phwnd); | |
563 if (phwnd is null) return; | |
564 OS.SetFocus(phwnd); | |
97 | 565 } |
566 void onFocusOut(Event e) { | |
567 if (objIOleInPlaceObject !is null) { | |
568 /* | |
569 * Bug in Windows. When IE7 loses focus and UIDeactivate() | |
570 * is called, IE destroys the caret even though it is | |
571 * no longer owned by IE. If focus has moved to a control | |
572 * that shows a caret then the caret disappears. The fix | |
573 * is to detect this case and restore the caret. | |
574 */ | |
98 | 575 auto threadId = OS.GetCurrentThreadId(); |
576 GUITHREADINFO* lpgui1 = new GUITHREADINFO(); | |
97 | 577 lpgui1.cbSize = GUITHREADINFO.sizeof; |
578 OS.GetGUIThreadInfo(threadId, lpgui1); | |
579 objIOleInPlaceObject.UIDeactivate(); | |
98 | 580 if (lpgui1.hwndCaret !is null) { |
581 GUITHREADINFO* lpgui2 = new GUITHREADINFO(); | |
97 | 582 lpgui2.cbSize = GUITHREADINFO.sizeof; |
583 OS.GetGUIThreadInfo(threadId, lpgui2); | |
98 | 584 if (lpgui2.hwndCaret is null && lpgui1.hwndCaret is OS.GetFocus()) { |
97 | 585 if (SWT_RESTORECARET is 0) { |
98 | 586 SWT_RESTORECARET = OS.RegisterWindowMessage (StrToTCHARz (0, "SWT_RESTORECARET")); |
97 | 587 } |
588 /* | |
589 * If the caret was not restored by DWT, put it back using | |
590 * the information from GUITHREADINFO. Note that this will | |
591 * not be correct when the caret has a bitmap. There is no | |
592 * API to query the bitmap that the caret is using. | |
593 */ | |
594 if (OS.SendMessage (lpgui1.hwndCaret, SWT_RESTORECARET, 0, 0) is 0) { | |
98 | 595 int width = lpgui1.rcCaret.right - lpgui1.rcCaret.left; |
596 int height = lpgui1.rcCaret.bottom - lpgui1.rcCaret.top; | |
597 OS.CreateCaret (lpgui1.hwndCaret, null, width, height); | |
598 OS.SetCaretPos (lpgui1.rcCaret.left, lpgui1.rcCaret.top); | |
97 | 599 OS.ShowCaret (lpgui1.hwndCaret); |
600 } | |
601 } | |
602 } | |
603 } | |
604 } | |
605 private int OnFocus(int fGotFocus) { | |
606 return COM.S_OK; | |
607 } | |
608 protected int OnUIDeactivate(int fUndoable) { | |
609 // controls don't need to do anything for | |
610 // border space or menubars | |
611 state = STATE_INPLACEACTIVE; | |
612 return COM.S_OK; | |
613 } | |
98 | 614 override protected HRESULT QueryInterface(REFIID riid, void ** ppvObject) { |
615 int nullv = 0; | |
97 | 616 int result = super.QueryInterface(riid, ppvObject); |
617 if (result is COM.S_OK) | |
618 return result; | |
98 | 619 if (riid is null || ppvObject is null) |
97 | 620 return COM.E_INVALIDARG; |
289
d17d33bea6d0
Fix: indirection typo, thanks Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
284
diff
changeset
|
621 GUID oGuid = *riid; |
284
bb89fd34ec82
Fix for OLE functionality. Thanks to Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
622 GUID* guid = &oGuid; |
bb89fd34ec82
Fix for OLE functionality. Thanks to Enzo Petrelli
Frank Benoit <benoit@tionex.de>
parents:
246
diff
changeset
|
623 //COM.MoveMemory(&guid, riid, GUID.sizeof); |
98 | 624 if (COM.IsEqualGUID(guid, &COM.IIDIOleControlSite)) { |
625 *ppvObject = cast(void*)cast(IOleControlSite)iOleControlSite; | |
97 | 626 AddRef(); |
627 return COM.S_OK; | |
628 } | |
98 | 629 if (COM.IsEqualGUID(guid, &COM.IIDIDispatch)) { |
630 *ppvObject = cast(void*)cast(IDispatch)iDispatch; | |
97 | 631 AddRef(); |
632 return COM.S_OK; | |
633 } | |
98 | 634 *ppvObject = null; |
97 | 635 return COM.E_NOINTERFACE; |
636 } | |
637 protected int Release() { | |
638 int result = super.Release(); | |
639 if (result is 0) { | |
640 for (int i = 0; i < sitePropertyIds.length; i++) { | |
641 sitePropertyValues[i].dispose(); | |
642 } | |
98 | 643 sitePropertyIds = null; |
644 sitePropertyValues = null; | |
97 | 645 } |
646 return result; | |
647 } | |
648 protected void releaseObjectInterfaces() { | |
649 | |
650 disconnectEventSinks(); | |
651 | |
652 disconnectPropertyChangeSink(); | |
653 | |
654 super.releaseObjectInterfaces(); | |
655 } | |
656 /** | |
657 * Removes the listener. | |
658 * | |
659 * @param eventID the event identifier | |
660 * | |
246 | 661 * @param listener the listener which should no longer be notified |
97 | 662 * |
663 * @exception IllegalArgumentException <ul> | |
664 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
665 * </ul> | |
666 */ | |
667 public void removeEventListener(int eventID, OleListener listener) { | |
668 checkWidget(); | |
98 | 669 if (listener is null) DWT.error (__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
97 | 670 |
98 | 671 GUID* riid = getDefaultEventSinkGUID(objIUnknown); |
97 | 672 if (riid !is null) { |
98 | 673 removeEventListener(objIUnknown, riid, eventID, listener); |
97 | 674 } |
675 } | |
676 /** | |
677 * Removes the listener. | |
678 * | |
679 * @since 2.0 | |
680 * @deprecated - use OleControlSite.removeEventListener(OleAutomation, int, OleListener) | |
681 * | |
682 * @param automation the automation object that provides the event notification | |
683 * | |
684 * @param guid the identifier of the events COM interface | |
685 * | |
686 * @param eventID the event identifier | |
687 * | |
688 * @param listener the listener | |
689 * | |
690 * @exception IllegalArgumentException <ul> | |
691 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
692 * </ul> | |
693 */ | |
98 | 694 public void removeEventListener(OleAutomation automation, GUID* guid, int eventID, OleListener listener) { |
97 | 695 checkWidget(); |
98 | 696 if (automation is null || listener is null || guid is null) DWT.error ( __FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
97 | 697 removeEventListener(automation.getAddress(), guid, eventID, listener); |
698 } | |
699 /** | |
700 * Removes the listener. | |
701 * | |
702 * @param automation the automation object that provides the event notification | |
703 * @param eventID the event identifier | |
246 | 704 * @param listener the listener which should no longer be notified |
97 | 705 * |
706 * @exception IllegalArgumentException <ul> | |
707 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
708 * </ul> | |
246 | 709 * |
710 * @since 2.0 | |
97 | 711 */ |
712 public void removeEventListener(OleAutomation automation, int eventID, OleListener listener) { | |
713 checkWidget(); | |
98 | 714 if (automation is null || listener is null) DWT.error ( __FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
715 auto unknown = automation.getAddress(); | |
716 GUID* riid = getDefaultEventSinkGUID(unknown); | |
97 | 717 if (riid !is null) { |
98 | 718 removeEventListener(unknown, riid, eventID, listener); |
97 | 719 } |
720 } | |
98 | 721 void removeEventListener(IUnknown iunknown, GUID* guid, int eventID, OleListener listener) { |
722 if (listener is null || guid is null) DWT.error ( __FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); | |
97 | 723 for (int i = 0; i < oleEventSink.length; i++) { |
724 if (COM.IsEqualGUID(oleEventSinkGUID[i], guid)) { | |
725 if (iunknown is oleEventSinkIUnknown[i]) { | |
726 oleEventSink[i].removeListener(eventID, listener); | |
727 if (!oleEventSink[i].hasListeners()) { | |
728 //free resources associated with event sink | |
729 oleEventSink[i].disconnect(); | |
730 oleEventSink[i].Release(); | |
731 int oldLength = oleEventSink.length; | |
732 if (oldLength is 1) { | |
98 | 733 oleEventSink = null; |
734 oleEventSinkGUID = null; | |
735 oleEventSinkIUnknown = null; | |
97 | 736 } else { |
737 OleEventSink[] newOleEventSink = new OleEventSink[oldLength - 1]; | |
738 System.arraycopy(oleEventSink, 0, newOleEventSink, 0, i); | |
739 System.arraycopy(oleEventSink, i + 1, newOleEventSink, i, oldLength - i - 1); | |
740 oleEventSink = newOleEventSink; | |
741 | |
98 | 742 GUID*[] newOleEventSinkGUID = new GUID*[oldLength - 1]; |
743 SimpleType!(GUID*).arraycopy(oleEventSinkGUID, 0, newOleEventSinkGUID, 0, i); | |
744 SimpleType!(GUID*).arraycopy(oleEventSinkGUID, i + 1, newOleEventSinkGUID, i, oldLength - i - 1); | |
97 | 745 oleEventSinkGUID = newOleEventSinkGUID; |
746 | |
98 | 747 IUnknown[] newOleEventSinkIUnknown = new IUnknown[oldLength - 1]; |
748 SimpleType!(IUnknown).arraycopy(oleEventSinkIUnknown, 0, newOleEventSinkIUnknown, 0, i); | |
749 SimpleType!(IUnknown).arraycopy(oleEventSinkIUnknown, i + 1, newOleEventSinkIUnknown, i, oldLength - i - 1); | |
97 | 750 oleEventSinkIUnknown = newOleEventSinkIUnknown; |
751 } | |
752 } | |
753 return; | |
754 } | |
755 } | |
756 } | |
757 } | |
758 /** | |
759 * Removes the listener. | |
760 * | |
246 | 761 * @param propertyID the identifier of the property |
762 * @param listener the listener which should no longer be notified | |
97 | 763 * |
764 * @exception IllegalArgumentException <ul> | |
765 * <li>ERROR_NULL_ARGUMENT when listener is null</li> | |
766 * </ul> | |
767 */ | |
768 public void removePropertyListener(int propertyID, OleListener listener) { | |
98 | 769 if (listener is null) DWT.error (__FILE__, __LINE__, DWT.ERROR_NULL_ARGUMENT); |
97 | 770 olePropertyChangeSink.removeListener(propertyID, listener); |
771 } | |
772 public void setBackground (Color color) { | |
773 | |
774 super.setBackground(color); | |
775 | |
776 //set the background of the ActiveX Control | |
777 if (objIUnknown !is null) { | |
778 OleAutomation oleObject= new OleAutomation(this); | |
98 | 779 oleObject.setProperty(COM.DISPID_BACKCOLOR, new Variant(cast(int)color.handle)); |
97 | 780 oleObject.dispose(); |
781 } | |
782 } | |
783 public void setFont (Font font) { | |
784 | |
785 super.setFont(font); | |
786 | |
787 //set the font of the ActiveX Control | |
788 if (objIUnknown !is null) { | |
789 | |
790 OleAutomation oleObject= new OleAutomation(this); | |
791 Variant varDispFont = oleObject.getProperty(COM.DISPID_FONT); | |
792 oleObject.dispose(); | |
793 | |
794 if (varDispFont !is null){ | |
795 OleAutomation iDispFont = varDispFont.getAutomation(); | |
796 FontData[] fdata = font.getFontData(); | |
797 iDispFont.setProperty(COM.DISPID_FONT_NAME, new Variant(fdata[0].getName())); | |
798 iDispFont.setProperty(COM.DISPID_FONT_SIZE, new Variant(fdata[0].getHeight())); | |
799 iDispFont.setProperty(COM.DISPID_FONT_ITALIC, new Variant(fdata[0].getStyle() & DWT.ITALIC)); | |
800 //iDispFont.setProperty(COM.DISPID_FONT_CHARSET, new Variant(fdata[0].getCharset)); | |
801 iDispFont.setProperty(COM.DISPID_FONT_BOLD, new Variant((fdata[0].getStyle() & DWT.BOLD))); | |
802 iDispFont.dispose(); | |
803 } | |
804 } | |
805 | |
806 return; | |
807 } | |
808 public void setForeground (Color color) { | |
809 | |
810 super.setForeground(color); | |
811 | |
812 //set the foreground of the ActiveX Control | |
813 if (objIUnknown !is null) { | |
814 OleAutomation oleObject= new OleAutomation(this); | |
98 | 815 oleObject.setProperty(COM.DISPID_FORECOLOR, new Variant(cast(int)color.handle)); |
97 | 816 oleObject.dispose(); |
817 } | |
818 } | |
819 /** | |
820 * Sets the control site property specified by the dispIdMember to a new value. | |
821 * The value will be disposed by the control site when it is no longer required | |
822 * using Variant.dispose. Passing a value of null will clear the dispId value. | |
823 * | |
824 * @param dispId the ID of the property as specified by the IDL of the ActiveX Control | |
825 * @param value The new value for the property as expressed in a Variant. | |
826 * | |
827 * @since 2.1 | |
828 */ | |
829 public void setSiteProperty(int dispId, Variant value){ | |
830 for (int i = 0; i < sitePropertyIds.length; i++) { | |
831 if (sitePropertyIds[i] is dispId) { | |
832 if (sitePropertyValues[i] !is null) { | |
833 sitePropertyValues[i].dispose(); | |
834 } | |
835 if (value !is null) { | |
836 sitePropertyValues[i] = value; | |
837 } else { | |
838 int oldLength = sitePropertyIds.length; | |
839 int[] newSitePropertyIds = new int[oldLength - 1]; | |
840 Variant[] newSitePropertyValues = new Variant[oldLength - 1]; | |
841 System.arraycopy(sitePropertyIds, 0, newSitePropertyIds, 0, i); | |
842 System.arraycopy(sitePropertyIds, i + 1, newSitePropertyIds, i, oldLength - i - 1); | |
843 System.arraycopy(sitePropertyValues, 0, newSitePropertyValues, 0, i); | |
844 System.arraycopy(sitePropertyValues, i + 1, newSitePropertyValues, i, oldLength - i - 1); | |
845 sitePropertyIds = newSitePropertyIds; | |
846 sitePropertyValues = newSitePropertyValues; | |
847 } | |
848 return; | |
849 } | |
850 } | |
851 int oldLength = sitePropertyIds.length; | |
852 int[] newSitePropertyIds = new int[oldLength + 1]; | |
853 Variant[] newSitePropertyValues = new Variant[oldLength + 1]; | |
854 System.arraycopy(sitePropertyIds, 0, newSitePropertyIds, 0, oldLength); | |
855 System.arraycopy(sitePropertyValues, 0, newSitePropertyValues, 0, oldLength); | |
856 newSitePropertyIds[oldLength] = dispId; | |
857 newSitePropertyValues[oldLength] = value; | |
858 sitePropertyIds = newSitePropertyIds; | |
859 sitePropertyValues = newSitePropertyValues; | |
860 } | |
861 } | |
98 | 862 |
863 class _IDispatchImpl : IDispatch { | |
864 | |
865 OleControlSite parent; | |
866 this(OleControlSite p) { parent = p; } | |
867 extern (Windows): | |
868 // interface of IUnknown | |
869 HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } | |
870 ULONG AddRef() { return parent.AddRef(); } | |
871 ULONG Release() { return parent.Release(); } | |
872 | |
873 // interface of IDispatch : IUnknown | |
874 HRESULT GetTypeInfoCount(UINT * pctinfo) { return COM.E_NOTIMPL; } | |
875 HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo * ppTInfo) { return COM.E_NOTIMPL; } | |
876 HRESULT GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgDispId) { return COM.E_NOTIMPL; } | |
877 // Note : <Shawn> one argument is short !!! | |
878 HRESULT Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS* pDispParams,VARIANT* pVarResult,EXCEPINFO* pExcepInfo,UINT* puArgErr) { | |
879 return parent.Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); | |
880 } | |
881 } | |
882 | |
883 class _IOleControlSiteImpl : IOleControlSite { | |
884 | |
885 OleControlSite parent; | |
886 this(OleControlSite p) { parent = p; } | |
887 extern (Windows): | |
888 // interface of IUnknown | |
889 HRESULT QueryInterface(REFIID riid, void ** ppvObject) { return parent.QueryInterface(riid, ppvObject); } | |
890 ULONG AddRef() { return parent.AddRef(); } | |
891 ULONG Release() { return parent.Release(); } | |
892 | |
893 // interface IOleControlSite : IUnknown | |
894 HRESULT OnControlInfoChanged() { return parent.OnControlInfoChanged();} | |
895 HRESULT LockInPlaceActive(BOOL fLock) { return COM.E_NOTIMPL; } | |
896 HRESULT GetExtendedControl(LPDISPATCH* ppDisp) { return COM.E_NOTIMPL; } | |
897 HRESULT TransformCoords( | |
128
07e8963537b7
removed tango_sys_win32 and added all necessary bindings to the dwt.internal.win32 WINTYPES and WINAPI modules
Frank Benoit <benoit@tionex.de>
parents:
98
diff
changeset
|
898 POINTL* pPtlHimetric , //Address of POINTL structure |
98 | 899 POINTF* pPtfContainer , //Address of POINTF structure |
900 DWORD dwFlags //Flags indicating the exact conversion | |
901 ) { return COM.E_NOTIMPL; } | |
902 HRESULT TranslateAccelerator( | |
903 LPMSG pMsg , //Pointer to the structure | |
904 DWORD grfModifiers //Flags describing the state of the keys | |
905 ) | |
906 { return COM.E_NOTIMPL; } | |
907 HRESULT OnFocus( | |
908 BOOL fGotFocus //Indicates whether the control gained focus | |
909 ) | |
910 { return COM.S_OK; } | |
911 HRESULT ShowPropertyFrame() { return COM.E_NOTIMPL; } | |
912 } | |
913 | |
914 | |
915 |