Mercurial > projects > dwt2
comparison org.eclipse.swt.win32.win32.x86/src/org/eclipse/swt/ole/win32/Variant.d @ 0:6dd524f61e62
add dwt win and basic java stuff
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 02 Mar 2009 14:44:16 +0100 |
parents | |
children | 6bf2837c50fe |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:6dd524f61e62 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.swt.ole.win32.Variant; | |
14 | |
15 import org.eclipse.swt.SWT; | |
16 import org.eclipse.swt.SWTException; | |
17 import org.eclipse.swt.internal.ole.win32.extras; | |
18 import org.eclipse.swt.internal.ole.win32.COM; | |
19 import org.eclipse.swt.internal.ole.win32.COMTYPES; | |
20 import org.eclipse.swt.internal.ole.win32.OAIDL; | |
21 import org.eclipse.swt.internal.win32.OS; | |
22 | |
23 import org.eclipse.swt.ole.win32.OleAutomation; | |
24 import org.eclipse.swt.ole.win32.OLE; | |
25 | |
26 import tango.util.Convert; | |
27 import tango.text.convert.Format; | |
28 import java.lang.all; | |
29 | |
30 /** | |
31 * | |
32 * A Variant is a generic OLE mechanism for passing data of different types via a common interface. | |
33 * | |
34 * <p>It is used within the OleAutomation object for getting a property, setting a property or invoking | |
35 * a method on an OLE Control or OLE Document. | |
36 * | |
37 */ | |
38 public final class Variant { | |
39 /** | |
40 * The size in bytes of a native VARIANT struct. | |
41 */ | |
42 /** | |
43 * A variant always takes up 16 bytes, no matter what you | |
44 * store in it. Objects, strings, and arrays are not physically | |
45 * stored in the Variant; in these cases, four bytes of the | |
46 * Variant are used to hold either an object reference, or a | |
47 * pointer to the string or array. The actual data are stored elsewhere. | |
48 */ | |
49 //public static final int sizeof = 16; | |
50 | |
51 | |
52 private short type; // OLE.VT_* type | |
53 private bool booleanData; | |
54 private byte byteData; | |
55 private short shortData; | |
56 private wchar charData; | |
57 private int intData; | |
58 private long longData; | |
59 private float floatData; | |
60 private double doubleData; | |
61 private String stringData; | |
62 private void* byRefPtr; | |
63 private IDispatch dispatchData; | |
64 private IUnknown unknownData; | |
65 | |
66 /** | |
67 * Invokes platform specific functionality to copy a variant | |
68 * into operating system memory. | |
69 * <p> | |
70 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
71 * API for <code>Variant</code>. It is marked public only so that it | |
72 * can be shared within the packages provided by SWT. It is not | |
73 * available on all platforms, and should never be called from | |
74 * application code. | |
75 * </p> | |
76 * | |
77 * @param pVarDest destination pointer to a variant | |
78 * @param varSrc source <code>Variant</code> | |
79 * | |
80 * @since 3.3 | |
81 */ | |
82 public static void win32_copy (VARIANT* pVarDest, Variant varSrc) { | |
83 varSrc.getData (pVarDest); | |
84 } | |
85 | |
86 /** | |
87 * Invokes platform specific functionality to wrap a variant | |
88 * that was allocated in operating system memory. | |
89 * <p> | |
90 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
91 * API for <code>Variant</code>. It is marked public only so that it | |
92 * can be shared within the packages provided by SWT. It is not | |
93 * available on all platforms, and should never be called from | |
94 * application code. | |
95 * </p> | |
96 * | |
97 * @param pVariant pointer to a variant | |
98 * | |
99 * @return a new <code>Variant</code> | |
100 * | |
101 * @since 3.3 | |
102 */ | |
103 public static Variant win32_new (VARIANT* pVariant) { | |
104 Variant variant = new Variant (); | |
105 variant.setData (pVariant); | |
106 return variant; | |
107 } | |
108 | |
109 /** | |
110 * Create an empty Variant object with type VT_EMPTY. | |
111 * | |
112 * @since 2.0 | |
113 */ | |
114 public this(){ | |
115 type = COM.VT_EMPTY; | |
116 } | |
117 /** | |
118 * Create a Variant object which represents a Java float as a VT_R4. | |
119 * | |
120 * @param val the Java float value that this Variant represents | |
121 * | |
122 */ | |
123 public this(float val) { | |
124 type = COM.VT_R4; | |
125 floatData = val; | |
126 | |
127 } | |
128 /** | |
129 * Create a Variant object which represents a Java double as a VT_R8. | |
130 * | |
131 * @param val the Java double value that this Variant represents | |
132 * | |
133 * @since 3.2 | |
134 */ | |
135 public this(double val) { | |
136 type = COM.VT_R8; | |
137 doubleData = val; | |
138 } | |
139 /** | |
140 * Create a Variant object which represents a Java int as a VT_I4. | |
141 * | |
142 * @param val the Java int value that this Variant represents | |
143 * | |
144 */ | |
145 public this(int val) { | |
146 type = COM.VT_I4; | |
147 intData = val; | |
148 } | |
149 public this(uint val) { | |
150 type = COM.VT_I4; | |
151 intData = val; | |
152 } | |
153 /** | |
154 * Create a Variant object which contains a reference to the data being transferred. | |
155 * | |
156 * <p>When creating a VT_BYREF Variant, you must give the full Variant type | |
157 * including VT_BYREF such as | |
158 * | |
159 * <pre><code>short byRefType = OLE.VT_BSTR | OLE.VT_BYREF</code></pre>. | |
160 * | |
161 * @param ptr a pointer to the data being transferred. | |
162 * @param byRefType the type of the data being transferred such as OLE.VT_BSTR | OLE.VT_BYREF | |
163 * | |
164 */ | |
165 public this(void* ptr, ushort byRefType) { | |
166 type = byRefType; | |
167 byRefPtr = ptr; | |
168 } | |
169 /** | |
170 * Create a Variant object which represents an IDispatch interface as a VT_Dispatch. | |
171 * | |
172 * @param automation the OleAutomation object that this Variant represents | |
173 * | |
174 */ | |
175 public this(OleAutomation automation) { | |
176 type = COM.VT_DISPATCH; | |
177 dispatchData = automation.getAddress(); | |
178 } | |
179 /** | |
180 * Create a Variant object which represents an IDispatch interface as a VT_Dispatch. | |
181 * <p>The caller is expected to have appropriately invoked unknown.AddRef() before creating | |
182 * this Variant. | |
183 * | |
184 * @since 2.0 | |
185 * | |
186 * @param idispatch the IDispatch object that this Variant represents | |
187 * | |
188 */ | |
189 public this(IDispatch idispatch) { | |
190 type = COM.VT_DISPATCH; | |
191 dispatchData = idispatch; | |
192 } | |
193 /** | |
194 * Create a Variant object which represents an IUnknown interface as a VT_UNKNOWN. | |
195 * | |
196 * <p>The caller is expected to have appropriately invoked unknown.AddRef() before creating | |
197 * this Variant. | |
198 * | |
199 * @param unknown the IUnknown object that this Variant represents | |
200 * | |
201 */ | |
202 public this(IUnknown unknown) { | |
203 type = COM.VT_UNKNOWN; | |
204 unknownData = unknown; | |
205 } | |
206 /** | |
207 * Create a Variant object which represents a Java long as a VT_I8. | |
208 * | |
209 * @param val the Java long value that this Variant represents | |
210 * | |
211 * @since 3.2 | |
212 */ | |
213 public this(long val) { | |
214 type = COM.VT_I8; | |
215 longData = val; | |
216 } | |
217 /** | |
218 * Create a Variant object which represents a Java String as a VT_BSTR. | |
219 * | |
220 * @param string the Java String value that this Variant represents | |
221 * | |
222 */ | |
223 public this(String string) { | |
224 type = COM.VT_BSTR; | |
225 stringData = string; | |
226 } | |
227 /** | |
228 * Create a Variant object which represents a Java short as a VT_I2. | |
229 * | |
230 * @param val the Java short value that this Variant represents | |
231 * | |
232 */ | |
233 public this(short val) { | |
234 type = COM.VT_I2; | |
235 shortData = val; | |
236 } | |
237 /** | |
238 * Create a Variant object which represents a Java bool as a VT_BOOL. | |
239 * | |
240 * @param val the Java bool value that this Variant represents | |
241 * | |
242 */ | |
243 public this(bool val) { | |
244 type = COM.VT_BOOL; | |
245 booleanData = val; | |
246 } | |
247 | |
248 /** | |
249 * Calling dispose will release resources associated with this Variant. | |
250 * If the resource is an IDispatch or IUnknown interface, Release will be called. | |
251 * If the resource is a ByRef pointer, nothing is released. | |
252 * | |
253 * @since 2.1 | |
254 */ | |
255 public void dispose() { | |
256 if ((type & COM.VT_BYREF) is COM.VT_BYREF) { | |
257 return; | |
258 } | |
259 | |
260 switch (type) { | |
261 case COM.VT_DISPATCH : | |
262 dispatchData.Release(); | |
263 break; | |
264 case COM.VT_UNKNOWN : | |
265 unknownData.Release(); | |
266 break; | |
267 default: | |
268 } | |
269 | |
270 } | |
271 /** | |
272 * Returns the OleAutomation object represented by this Variant. | |
273 * | |
274 * <p>If this Variant does not contain an OleAutomation object, an attempt is made to | |
275 * coerce the Variant type into an OleAutomation object. If this fails, an error is | |
276 * thrown. Note that OleAutomation objects must be disposed when no longer | |
277 * needed. | |
278 * | |
279 * @return the OleAutomation object represented by this Variant | |
280 * | |
281 * @exception SWTException <ul> | |
282 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an OleAutomation object</li> | |
283 * </ul> | |
284 */ | |
285 public OleAutomation getAutomation() { | |
286 if (type is COM.VT_EMPTY) { | |
287 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
288 } | |
289 if (type is COM.VT_DISPATCH) { | |
290 return new OleAutomation(dispatchData); | |
291 } | |
292 // try to coerce the value to the desired type | |
293 VARIANT oldPtr, newPtr; | |
294 try { | |
295 getData(&oldPtr); | |
296 HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_DISPATCH); | |
297 if (result !is COM.S_OK) | |
298 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
299 Variant autoVar = new Variant(); | |
300 autoVar.setData(&newPtr); | |
301 return autoVar.getAutomation(); | |
302 } finally { | |
303 COM.VariantClear(&oldPtr); | |
304 COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the | |
305 // OleAutomation object is created as Variant Clear | |
306 // will result in a Release being performed on the | |
307 // Dispatch object | |
308 } | |
309 } | |
310 /** | |
311 * Returns the IDispatch object represented by this Variant. | |
312 * | |
313 * <p>If this Variant does not contain an IDispatch object, an attempt is made to | |
314 * coerce the Variant type into an IDIspatch object. If this fails, an error is | |
315 * thrown. | |
316 * | |
317 * @since 2.0 | |
318 * | |
319 * @return the IDispatch object represented by this Variant | |
320 * | |
321 * @exception SWTException <ul> | |
322 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an IDispatch object</li> | |
323 * </ul> | |
324 */ | |
325 public IDispatch getDispatch() { | |
326 if (type is COM.VT_EMPTY) { | |
327 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
328 } | |
329 | |
330 if (type is COM.VT_DISPATCH) { | |
331 return dispatchData; | |
332 } | |
333 // try to coerce the value to the desired type | |
334 VARIANT oldPtr, newPtr; | |
335 try { | |
336 getData(&oldPtr); | |
337 HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_DISPATCH); | |
338 if (result !is COM.S_OK) | |
339 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
340 Variant autoVar = new Variant(); | |
341 autoVar.setData(&newPtr); | |
342 return autoVar.getDispatch(); | |
343 } finally { | |
344 COM.VariantClear(&oldPtr); | |
345 COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the | |
346 // OleAutomation object is created as Variant Clear | |
347 // will result in a Release being performed on the | |
348 // Dispatch object | |
349 } | |
350 } | |
351 /** | |
352 * Returns the Java bool represented by this Variant. | |
353 * | |
354 * <p>If this Variant does not contain a Java bool, an attempt is made to | |
355 * coerce the Variant type into a Java bool. If this fails, an error is thrown. | |
356 * | |
357 * @return the Java bool represented by this Variant | |
358 * | |
359 * @exception SWTException <ul> | |
360 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a bool</li> | |
361 * </ul> | |
362 * | |
363 */ | |
364 public bool getBoolean() { | |
365 if (type is COM.VT_EMPTY) { | |
366 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
367 } | |
368 if (type is COM.VT_BOOL) { | |
369 return booleanData; | |
370 } | |
371 // try to coerce the value to the desired type | |
372 VARIANT oldPtr, newPtr; | |
373 try { | |
374 getData(&oldPtr); | |
375 HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_BOOL); | |
376 if (result !is COM.S_OK) | |
377 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
378 Variant boolVar = new Variant(); | |
379 boolVar.setData(&newPtr); | |
380 return boolVar.getBoolean(); | |
381 } finally { | |
382 COM.VariantClear(&oldPtr); | |
383 COM.VariantClear(&newPtr); | |
384 } | |
385 } | |
386 /** | |
387 * Returns a pointer to the referenced data represented by this Variant. | |
388 * | |
389 * <p>If this Variant does not contain a reference to data, zero is returned. | |
390 * | |
391 * @return a pointer to the referenced data represented by this Variant or 0 | |
392 * | |
393 */ | |
394 public void* getByRef() { | |
395 if (type is COM.VT_EMPTY) { | |
396 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
397 } | |
398 if ((type & COM.VT_BYREF)is COM.VT_BYREF) { | |
399 return byRefPtr; | |
400 } | |
401 | |
402 return null; | |
403 } | |
404 /** | |
405 * Returns the Java byte represented by this Variant. | |
406 * | |
407 * <p>If this Variant does not contain a Java byte, an attempt is made to | |
408 * coerce the Variant type into a Java byte. If this fails, an error is thrown. | |
409 * | |
410 * @return the Java byte represented by this Variant | |
411 * | |
412 * @exception SWTException <ul> | |
413 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a byte</li> | |
414 * </ul> | |
415 * | |
416 * @since 3.3 | |
417 */ | |
418 public byte getByte() { | |
419 if (type is COM.VT_EMPTY) { | |
420 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
421 } | |
422 if (type is COM.VT_I1) { | |
423 return byteData; | |
424 } | |
425 | |
426 // try to coerce the value to the desired type | |
427 VARIANT oldPtr, newPtr; | |
428 try { | |
429 getData(&oldPtr); | |
430 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I1); | |
431 if (result !is COM.S_OK) | |
432 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
433 Variant byteVar = new Variant(); | |
434 byteVar.setData(&newPtr); | |
435 return byteVar.getByte(); | |
436 } finally { | |
437 COM.VariantClear(&oldPtr); | |
438 COM.VariantClear(&newPtr); | |
439 } | |
440 } | |
441 /** | |
442 * Returns the Java char represented by this Variant. | |
443 * | |
444 * <p>If this Variant does not contain a Java char, an attempt is made to | |
445 * coerce the Variant type into a Java char. If this fails, an error is thrown. | |
446 * | |
447 * @return the Java char represented by this Variant | |
448 * | |
449 * @exception SWTException <ul> | |
450 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a char</li> | |
451 * </ul> | |
452 * | |
453 * @since 3.3 | |
454 */ | |
455 public wchar getChar() { | |
456 if (type is COM.VT_EMPTY) { | |
457 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
458 } | |
459 if (type is COM.VT_UI2) { | |
460 return charData; | |
461 } | |
462 | |
463 // try to coerce the value to the desired type | |
464 VARIANT oldPtr, newPtr; | |
465 try { | |
466 getData(&oldPtr); | |
467 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_UI2); | |
468 if (result !is COM.S_OK) | |
469 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
470 Variant charVar = new Variant(); | |
471 charVar.setData(&newPtr); | |
472 return charVar.getChar(); | |
473 } finally { | |
474 COM.VariantClear(&oldPtr); | |
475 COM.VariantClear(&newPtr); | |
476 } | |
477 } | |
478 void getData(VARIANT* pData){ | |
479 if (pData is null) OLE.error(OLE.ERROR_OUT_OF_MEMORY); | |
480 | |
481 COM.VariantInit(pData); | |
482 | |
483 // set type | |
484 pData.vt = type; | |
485 if ((type & COM.VT_BYREF) is COM.VT_BYREF) { | |
486 COM.MoveMemory((cast(void*)pData), &type, 2); | |
487 COM.MoveMemory((cast(void*)pData) + 8, &byRefPtr, 4); | |
488 return; | |
489 } | |
490 | |
491 switch (type) { | |
492 case COM.VT_EMPTY : | |
493 case COM.VT_NULL : | |
494 COM.MoveMemory((cast(void*)pData), &type, 2); | |
495 break; | |
496 case COM.VT_BOOL : | |
497 COM.MoveMemory((cast(void*)pData), &type, 2); | |
498 auto v = booleanData ? COM.VARIANT_TRUE : COM.VARIANT_FALSE; | |
499 COM.MoveMemory((cast(void*)pData) + 8, &v, 2); | |
500 break; | |
501 case COM.VT_I1 : | |
502 COM.MoveMemory((cast(void*)pData), &type, 2); | |
503 COM.MoveMemory((cast(void*)pData) + 8, &byteData, 1); | |
504 break; | |
505 case COM.VT_I2 : | |
506 COM.MoveMemory((cast(void*)pData), &type, 2); | |
507 COM.MoveMemory((cast(void*)pData) + 8, &shortData, 2); | |
508 break; | |
509 case COM.VT_UI2 : | |
510 COM.MoveMemory((cast(void*)pData), &type, 2); | |
511 COM.MoveMemory((cast(void*)pData) + 8, &charData, 2); | |
512 break; | |
513 case COM.VT_I4 : | |
514 COM.MoveMemory((cast(void*)pData), &type, 2); | |
515 COM.MoveMemory((cast(void*)pData) + 8, &intData, 4); | |
516 break; | |
517 case COM.VT_I8 : | |
518 COM.MoveMemory((cast(void*)pData), &type, 2); | |
519 COM.MoveMemory((cast(void*)pData) + 8, &longData, 8); | |
520 break; | |
521 case COM.VT_R4 : | |
522 COM.MoveMemory((cast(void*)pData), &type, 2); | |
523 COM.MoveMemory((cast(void*)pData) + 8, &floatData, 4); | |
524 break; | |
525 case COM.VT_R8 : | |
526 COM.MoveMemory((cast(void*)pData), &type, 2); | |
527 COM.MoveMemory((cast(void*)pData) + 8, &doubleData, 8); | |
528 break; | |
529 case COM.VT_DISPATCH : | |
530 dispatchData.AddRef(); | |
531 COM.MoveMemory((cast(void*)pData), &type, 2); | |
532 auto v = cast(void*)dispatchData; | |
533 COM.MoveMemory((cast(void*)pData) + 8, &v, 4); | |
534 break; | |
535 case COM.VT_UNKNOWN : | |
536 unknownData.AddRef(); | |
537 COM.MoveMemory((cast(void*)pData), &type, 2); | |
538 auto v = cast(void*)dispatchData; | |
539 COM.MoveMemory((cast(void*)pData) + 8, &v, 4); | |
540 break; | |
541 case COM.VT_BSTR : | |
542 COM.MoveMemory((cast(void*)pData), &type, 2); | |
543 wchar[] data = StrToWCHARs(stringData); | |
544 auto ptr = COM.SysAllocString(data.ptr); | |
545 COM.MoveMemory((cast(void*)pData) + 8, &ptr, 4); | |
546 break; | |
547 | |
548 default : | |
549 OLE.error(SWT.ERROR_NOT_IMPLEMENTED); | |
550 } | |
551 } | |
552 /** | |
553 * Returns the Java double represented by this Variant. | |
554 * | |
555 * <p>If this Variant does not contain a Java double, an attempt is made to | |
556 * coerce the Variant type into a Java double. If this fails, an error is thrown. | |
557 * | |
558 * @return the Java double represented by this Variant | |
559 * | |
560 * @exception SWTException <ul> | |
561 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a double</li> | |
562 * </ul> | |
563 * | |
564 * @since 3.2 | |
565 */ | |
566 public double getDouble() { | |
567 if (type is COM.VT_EMPTY) { | |
568 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
569 } | |
570 if (type is COM.VT_R8) { | |
571 return doubleData; | |
572 } | |
573 | |
574 // try to coerce the value to the desired type | |
575 VARIANT oldPtr, newPtr; | |
576 try { | |
577 getData(&oldPtr); | |
578 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_R8); | |
579 if (result !is COM.S_OK) | |
580 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
581 Variant doubleVar = new Variant(); | |
582 doubleVar.setData(&newPtr); | |
583 return doubleVar.getDouble(); | |
584 } finally { | |
585 COM.VariantClear(&oldPtr); | |
586 COM.VariantClear(&newPtr); | |
587 } | |
588 } | |
589 | |
590 /** | |
591 * Returns the Java float represented by this Variant. | |
592 * | |
593 * <p>If this Variant does not contain a Java float, an attempt is made to | |
594 * coerce the Variant type into a Java float. If this fails, an error is thrown. | |
595 * | |
596 * @return the Java float represented by this Variant | |
597 * | |
598 * @exception SWTException <ul> | |
599 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a float</li> | |
600 * </ul> | |
601 */ | |
602 public float getFloat() { | |
603 if (type is COM.VT_EMPTY) { | |
604 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
605 } | |
606 if (type is COM.VT_R4) { | |
607 return floatData; | |
608 } | |
609 | |
610 // try to coerce the value to the desired type | |
611 VARIANT oldPtr, newPtr; | |
612 try { | |
613 getData(&oldPtr); | |
614 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_R4); | |
615 if (result !is COM.S_OK) | |
616 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
617 Variant floatVar = new Variant(); | |
618 floatVar.setData(&newPtr); | |
619 return floatVar.getFloat(); | |
620 } finally { | |
621 COM.VariantClear(&oldPtr); | |
622 COM.VariantClear(&newPtr); | |
623 } | |
624 | |
625 } | |
626 /** | |
627 * Returns the Java int represented by this Variant. | |
628 * | |
629 * <p>If this Variant does not contain a Java int, an attempt is made to | |
630 * coerce the Variant type into a Java int. If this fails, an error is thrown. | |
631 * | |
632 * @return the Java int represented by this Variant | |
633 * | |
634 * @exception SWTException <ul> | |
635 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a int</li> | |
636 * </ul> | |
637 */ | |
638 public int getInt() { | |
639 if (type is COM.VT_EMPTY) { | |
640 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
641 } | |
642 if (type is COM.VT_I4) { | |
643 return intData; | |
644 } | |
645 | |
646 // try to coerce the value to the desired type | |
647 VARIANT oldPtr, newPtr; | |
648 try { | |
649 getData(&oldPtr); | |
650 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I4); | |
651 if (result !is COM.S_OK) | |
652 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
653 Variant intVar = new Variant(); | |
654 intVar.setData(&newPtr); | |
655 return intVar.getInt(); | |
656 } finally { | |
657 COM.VariantClear(&oldPtr); | |
658 COM.VariantClear(&newPtr); | |
659 } | |
660 } | |
661 /** | |
662 * Returns the Java long represented by this Variant. | |
663 * | |
664 * <p>If this Variant does not contain a Java long, an attempt is made to | |
665 * coerce the Variant type into a Java long. If this fails, an error is thrown. | |
666 * | |
667 * @return the Java long represented by this Variant | |
668 * | |
669 * @exception SWTException <ul> | |
670 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a long</li> | |
671 * </ul> | |
672 * | |
673 * @since 3.2 | |
674 */ | |
675 public long getLong() { | |
676 if (type is COM.VT_EMPTY) { | |
677 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
678 } | |
679 if (type is COM.VT_I8) { | |
680 return longData; | |
681 } | |
682 | |
683 // try to coerce the value to the desired type | |
684 VARIANT oldPtr, newPtr; | |
685 try { | |
686 getData(&oldPtr); | |
687 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I8); | |
688 if (result !is COM.S_OK) | |
689 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
690 Variant longVar = new Variant(); | |
691 longVar.setData(&newPtr); | |
692 return longVar.getLong(); | |
693 } finally { | |
694 COM.VariantClear(&oldPtr); | |
695 COM.VariantClear(&newPtr); | |
696 } | |
697 } | |
698 /** | |
699 * Returns the Java short represented by this Variant. | |
700 * | |
701 * <p>If this Variant does not contain a Java short, an attempt is made to | |
702 * coerce the Variant type into a Java short. If this fails, an error is thrown. | |
703 * | |
704 * @return the Java short represented by this Variant | |
705 * | |
706 * @exception SWTException <ul> | |
707 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a short</li> | |
708 * </ul> | |
709 */ | |
710 public short getShort() { | |
711 if (type is COM.VT_EMPTY) { | |
712 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
713 } | |
714 if (type is COM.VT_I2) { | |
715 return shortData; | |
716 } | |
717 | |
718 // try to coerce the value to the desired type | |
719 VARIANT oldPtr, newPtr; | |
720 try { | |
721 getData(&oldPtr); | |
722 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I2); | |
723 if (result !is COM.S_OK) | |
724 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
725 Variant shortVar = new Variant(); | |
726 shortVar.setData(&newPtr); | |
727 return shortVar.getShort(); | |
728 } finally { | |
729 COM.VariantClear(&oldPtr); | |
730 COM.VariantClear(&newPtr); | |
731 } | |
732 | |
733 } | |
734 /** | |
735 * Returns the Java String represented by this Variant. | |
736 * | |
737 * <p>If this Variant does not contain a Java String, an attempt is made to | |
738 * coerce the Variant type into a Java String. If this fails, an error is thrown. | |
739 * | |
740 * @return the Java String represented by this Variant | |
741 * | |
742 * @exception SWTException <ul> | |
743 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a String</li> | |
744 * </ul> | |
745 */ | |
746 public String getString() { | |
747 if (type is COM.VT_EMPTY) { | |
748 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
749 } | |
750 if (type is COM.VT_BSTR) { | |
751 return stringData; | |
752 } | |
753 | |
754 // try to coerce the value to the desired type | |
755 VARIANT oldPtr, newPtr; | |
756 try { | |
757 getData(&oldPtr); | |
758 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_BSTR); | |
759 if (result !is COM.S_OK) | |
760 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
761 | |
762 Variant stringVar = new Variant(); | |
763 stringVar.setData(&newPtr); | |
764 return stringVar.getString(); | |
765 | |
766 } finally { | |
767 COM.VariantClear(&oldPtr); | |
768 COM.VariantClear(&newPtr); | |
769 } | |
770 } | |
771 /** | |
772 * Returns the type of the variant type. This will be an OLE.VT_* value or | |
773 * a bitwise combination of OLE.VT_* values as in the case of | |
774 * OLE.VT_BSTR | OLE.VT_BYREF. | |
775 * | |
776 * @return the type of the variant data | |
777 * | |
778 * @since 2.0 | |
779 */ | |
780 public short getType() { | |
781 return type; | |
782 } | |
783 /** | |
784 * Returns the IUnknown object represented by this Variant. | |
785 * | |
786 * <p>If this Variant does not contain an IUnknown object, an attempt is made to | |
787 * coerce the Variant type into an IUnknown object. If this fails, an error is | |
788 * thrown. | |
789 * | |
790 * @return the IUnknown object represented by this Variant | |
791 * | |
792 * @exception SWTException <ul> | |
793 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into | |
794 * an IUnknown object</li> | |
795 * </ul> | |
796 */ | |
797 public IUnknown getUnknown() { | |
798 if (type is COM.VT_EMPTY) { | |
799 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
800 } | |
801 if (type is COM.VT_UNKNOWN) { | |
802 return unknownData; | |
803 } | |
804 | |
805 // try to coerce the value to the desired type | |
806 VARIANT oldPtr, newPtr; | |
807 try { | |
808 getData(&oldPtr); | |
809 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_UNKNOWN); | |
810 if (result !is COM.S_OK) | |
811 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
812 Variant unknownVar = new Variant(); | |
813 unknownVar.setData(&newPtr); | |
814 return unknownVar.getUnknown(); | |
815 } finally { | |
816 COM.VariantClear(&oldPtr); | |
817 COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the | |
818 // IUnknown object is created as Variant Clear | |
819 // will result in a Release being performed on the | |
820 // Dispatch object | |
821 } | |
822 } | |
823 /** | |
824 * Update the by reference value of this variant with a new bool value. | |
825 * | |
826 * @param val the new bool value | |
827 * | |
828 * @exception SWTException <ul> | |
829 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not | |
830 * a (VT_BYREF | VT_BOOL) object</li> | |
831 * </ul> | |
832 * | |
833 * @since 2.1 | |
834 */ | |
835 public void setByRef(bool val) { | |
836 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_BOOL) is 0) { | |
837 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
838 } | |
839 auto v = val ? COM.VARIANT_TRUE : COM.VARIANT_FALSE; | |
840 COM.MoveMemory(byRefPtr, &v, 2); | |
841 } | |
842 /** | |
843 * Update the by reference value of this variant with a new float value. | |
844 * | |
845 * @param val the new float value | |
846 * | |
847 * @exception SWTException <ul> | |
848 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not | |
849 * a (VT_BYREF | VT_R4) object</li> | |
850 * </ul> | |
851 * | |
852 * @since 2.1 | |
853 */ | |
854 public void setByRef(float val) { | |
855 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_R4) is 0) { | |
856 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
857 } | |
858 COM.MoveMemory(byRefPtr, &val, 4); | |
859 } | |
860 /** | |
861 * Update the by reference value of this variant with a new integer value. | |
862 * | |
863 * @param val the new integer value | |
864 * | |
865 * @exception SWTException <ul> | |
866 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I4) object</li> | |
867 * </ul> | |
868 * | |
869 * @since 2.1 | |
870 */ | |
871 public void setByRef(int val) { | |
872 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_I4) is 0) { | |
873 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
874 } | |
875 COM.MoveMemory(byRefPtr, &val, 4); | |
876 } | |
877 /** | |
878 * Update the by reference value of this variant with a new short value. | |
879 * | |
880 * @param val the new short value | |
881 * | |
882 * @exception SWTException <ul> | |
883 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I2) object | |
884 * </ul> | |
885 * | |
886 * @since 2.1 | |
887 */ | |
888 public void setByRef(short val) { | |
889 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_I2) is 0) { | |
890 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
891 } | |
892 COM.MoveMemory(byRefPtr, &val, 2); | |
893 } | |
894 | |
895 void setData(VARIANT* pData){ | |
896 if (pData is null) OLE.error(OLE.ERROR_INVALID_ARGUMENT); | |
897 | |
898 short[1] dataType ; | |
899 COM.MoveMemory(dataType.ptr, (cast(void*)pData), 2); | |
900 type = dataType[0]; | |
901 | |
902 if ((type & COM.VT_BYREF) is COM.VT_BYREF) { | |
903 void*[1] newByRefPtr; | |
904 OS.MoveMemory(newByRefPtr.ptr, (cast(void*)pData) + 8, 4); | |
905 byRefPtr = newByRefPtr[0]; | |
906 return; | |
907 } | |
908 | |
909 switch (type) { | |
910 case COM.VT_EMPTY : | |
911 case COM.VT_NULL : | |
912 break; | |
913 case COM.VT_BOOL : | |
914 short[1] newBooleanData; | |
915 COM.MoveMemory(newBooleanData.ptr, (cast(void*)pData) + 8, 2); | |
916 booleanData = (newBooleanData[0] !is COM.VARIANT_FALSE); | |
917 break; | |
918 case COM.VT_I1 : | |
919 byte[1] newByteData; | |
920 COM.MoveMemory(newByteData.ptr, (cast(void*)pData) + 8, 1); | |
921 byteData = newByteData[0]; | |
922 break; | |
923 case COM.VT_I2 : | |
924 short[1] newShortData; | |
925 COM.MoveMemory(newShortData.ptr, (cast(void*)pData) + 8, 2); | |
926 shortData = newShortData[0]; | |
927 break; | |
928 case COM.VT_UI2 : | |
929 wchar[1] newCharData; | |
930 COM.MoveMemory(newCharData.ptr, (cast(void*)pData) + 8, 2); | |
931 charData = newCharData[0]; | |
932 break; | |
933 case COM.VT_I4 : | |
934 int[1] newIntData; | |
935 OS.MoveMemory(newIntData.ptr, (cast(void*)pData) + 8, 4); | |
936 intData = newIntData[0]; | |
937 break; | |
938 case COM.VT_I8 : | |
939 long[1] newLongData; | |
940 OS.MoveMemory(newLongData.ptr, (cast(void*)pData) + 8, 8); | |
941 longData = newLongData[0]; | |
942 break; | |
943 case COM.VT_R4 : | |
944 float[1] newFloatData; | |
945 COM.MoveMemory(newFloatData.ptr, (cast(void*)pData) + 8, 4); | |
946 floatData = newFloatData[0]; | |
947 break; | |
948 case COM.VT_R8 : | |
949 double[1] newDoubleData; | |
950 COM.MoveMemory(newDoubleData.ptr, (cast(void*)pData) + 8, 8); | |
951 doubleData = newDoubleData[0]; | |
952 break; | |
953 case COM.VT_DISPATCH : { | |
954 IDispatch[1] ppvObject; | |
955 OS.MoveMemory(ppvObject.ptr, (cast(void*)pData) + 8, 4); | |
956 if (ppvObject[0] is null) { | |
957 type = COM.VT_EMPTY; | |
958 break; | |
959 } | |
960 dispatchData = ppvObject[0]; | |
961 dispatchData.AddRef(); | |
962 break; | |
963 } | |
964 case COM.VT_UNKNOWN : { | |
965 IUnknown[1] ppvObject; | |
966 OS.MoveMemory(ppvObject.ptr, (cast(void*)pData) + 8, 4); | |
967 if (ppvObject[0] is null) { | |
968 type = COM.VT_EMPTY; | |
969 break; | |
970 } | |
971 unknownData = ppvObject[0]; | |
972 unknownData.AddRef(); | |
973 break; | |
974 } | |
975 case COM.VT_BSTR : | |
976 // get the address of the memory in which the string resides | |
977 wchar*[1] hMem; | |
978 OS.MoveMemory(hMem.ptr, (cast(void*)pData) + 8, 4); | |
979 if (hMem[0] is null) { | |
980 type = COM.VT_EMPTY; | |
981 break; | |
982 } | |
983 // Get the size of the string from the OS - the size is expressed in number | |
984 // of bytes - each unicode character is 2 bytes. | |
985 int size = COM.SysStringByteLen(hMem[0]); | |
986 if (size > 0){ | |
987 // get the unicode character array from the global memory and create a String | |
988 wchar[] buffer = new wchar[(size + 1) /2]; // add one to avoid rounding errors | |
989 COM.MoveMemory(buffer.ptr, hMem[0], size); | |
990 stringData = WCHARsToStr( buffer ); | |
991 } else { | |
992 stringData = ""; //$NON-NLS-1$ | |
993 } | |
994 break; | |
995 | |
996 default : | |
997 // try coercing it into one of the known forms | |
998 auto newPData = cast(VARIANT*) OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof); | |
999 if (COM.VariantChangeType(newPData, pData, 0, COM.VT_R4) is COM.S_OK) { | |
1000 setData(newPData); | |
1001 } else if (COM.VariantChangeType(newPData, pData, 0, COM.VT_I4) is COM.S_OK) { | |
1002 setData(newPData); | |
1003 } else if (COM.VariantChangeType(newPData, pData, 0, COM.VT_BSTR) is COM.S_OK) { | |
1004 setData(newPData); | |
1005 } | |
1006 COM.VariantClear(newPData); | |
1007 OS.GlobalFree(newPData); | |
1008 break; | |
1009 } | |
1010 } | |
1011 | |
1012 /** | |
1013 * Returns a string containing a concise, human-readable | |
1014 * description of the receiver. | |
1015 * | |
1016 * @return a string representation of the Variant | |
1017 */ | |
1018 public String toString () { | |
1019 switch (type) { | |
1020 case COM.VT_BOOL : | |
1021 return "VT_BOOL{"~to!(String)(booleanData)~"}"; | |
1022 case COM.VT_I1 : | |
1023 return "VT_I1{"~to!(String)(byteData)~"}"; | |
1024 case COM.VT_I2 : | |
1025 return "VT_I2{"~to!(String)(shortData)~"}"; | |
1026 case COM.VT_UI2 : | |
1027 return "VT_UI2{"~ dcharToString(charData) ~"}"; | |
1028 case COM.VT_I4 : | |
1029 return "VT_I4{"~to!(String)(intData)~"}"; | |
1030 case COM.VT_I8 : | |
1031 return "VT_I8{"~to!(String)(longData)~"}"; | |
1032 case COM.VT_R4 : | |
1033 return "VT_R4{"~to!(String)(floatData)~"}"; | |
1034 case COM.VT_R8 : | |
1035 return "VT_R8{"~to!(String)(doubleData)~"}"; | |
1036 case COM.VT_BSTR : | |
1037 return "VT_BSTR{"~stringData~"}"; | |
1038 case COM.VT_DISPATCH : | |
1039 return Format("VT_DISPATCH{{0x{:X}}", cast(void*) (dispatchData is null ? null : dispatchData)); | |
1040 case COM.VT_UNKNOWN : | |
1041 return Format("VT_UNKNOWN{{0x{:X}}", cast(void*) (unknownData is null ? null : unknownData)); | |
1042 case COM.VT_EMPTY : | |
1043 return "VT_EMPTY"; | |
1044 case COM.VT_NULL : | |
1045 return "VT_NULL"; | |
1046 default: | |
1047 } | |
1048 if ((type & COM.VT_BYREF) !is 0) { | |
1049 return Format("VT_BYREF|{}{{{}}",(type & ~COM.VT_BYREF), byRefPtr ); | |
1050 } | |
1051 return "Unsupported Type "~to!(String)(type); | |
1052 } | |
1053 } |