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