001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.ole.win32;
011:
012: import org.eclipse.swt.internal.ole.win32.*;
013: import org.eclipse.swt.internal.win32.*;
014:
015: /**
016: * OleAutomation provides a generic mechanism for accessing functionality that is
017: * specific to a particular ActiveX Control or OLE Document.
018: *
019: * <p>The OLE Document or ActiveX Control must support the IDispatch interface in order to provide
020: * OleAutomation support. The additional functionality provided by the OLE Object is specified in
021: * its IDL file. The additional methods can either be to get property values (<code>getProperty</code>),
022: * to set property values (<code>setProperty</code>) or to invoke a method (<code>invoke</code> or
023: * <code>invokeNoReply</code>). Arguments are passed around in the form of <code>Variant</code>
024: * objects.
025: *
026: * <p>Here is a sample IDL fragment:
027: *
028: * <pre>
029: * interface IMyControl : IDispatch
030: * {
031: * [propget, id(0)] HRESULT maxFileCount([retval, out] int *c);
032: * [propput, id(0)] HRESULT maxFileCount([in] int c);
033: * [id(1)] HRESULT AddFile([in] BSTR fileName);
034: * };
035: * </pre>
036: *
037: * <p>An example of how to interact with this extended functionality is shown below:
038: *
039: * <code><pre>
040: * OleAutomation automation = new OleAutomation(myControlSite);
041: *
042: * // Look up the ID of the maxFileCount parameter
043: * int[] rgdispid = automation.getIDsOfNames(new String[]{"maxFileCount"});
044: * int maxFileCountID = rgdispid[0];
045: *
046: * // Set the property maxFileCount to 100:
047: * if (automation.setProperty(maxFileCountID, new Variant(100))) {
048: * System.out.println("Max File Count was successfully set.");
049: * }
050: *
051: * // Get the new value of the maxFileCount parameter:
052: * Variant pVarResult = automation.getProperty(maxFileCountID);
053: * if (pVarResult != null) {
054: * System.out.println("Max File Count is "+pVarResult.getInt());
055: * }
056: *
057: * // Invoke the AddFile method
058: * // Look up the IDs of the AddFile method and its parameter
059: * rgdispid = automation.getIDsOfNames(new String[]{"AddFile", "fileName"});
060: * int dispIdMember = rgdispid[0];
061: * int[] rgdispidNamedArgs = new int[] {rgdispid[1]};
062: *
063: * // Convert arguments to Variant objects
064: * Variant[] rgvarg = new Variant[1];
065: * String fileName = "C:\\testfile";
066: * rgvarg[0] = new Variant(fileName);
067: *
068: * // Call the method
069: * Variant pVarResult = automation.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);
070: *
071: * // Check the return value
072: * if (pVarResult == null || pVarResult.getInt() != OLE.S_OK){
073: * System.out.println("Failed to add file "+fileName);
074: * }
075: *
076: * automation.dispose();
077: *
078: * </pre></code>
079: */
080: public final class OleAutomation {
081: private IDispatch objIDispatch;
082: private String exceptionDescription;
083: private ITypeInfo objITypeInfo;
084:
085: OleAutomation(IDispatch idispatch) {
086: if (idispatch == null)
087: OLE.error(OLE.ERROR_INVALID_INTERFACE_ADDRESS);
088: objIDispatch = idispatch;
089: objIDispatch.AddRef();
090:
091: int /*long*/[] ppv = new int /*long*/[1];
092: int result = objIDispatch.GetTypeInfo(0,
093: COM.LOCALE_USER_DEFAULT, ppv);
094: if (result == OLE.S_OK) {
095: objITypeInfo = new ITypeInfo(ppv[0]);
096: objITypeInfo.AddRef();
097: }
098: }
099:
100: /**
101: * Creates an OleAutomation object for the specified client.
102: *
103: * @param clientSite the site for the OLE Document or ActiveX Control whose additional functionality
104: * you need to access
105: *
106: * @exception IllegalArgumentException <ul>
107: * <li>ERROR_INVALID_INTERFACE_ADDRESS when called with an invalid client site
108: * </ul>
109: */
110: public OleAutomation(OleClientSite clientSite) {
111: if (clientSite == null)
112: OLE.error(OLE.ERROR_INVALID_INTERFACE_ADDRESS);
113: objIDispatch = clientSite.getAutomationObject();
114:
115: int /*long*/[] ppv = new int /*long*/[1];
116: int result = objIDispatch.GetTypeInfo(0,
117: COM.LOCALE_USER_DEFAULT, ppv);
118: if (result == OLE.S_OK) {
119: objITypeInfo = new ITypeInfo(ppv[0]);
120: objITypeInfo.AddRef();
121: }
122: }
123:
124: /**
125: * Disposes the automation object.
126: * <p>
127: * This method releases the IDispatch interface on the OLE Document or ActiveX Control.
128: * Do not use the OleAutomation object after it has been disposed.
129: */
130: public void dispose() {
131:
132: if (objIDispatch != null) {
133: objIDispatch.Release();
134: }
135: objIDispatch = null;
136:
137: if (objITypeInfo != null) {
138: objITypeInfo.Release();
139: }
140: objITypeInfo = null;
141:
142: }
143:
144: int /*long*/getAddress() {
145: return objIDispatch.getAddress();
146: }
147:
148: public String getHelpFile(int dispId) {
149: if (objITypeInfo == null)
150: return null;
151: String[] file = new String[1];
152: int rc = objITypeInfo.GetDocumentation(dispId, null, null,
153: null, file);
154: if (rc == OLE.S_OK)
155: return file[0];
156: return null;
157: }
158:
159: public String getDocumentation(int dispId) {
160: if (objITypeInfo == null)
161: return null;
162: String[] doc = new String[1];
163: int rc = objITypeInfo.GetDocumentation(dispId, null, doc, null,
164: null);
165: if (rc == OLE.S_OK)
166: return doc[0];
167: return null;
168: }
169:
170: public OlePropertyDescription getPropertyDescription(int index) {
171: if (objITypeInfo == null)
172: return null;
173: int /*long*/[] ppVarDesc = new int /*long*/[1];
174: int rc = objITypeInfo.GetVarDesc(index, ppVarDesc);
175: if (rc != OLE.S_OK)
176: return null;
177: VARDESC vardesc = new VARDESC();
178: COM.MoveMemory(vardesc, ppVarDesc[0], VARDESC.sizeof);
179:
180: OlePropertyDescription data = new OlePropertyDescription();
181: data.id = vardesc.memid;
182: data.name = getName(vardesc.memid);
183: data.type = vardesc.elemdescVar_tdesc_vt;
184: if (data.type == OLE.VT_PTR) {
185: short[] vt = new short[1];
186: COM.MoveMemory(vt, vardesc.elemdescVar_tdesc_union
187: + OS.PTR_SIZEOF, 2);
188: data.type = vt[0];
189: }
190: data.flags = vardesc.wVarFlags;
191: data.kind = vardesc.varkind;
192: data.description = getDocumentation(vardesc.memid);
193: data.helpFile = getHelpFile(vardesc.memid);
194:
195: objITypeInfo.ReleaseVarDesc(ppVarDesc[0]);
196: return data;
197: }
198:
199: public OleFunctionDescription getFunctionDescription(int index) {
200: if (objITypeInfo == null)
201: return null;
202: int /*long*/[] ppFuncDesc = new int /*long*/[1];
203: int rc = objITypeInfo.GetFuncDesc(index, ppFuncDesc);
204: if (rc != OLE.S_OK)
205: return null;
206: FUNCDESC funcdesc = new FUNCDESC();
207: COM.MoveMemory(funcdesc, ppFuncDesc[0], FUNCDESC.sizeof);
208:
209: OleFunctionDescription data = new OleFunctionDescription();
210:
211: data.id = funcdesc.memid;
212: data.optionalArgCount = funcdesc.cParamsOpt;
213: data.invokeKind = funcdesc.invkind;
214: data.funcKind = funcdesc.funckind;
215: data.flags = funcdesc.wFuncFlags;
216: data.callingConvention = funcdesc.callconv;
217: data.documentation = getDocumentation(funcdesc.memid);
218: data.helpFile = getHelpFile(funcdesc.memid);
219:
220: String[] names = getNames(funcdesc.memid, funcdesc.cParams + 1);
221: if (names.length > 0) {
222: data.name = names[0];
223: }
224: data.args = new OleParameterDescription[funcdesc.cParams];
225: for (int i = 0; i < data.args.length; i++) {
226: data.args[i] = new OleParameterDescription();
227: if (names.length > i + 1) {
228: data.args[i].name = names[i + 1];
229: }
230: //TODO 0- use structures
231: short[] vt = new short[1];
232: COM.MoveMemory(vt, funcdesc.lprgelemdescParam + i
233: * COM.ELEMDESC_sizeof() + OS.PTR_SIZEOF, 2);
234: if (vt[0] == OLE.VT_PTR) {
235: int /*long*/[] pTypedesc = new int /*long*/[1];
236: COM.MoveMemory(pTypedesc, funcdesc.lprgelemdescParam
237: + i * COM.ELEMDESC_sizeof(), OS.PTR_SIZEOF);
238: short[] vt2 = new short[1];
239: COM.MoveMemory(vt2, pTypedesc[0] + OS.PTR_SIZEOF, 2);
240: vt[0] = (short) (vt2[0] | COM.VT_BYREF);
241: }
242: data.args[i].type = vt[0];
243: short[] wParamFlags = new short[1];
244: COM.MoveMemory(wParamFlags, funcdesc.lprgelemdescParam + i
245: * COM.ELEMDESC_sizeof() + COM.TYPEDESC_sizeof()
246: + OS.PTR_SIZEOF, 2);
247: data.args[i].flags = wParamFlags[0];
248: }
249:
250: data.returnType = funcdesc.elemdescFunc_tdesc_vt;
251: if (data.returnType == OLE.VT_PTR) {
252: short[] vt = new short[1];
253: COM.MoveMemory(vt, funcdesc.elemdescFunc_tdesc_union
254: + OS.PTR_SIZEOF, 2);
255: data.returnType = vt[0];
256: }
257:
258: objITypeInfo.ReleaseFuncDesc(ppFuncDesc[0]);
259: return data;
260: }
261:
262: public TYPEATTR getTypeInfoAttributes() {
263: if (objITypeInfo == null)
264: return null;
265: int /*long*/[] ppTypeAttr = new int /*long*/[1];
266: int rc = objITypeInfo.GetTypeAttr(ppTypeAttr);
267: if (rc != OLE.S_OK)
268: return null;
269: TYPEATTR typeattr = new TYPEATTR();
270: COM.MoveMemory(typeattr, ppTypeAttr[0], TYPEATTR.sizeof);
271: objITypeInfo.ReleaseTypeAttr(ppTypeAttr[0]);
272: return typeattr;
273: }
274:
275: public String getName(int dispId) {
276: if (objITypeInfo == null)
277: return null;
278: String[] name = new String[1];
279: int rc = objITypeInfo.GetDocumentation(dispId, name, null,
280: null, null);
281: if (rc == OLE.S_OK)
282: return name[0];
283: return null;
284: }
285:
286: public String[] getNames(int dispId, int maxSize) {
287: if (objITypeInfo == null)
288: return new String[0];
289: String[] names = new String[maxSize];
290: int[] count = new int[1];
291: int rc = objITypeInfo.GetNames(dispId, names, maxSize, count);
292: if (rc == OLE.S_OK) {
293: String[] newNames = new String[count[0]];
294: System.arraycopy(names, 0, newNames, 0, count[0]);
295: return newNames;
296: }
297: return new String[0];
298: }
299:
300: /**
301: * Returns the positive integer values (IDs) that are associated with the specified names by the
302: * IDispatch implementor. If you are trying to get the names of the parameters in a method, the first
303: * String in the names array must be the name of the method followed by the names of the parameters.
304: *
305: * @param names an array of names for which you require the identifiers
306: *
307: * @return positive integer values that are associated with the specified names in the same
308: * order as the names where provided; or null if the names are unknown
309: */
310: public int[] getIDsOfNames(String[] names) {
311:
312: int[] rgdispid = new int[names.length];
313: int result = objIDispatch.GetIDsOfNames(new GUID(), names,
314: names.length, COM.LOCALE_USER_DEFAULT, rgdispid);
315: if (result != COM.S_OK)
316: return null;
317:
318: return rgdispid;
319: }
320:
321: /**
322: * Returns a description of the last error encountered.
323: *
324: * @return a description of the last error encountered
325: */
326: public String getLastError() {
327:
328: return exceptionDescription;
329:
330: }
331:
332: /**
333: * Returns the value of the property specified by the dispIdMember.
334: *
335: * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
336: * value for the ID can be obtained using OleAutomation.getIDsOfNames
337: *
338: * @return the value of the property specified by the dispIdMember or null
339: */
340: public Variant getProperty(int dispIdMember) {
341: Variant pVarResult = new Variant();
342: int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET,
343: null, null, pVarResult);
344: return (result == OLE.S_OK) ? pVarResult : null;
345: }
346:
347: /**
348: * Returns the value of the property specified by the dispIdMember.
349: *
350: * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
351: * value for the ID can be obtained using OleAutomation.getIDsOfNames
352: *
353: * @param rgvarg an array of arguments for the method. All arguments are considered to be
354: * read only unless the Variant is a By Reference Variant type.
355: *
356: * @return the value of the property specified by the dispIdMember or null
357: *
358: * @since 2.0
359: */
360: public Variant getProperty(int dispIdMember, Variant[] rgvarg) {
361: Variant pVarResult = new Variant();
362: int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET,
363: rgvarg, null, pVarResult);
364: return (result == OLE.S_OK) ? pVarResult : null;
365:
366: }
367:
368: /**
369: * Returns the value of the property specified by the dispIdMember.
370: *
371: * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
372: * value for the ID can be obtained using OleAutomation.getIDsOfNames
373: *
374: * @param rgvarg an array of arguments for the method. All arguments are considered to be
375: * read only unless the Variant is a By Reference Variant type.
376: *
377: * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
378: * parameter IDs must be in the same order as their corresponding values;
379: * all arguments must have an identifier - identifiers can be obtained using
380: * OleAutomation.getIDsOfNames
381: *
382: * @return the value of the property specified by the dispIdMember or null
383: *
384: * @since 2.0
385: */
386: public Variant getProperty(int dispIdMember, Variant[] rgvarg,
387: int[] rgdispidNamedArgs) {
388: Variant pVarResult = new Variant();
389: int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET,
390: rgvarg, rgdispidNamedArgs, pVarResult);
391: return (result == OLE.S_OK) ? pVarResult : null;
392: }
393:
394: /**
395: * Invokes a method on the OLE Object; the method has no parameters.
396: *
397: * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
398: * value for the ID can be obtained using OleAutomation.getIDsOfNames
399: *
400: * @return the result of the method or null if the method failed to give result information
401: */
402: public Variant invoke(int dispIdMember) {
403: Variant pVarResult = new Variant();
404: int result = invoke(dispIdMember, COM.DISPATCH_METHOD, null,
405: null, pVarResult);
406: return (result == COM.S_OK) ? pVarResult : null;
407: }
408:
409: /**
410: * Invokes a method on the OLE Object; the method has no optional parameters.
411: *
412: * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
413: * value for the ID can be obtained using OleAutomation.getIDsOfNames
414: *
415: * @param rgvarg an array of arguments for the method. All arguments are considered to be
416: * read only unless the Variant is a By Reference Variant type.
417: *
418: * @return the result of the method or null if the method failed to give result information
419: */
420: public Variant invoke(int dispIdMember, Variant[] rgvarg) {
421: Variant pVarResult = new Variant();
422: int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg,
423: null, pVarResult);
424: return (result == COM.S_OK) ? pVarResult : null;
425: }
426:
427: /**
428: * Invokes a method on the OLE Object; the method has optional parameters. It is not
429: * necessary to specify all the optional parameters, only include the parameters for which
430: * you are providing values.
431: *
432: * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
433: * value for the ID can be obtained using OleAutomation.getIDsOfNames
434: *
435: * @param rgvarg an array of arguments for the method. All arguments are considered to be
436: * read only unless the Variant is a By Reference Variant type.
437: *
438: * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
439: * parameter IDs must be in the same order as their corresponding values;
440: * all arguments must have an identifier - identifiers can be obtained using
441: * OleAutomation.getIDsOfNames
442: *
443: * @return the result of the method or null if the method failed to give result information
444: */
445: public Variant invoke(int dispIdMember, Variant[] rgvarg,
446: int[] rgdispidNamedArgs) {
447: Variant pVarResult = new Variant();
448: int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg,
449: rgdispidNamedArgs, pVarResult);
450: return (result == COM.S_OK) ? pVarResult : null;
451: }
452:
453: private int invoke(int dispIdMember, int wFlags, Variant[] rgvarg,
454: int[] rgdispidNamedArgs, Variant pVarResult) {
455:
456: // get the IDispatch interface for the control
457: if (objIDispatch == null)
458: return COM.E_FAIL;
459:
460: // create a DISPPARAMS structure for the input parameters
461: DISPPARAMS pDispParams = new DISPPARAMS();
462: // store arguments in rgvarg
463: if (rgvarg != null && rgvarg.length > 0) {
464: pDispParams.cArgs = rgvarg.length;
465: pDispParams.rgvarg = OS
466: .GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT,
467: VARIANT.sizeof * rgvarg.length);
468: int offset = 0;
469: for (int i = rgvarg.length - 1; i >= 0; i--) {
470: rgvarg[i].getData(pDispParams.rgvarg + offset);
471: offset += VARIANT.sizeof;
472: }
473: }
474:
475: // if arguments have ids, store the ids in rgdispidNamedArgs
476: if (rgdispidNamedArgs != null && rgdispidNamedArgs.length > 0) {
477: pDispParams.cNamedArgs = rgdispidNamedArgs.length;
478: pDispParams.rgdispidNamedArgs = OS.GlobalAlloc(
479: COM.GMEM_FIXED | COM.GMEM_ZEROINIT,
480: 4 * rgdispidNamedArgs.length);
481: int offset = 0;
482: for (int i = rgdispidNamedArgs.length; i > 0; i--) {
483: COM.MoveMemory(pDispParams.rgdispidNamedArgs + offset,
484: new int[] { rgdispidNamedArgs[i - 1] }, 4);
485: offset += 4;
486: }
487: }
488:
489: // invoke the method
490: EXCEPINFO excepInfo = new EXCEPINFO();
491: int[] pArgErr = new int[1];
492: int /*long*/pVarResultAddress = 0;
493: if (pVarResult != null)
494: pVarResultAddress = OS.GlobalAlloc(OS.GMEM_FIXED
495: | OS.GMEM_ZEROINIT, VARIANT.sizeof);
496: int result = objIDispatch.Invoke(dispIdMember, new GUID(),
497: COM.LOCALE_USER_DEFAULT, wFlags, pDispParams,
498: pVarResultAddress, excepInfo, pArgErr);
499:
500: if (pVarResultAddress != 0) {
501: pVarResult.setData(pVarResultAddress);
502: COM.VariantClear(pVarResultAddress);
503: OS.GlobalFree(pVarResultAddress);
504: }
505:
506: // free the Dispparams resources
507: if (pDispParams.rgdispidNamedArgs != 0) {
508: OS.GlobalFree(pDispParams.rgdispidNamedArgs);
509: }
510: if (pDispParams.rgvarg != 0) {
511: int offset = 0;
512: for (int i = 0, length = rgvarg.length; i < length; i++) {
513: COM.VariantClear(pDispParams.rgvarg + offset);
514: offset += VARIANT.sizeof;
515: }
516: OS.GlobalFree(pDispParams.rgvarg);
517: }
518:
519: // save error string and cleanup EXCEPINFO
520: manageExcepinfo(result, excepInfo);
521:
522: return result;
523: }
524:
525: /**
526: * Invokes a method on the OLE Object; the method has no parameters. In the early days of OLE,
527: * the IDispatch interface was not well defined and some applications (mainly Word) did not support
528: * a return value. For these applications, call this method instead of calling
529: * <code>public void invoke(int dispIdMember)</code>.
530: *
531: * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
532: * value for the ID can be obtained using OleAutomation.getIDsOfNames
533: *
534: * @exception org.eclipse.swt.SWTException <ul>
535: * <li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
536: * </ul>
537: */
538: public void invokeNoReply(int dispIdMember) {
539: int result = invoke(dispIdMember, COM.DISPATCH_METHOD, null,
540: null, null);
541: if (result != COM.S_OK)
542: OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
543: }
544:
545: /**
546: * Invokes a method on the OLE Object; the method has no optional parameters. In the early days of OLE,
547: * the IDispatch interface was not well defined and some applications (mainly Word) did not support
548: * a return value. For these applications, call this method instead of calling
549: * <code>public void invoke(int dispIdMember, Variant[] rgvarg)</code>.
550: *
551: * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
552: * value for the ID can be obtained using OleAutomation.getIDsOfNames
553: *
554: * @param rgvarg an array of arguments for the method. All arguments are considered to be
555: * read only unless the Variant is a By Reference Variant type.
556: *
557: * @exception org.eclipse.swt.SWTException <ul>
558: * <li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
559: * </ul>
560: */
561: public void invokeNoReply(int dispIdMember, Variant[] rgvarg) {
562: int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg,
563: null, null);
564: if (result != COM.S_OK)
565: OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
566: }
567:
568: /**
569: * Invokes a method on the OLE Object; the method has optional parameters. It is not
570: * necessary to specify all the optional parameters, only include the parameters for which
571: * you are providing values. In the early days of OLE, the IDispatch interface was not well
572: * defined and some applications (mainly Word) did not support a return value. For these
573: * applications, call this method instead of calling
574: * <code>public void invoke(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs)</code>.
575: *
576: * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
577: * value for the ID can be obtained using OleAutomation.getIDsOfNames
578: *
579: * @param rgvarg an array of arguments for the method. All arguments are considered to be
580: * read only unless the Variant is a By Reference Variant type.
581: *
582: * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
583: * parameter IDs must be in the same order as their corresponding values;
584: * all arguments must have an identifier - identifiers can be obtained using
585: * OleAutomation.getIDsOfNames
586: *
587: * @exception org.eclipse.swt.SWTException <ul>
588: * <li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
589: * </ul>
590: */
591: public void invokeNoReply(int dispIdMember, Variant[] rgvarg,
592: int[] rgdispidNamedArgs) {
593: int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg,
594: rgdispidNamedArgs, null);
595: if (result != COM.S_OK)
596: OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
597: }
598:
599: private void manageExcepinfo(int hResult, EXCEPINFO excepInfo) {
600:
601: if (hResult == COM.S_OK) {
602: exceptionDescription = "No Error"; //$NON-NLS-1$
603: return;
604: }
605:
606: // extract exception info
607: if (hResult == COM.DISP_E_EXCEPTION) {
608: if (excepInfo.bstrDescription != 0) {
609: int size = COM
610: .SysStringByteLen(excepInfo.bstrDescription);
611: char[] buffer = new char[(size + 1) / 2];
612: COM.MoveMemory(buffer, excepInfo.bstrDescription, size);
613: exceptionDescription = new String(buffer);
614: } else {
615: exceptionDescription = "OLE Automation Error Exception "; //$NON-NLS-1$
616: if (excepInfo.wCode != 0) {
617: exceptionDescription += "code = " + excepInfo.wCode; //$NON-NLS-1$
618: } else if (excepInfo.scode != 0) {
619: exceptionDescription += "code = " + excepInfo.scode; //$NON-NLS-1$
620: }
621: }
622: } else {
623: exceptionDescription = "OLE Automation Error HResult : " + hResult; //$NON-NLS-1$
624: }
625:
626: // cleanup EXCEPINFO struct
627: if (excepInfo.bstrDescription != 0)
628: COM.SysFreeString(excepInfo.bstrDescription);
629: if (excepInfo.bstrHelpFile != 0)
630: COM.SysFreeString(excepInfo.bstrHelpFile);
631: if (excepInfo.bstrSource != 0)
632: COM.SysFreeString(excepInfo.bstrSource);
633: }
634:
635: /**
636: * Sets the property specified by the dispIdMember to a new value.
637: *
638: * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
639: * value for the ID can be obtained using OleAutomation.getIDsOfNames
640: * @param rgvarg the new value of the property
641: *
642: * @return true if the operation was successful
643: */
644: public boolean setProperty(int dispIdMember, Variant rgvarg) {
645: Variant[] rgvarg2 = new Variant[] { rgvarg };
646: int[] rgdispidNamedArgs = new int[] { COM.DISPID_PROPERTYPUT };
647: int dwFlags = COM.DISPATCH_PROPERTYPUT;
648: if ((rgvarg.getType() & COM.VT_BYREF) == COM.VT_BYREF)
649: dwFlags = COM.DISPATCH_PROPERTYPUTREF;
650: Variant pVarResult = new Variant();
651: int result = invoke(dispIdMember, dwFlags, rgvarg2,
652: rgdispidNamedArgs, pVarResult);
653: return (result == COM.S_OK);
654: }
655:
656: /**
657: * Sets the property specified by the dispIdMember to a new value.
658: *
659: * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
660: * value for the ID can be obtained using OleAutomation.getIDsOfNames
661: * @param rgvarg an array of arguments for the method. All arguments are considered to be
662: * read only unless the Variant is a By Reference Variant type.
663: *
664: * @return true if the operation was successful
665: *
666: * @since 2.0
667: */
668: public boolean setProperty(int dispIdMember, Variant[] rgvarg) {
669: int[] rgdispidNamedArgs = new int[] { COM.DISPID_PROPERTYPUT };
670: int dwFlags = COM.DISPATCH_PROPERTYPUT;
671: for (int i = 0; i < rgvarg.length; i++) {
672: if ((rgvarg[i].getType() & COM.VT_BYREF) == COM.VT_BYREF)
673: dwFlags = COM.DISPATCH_PROPERTYPUTREF;
674: }
675: Variant pVarResult = new Variant();
676: int result = invoke(dispIdMember, dwFlags, rgvarg,
677: rgdispidNamedArgs, pVarResult);
678: return (result == COM.S_OK);
679: }
680: }
|