1 /*******************************************************************************
2 * Copyright (c) 2000, 2017 IBM Corporation and others.
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
9 * SPDX-License-Identifier: EPL-2.0
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.swt.ole.win32;
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.internal.*;
19 import org.eclipse.swt.internal.ole.win32.*;
20 import org.eclipse.swt.internal.win32.*;
23 * OleAutomation provides a generic mechanism for accessing functionality that is
24 * specific to a particular ActiveX Control or OLE Document.
26 * <p>The OLE Document or ActiveX Control must support the IDispatch interface in order to provide
27 * OleAutomation support. The additional functionality provided by the OLE Object is specified in
28 * its IDL file. The additional methods can either be to get property values (<code>getProperty</code>),
29 * to set property values (<code>setProperty</code>) or to invoke a method (<code>invoke</code> or
30 * <code>invokeNoReply</code>). Arguments are passed around in the form of <code>Variant</code>
33 * <p>Here is a sample IDL fragment:
36 * interface IMyControl : IDispatch
38 * [propget, id(0)] HRESULT maxFileCount([retval, out] int *c);
39 * [propput, id(0)] HRESULT maxFileCount([in] int c);
40 * [id(1)] HRESULT AddFile([in] BSTR fileName);
44 * <p>An example of how to interact with this extended functionality is shown below:
47 * OleAutomation automation = new OleAutomation(myControlSite);
49 * // Look up the ID of the maxFileCount parameter
50 * int[] rgdispid = automation.getIDsOfNames(new String[]{"maxFileCount"});
51 * int maxFileCountID = rgdispid[0];
53 * // Set the property maxFileCount to 100:
54 * if (automation.setProperty(maxFileCountID, new Variant(100))) {
55 * System.out.println("Max File Count was successfully set.");
58 * // Get the new value of the maxFileCount parameter:
59 * Variant pVarResult = automation.getProperty(maxFileCountID);
60 * if (pVarResult != null) {
61 * System.out.println("Max File Count is "+pVarResult.getInt());
64 * // Invoke the AddFile method
65 * // Look up the IDs of the AddFile method and its parameter
66 * rgdispid = automation.getIDsOfNames(new String[]{"AddFile", "fileName"});
67 * int dispIdMember = rgdispid[0];
68 * int[] rgdispidNamedArgs = new int[] {rgdispid[1]};
70 * // Convert arguments to Variant objects
71 * Variant[] rgvarg = new Variant[1];
72 * String fileName = "C:\\testfile";
73 * rgvarg[0] = new Variant(fileName);
76 * Variant pVarResult = automation.invoke(dispIdMember, rgvarg, rgdispidNamedArgs);
78 * // Check the return value
79 * if (pVarResult == null || pVarResult.getInt() != OLE.S_OK){
80 * System.out.println("Failed to add file "+fileName);
83 * automation.dispose();
87 * @see <a href="http://www.eclipse.org/swt/snippets/#ole">OLE and ActiveX snippets</a>
88 * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Examples: OLEExample, OleWebBrowser</a>
90 public final class OleAutomation {
91 private IUnknown objIUnknown;
92 private IDispatch objIDispatch;
93 private String exceptionDescription;
94 private ITypeInfo objITypeInfo;
96 OleAutomation(IDispatch idispatch) {
97 if (idispatch == null) OLE.error(OLE.ERROR_INVALID_INTERFACE_ADDRESS);
98 objIDispatch = idispatch;
99 objIDispatch.AddRef();
101 long[] ppv = new long[1];
102 /* GetTypeInfo([in] iTInfo, [in] lcid, [out] ppTInfo)
103 * AddRef has already been called on ppTInfo by the callee and must be released by the caller.
105 int result = objIDispatch.GetTypeInfo(0, COM.LOCALE_USER_DEFAULT, ppv);
106 if (result == OLE.S_OK) {
107 objITypeInfo = new ITypeInfo(ppv[0]);
111 * Creates an OleAutomation object for the specified client.
113 * @param clientSite the site for the OLE Document or ActiveX Control whose additional functionality
116 * @exception IllegalArgumentException <ul>
117 * <li>ERROR_INVALID_INTERFACE_ADDRESS when called with an invalid client site
120 public OleAutomation(OleClientSite clientSite) {
121 if (clientSite == null) OLE.error(OLE.ERROR_INVALID_INTERFACE_ADDRESS);
122 objIDispatch = clientSite.getAutomationObject();
124 long[] ppv = new long[1];
125 /* GetTypeInfo([in] iTInfo, [in] lcid, [out] ppTInfo)
126 * AddRef has already been called on ppTInfo by the callee and must be released by the caller.
128 int result = objIDispatch.GetTypeInfo(0, COM.LOCALE_USER_DEFAULT, ppv);
129 if (result == OLE.S_OK) {
130 objITypeInfo = new ITypeInfo(ppv[0]);
134 * Creates an OleAutomation object for the specified <code>progID</code>.
136 * @param progId the unique program identifier of an OLE Document application;
137 * the value of the ProgID key or the value of the VersionIndependentProgID key specified
138 * in the registry for the desired OLE Document (for example, the VersionIndependentProgID
139 * for Word is Word.Document)
141 * @exception SWTException
142 * <ul><li>ERROR_INVALID_CLASSID when the progId does not map to a registered CLSID
143 * <li>ERROR_CANNOT_CREATE_OBJECT when failed to create OLE Object
144 * <li>ERROR_INTERFACE_NOT_FOUND when the OLE object specified does not implement IDispatch
149 public OleAutomation(String progId) {
152 GUID appClsid = getClassID(progId);
153 if (appClsid == null) {
154 OS.OleUninitialize();
155 OLE.error(OLE.ERROR_INVALID_CLASSID);
157 int flags = COM.CLSCTX_INPROC_SERVER | COM.CLSCTX_LOCAL_SERVER;
158 long[] ppvObject = new long[1];
159 int result = COM.CoCreateInstance(appClsid, 0, flags, COM.IIDIUnknown, ppvObject);
160 if (result != COM.S_OK) {
161 OS.OleUninitialize();
162 OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);
164 objIUnknown = new IUnknown(ppvObject[0]);
167 result = objIUnknown.QueryInterface(COM.IIDIDispatch, ppvObject);
168 if (result != COM.S_OK) OLE.error(OLE.ERROR_INTERFACE_NOT_FOUND);
169 objIDispatch = new IDispatch(ppvObject[0]);
172 result = objIDispatch.GetTypeInfo(0, COM.LOCALE_USER_DEFAULT, ppvObject);
173 if (result == OLE.S_OK) {
174 objITypeInfo = new ITypeInfo(ppvObject[0]);
176 } catch (SWTException e) {
182 * Disposes the automation object.
184 * This method releases the IDispatch interface on the OLE Document or ActiveX Control.
185 * Do not use the OleAutomation object after it has been disposed.
187 public void dispose() {
189 if (objIDispatch != null){
190 objIDispatch.Release();
194 if (objITypeInfo != null){
195 objITypeInfo.Release();
199 if (objIUnknown != null){
200 objIUnknown.Release();
201 OS.OleUninitialize();
206 return objIDispatch.getAddress();
208 GUID getClassID(String clientName) {
209 // create a GUID struct to hold the result
210 GUID guid = new GUID();
212 // create a null terminated array of char
213 char[] buffer = null;
214 if (clientName != null) {
215 int count = clientName.length();
216 buffer = new char[count + 1];
217 clientName.getChars(0, count, buffer, 0);
219 if (COM.CLSIDFromProgID(buffer, guid) != COM.S_OK){
220 int result = COM.CLSIDFromString(buffer, guid);
221 if (result != COM.S_OK) return null;
226 * Returns the fully qualified name of the Help file for the given member ID.
228 * @param dispId the member ID whose Help file is being retrieved.
229 * @return a string representing the fully qualified name of a Help
232 public String getHelpFile(int dispId) {
233 if (objITypeInfo == null) return null;
234 String[] file = new String[1];
235 int rc = objITypeInfo.GetDocumentation(dispId, null, null, null, file );
236 if (rc == OLE.S_OK) return file[0];
240 * Returns the documentation string for the given member ID.
242 * @param dispId the member ID in which the documentation is being retrieved.
243 * @return the documentation string if it exists; otherwise return null.
245 public String getDocumentation(int dispId) {
246 if (objITypeInfo == null) return null;
247 String[] doc = new String[1];
248 int rc = objITypeInfo.GetDocumentation(dispId, null, doc, null, null );
249 if (rc == OLE.S_OK) return doc[0];
253 * Returns the property description of a variable at the given index.
255 * @param index the index of a variable whose property is being retrieved.
256 * @return an OlePropertyDescription for a variable at the given index.
258 public OlePropertyDescription getPropertyDescription(int index) {
259 if (objITypeInfo == null) return null;
260 long[] ppVarDesc = new long[1];
261 int rc = objITypeInfo.GetVarDesc(index, ppVarDesc);
262 if (rc != OLE.S_OK) return null;
263 VARDESC vardesc = new VARDESC();
264 COM.MoveMemory(vardesc, ppVarDesc[0], VARDESC.sizeof);
266 OlePropertyDescription data = new OlePropertyDescription();
267 data.id = vardesc.memid;
268 data.name = getName(vardesc.memid);
269 data.type = vardesc.elemdescVar_tdesc_vt;
270 if (data.type == OLE.VT_PTR) {
271 short[] vt = new short[1];
272 OS.MoveMemory(vt, vardesc.elemdescVar_tdesc_union + C.PTR_SIZEOF, 2);
275 data.flags = vardesc.wVarFlags;
276 data.kind = vardesc.varkind;
277 data.description = getDocumentation(vardesc.memid);
278 data.helpFile = getHelpFile(vardesc.memid);
280 objITypeInfo.ReleaseVarDesc(ppVarDesc[0]);
284 * Returns the description of a function at the given index.
286 * @param index the index of a function whose property is being retrieved.
287 * @return an OleFunctionDescription for a function at the given index.
289 public OleFunctionDescription getFunctionDescription(int index) {
290 if (objITypeInfo == null) return null;
291 long[] ppFuncDesc = new long[1];
292 int rc = objITypeInfo.GetFuncDesc(index, ppFuncDesc);
293 if (rc != OLE.S_OK) return null;
294 FUNCDESC funcdesc = new FUNCDESC();
295 COM.MoveMemory(funcdesc, ppFuncDesc[0], FUNCDESC.sizeof);
297 OleFunctionDescription data = new OleFunctionDescription();
299 data.id = funcdesc.memid;
300 data.optionalArgCount = funcdesc.cParamsOpt;
301 data.invokeKind = funcdesc.invkind;
302 data.funcKind = funcdesc.funckind;
303 data.flags = funcdesc.wFuncFlags;
304 data.callingConvention = funcdesc.callconv;
305 data.documentation = getDocumentation(funcdesc.memid);
306 data.helpFile = getHelpFile(funcdesc.memid);
308 String[] names = getNames(funcdesc.memid, funcdesc.cParams + 1);
309 if (names.length > 0) {
310 data.name = names[0];
312 data.args = new OleParameterDescription[funcdesc.cParams];
313 for (int i = 0; i < data.args.length; i++) {
314 data.args[i] = new OleParameterDescription();
315 if (names.length > i + 1) {
316 data.args[i].name = names[i + 1];
318 //TODO 0- use structures
319 short[] vt = new short[1];
320 OS.MoveMemory(vt, funcdesc.lprgelemdescParam + i * COM.ELEMDESC_sizeof() + C.PTR_SIZEOF, 2);
321 if (vt[0] == OLE.VT_PTR) {
322 long [] pTypedesc = new long [1];
323 OS.MoveMemory(pTypedesc, funcdesc.lprgelemdescParam + i * COM.ELEMDESC_sizeof(), C.PTR_SIZEOF);
324 short[] vt2 = new short[1];
325 OS.MoveMemory(vt2, pTypedesc[0] + C.PTR_SIZEOF, 2);
326 vt[0] = (short)(vt2[0] | COM.VT_BYREF);
328 data.args[i].type = vt[0];
329 short[] wParamFlags = new short[1];
330 OS.MoveMemory(wParamFlags, funcdesc.lprgelemdescParam + i * COM.ELEMDESC_sizeof() + COM.TYPEDESC_sizeof () + C.PTR_SIZEOF, 2);
331 data.args[i].flags = wParamFlags[0];
334 data.returnType = funcdesc.elemdescFunc_tdesc_vt;
335 if (data.returnType == OLE.VT_PTR) {
336 short[] vt = new short[1];
337 OS.MoveMemory(vt, funcdesc.elemdescFunc_tdesc_union + C.PTR_SIZEOF, 2);
338 data.returnType = vt[0];
341 objITypeInfo.ReleaseFuncDesc(ppFuncDesc[0]);
345 * Returns the type info of the current object referenced by the automation.
346 * The type info contains information about the object such as the function descriptions,
347 * the member descriptions and attributes of the type.
349 * @return the type info of the receiver
351 public TYPEATTR getTypeInfoAttributes() {
352 if (objITypeInfo == null) return null;
353 long [] ppTypeAttr = new long [1];
354 int rc = objITypeInfo.GetTypeAttr(ppTypeAttr);
355 if (rc != OLE.S_OK) return null;
356 TYPEATTR typeattr = new TYPEATTR();
357 COM.MoveMemory(typeattr, ppTypeAttr[0], TYPEATTR.sizeof);
358 objITypeInfo.ReleaseTypeAttr(ppTypeAttr[0]);
362 * Returns the name of the given member ID.
364 * @param dispId the member ID in which the name is being retrieved.
365 * @return the name if it exists; otherwise return null.
367 public String getName(int dispId) {
368 if (objITypeInfo == null) return null;
369 String[] name = new String[1];
370 int rc = objITypeInfo.GetDocumentation(dispId, name, null, null, null );
371 if (rc == OLE.S_OK) return name[0];
375 * Returns the name of a function and parameter names for the specified function ID.
377 * @param dispId the function ID in which the name and parameters are being retrieved.
378 * @param maxSize the maximum number of names to retrieve.
379 * @return an array of name containing the function name and the parameter names
381 public String[] getNames(int dispId, int maxSize) {
382 if (objITypeInfo == null) return new String[0];
383 String[] names = new String[maxSize];
384 int[] count = new int[1];
385 int rc = objITypeInfo.GetNames(dispId, names, maxSize, count);
386 if (rc == OLE.S_OK) {
387 String[] newNames = new String[count[0]];
388 System.arraycopy(names, 0, newNames, 0, count[0]);
391 return new String[0];
394 * Returns the positive integer values (IDs) that are associated with the specified names by the
395 * IDispatch implementor. If you are trying to get the names of the parameters in a method, the first
396 * String in the names array must be the name of the method followed by the names of the parameters.
398 * @param names an array of names for which you require the identifiers
400 * @return positive integer values that are associated with the specified names in the same
401 * order as the names where provided; or null if the names are unknown
403 public int[] getIDsOfNames(String[] names) {
405 int[] rgdispid = new int[names.length];
406 int result = objIDispatch.GetIDsOfNames(new GUID(), names, names.length, COM.LOCALE_USER_DEFAULT, rgdispid);
407 if (result != COM.S_OK) return null;
412 * Returns a description of the last error encountered.
414 * @return a description of the last error encountered
416 public String getLastError() {
418 return exceptionDescription;
422 * Returns the value of the property specified by the dispIdMember.
424 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
425 * value for the ID can be obtained using OleAutomation.getIDsOfNames
427 * @return the value of the property specified by the dispIdMember or null
429 public Variant getProperty(int dispIdMember) {
430 Variant pVarResult = new Variant();
431 int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET, null, null, pVarResult);
432 return (result == OLE.S_OK) ? pVarResult : null;
435 * Returns the value of the property specified by the dispIdMember.
437 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
438 * value for the ID can be obtained using OleAutomation.getIDsOfNames
440 * @param rgvarg an array of arguments for the method. All arguments are considered to be
441 * read only unless the Variant is a By Reference Variant type.
443 * @return the value of the property specified by the dispIdMember or null
447 public Variant getProperty(int dispIdMember, Variant[] rgvarg) {
448 Variant pVarResult = new Variant();
449 int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET, rgvarg, null, pVarResult);
450 return (result == OLE.S_OK) ? pVarResult : null;
454 * Returns the value of the property specified by the dispIdMember.
456 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
457 * value for the ID can be obtained using OleAutomation.getIDsOfNames
459 * @param rgvarg an array of arguments for the method. All arguments are considered to be
460 * read only unless the Variant is a By Reference Variant type.
462 * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
463 * parameter IDs must be in the same order as their corresponding values;
464 * all arguments must have an identifier - identifiers can be obtained using
465 * OleAutomation.getIDsOfNames
467 * @return the value of the property specified by the dispIdMember or null
471 public Variant getProperty(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs) {
472 Variant pVarResult = new Variant();
473 int result = invoke(dispIdMember, COM.DISPATCH_PROPERTYGET, rgvarg, rgdispidNamedArgs, pVarResult);
474 return (result == OLE.S_OK) ? pVarResult : null;
477 public boolean equals(Object object) {
478 if (object == this) return true;
479 if (object instanceof OleAutomation) {
480 if (objIDispatch == null) return false;
481 OleAutomation oleAutomation = ((OleAutomation) object);
482 if (oleAutomation.objIDispatch == null) return false;
483 long address1 = objIDispatch.getAddress();
484 long address2 = oleAutomation.objIDispatch.getAddress();
485 return address1 == address2;
490 * Invokes a method on the OLE Object; the method has no parameters.
492 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
493 * value for the ID can be obtained using OleAutomation.getIDsOfNames
495 * @return the result of the method or null if the method failed to give result information
497 public Variant invoke(int dispIdMember) {
498 Variant pVarResult = new Variant();
499 int result = invoke(dispIdMember, COM.DISPATCH_METHOD, null, null, pVarResult);
500 return (result == COM.S_OK) ? pVarResult : null;
503 * Invokes a method on the OLE Object; the method has no optional parameters.
505 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
506 * value for the ID can be obtained using OleAutomation.getIDsOfNames
508 * @param rgvarg an array of arguments for the method. All arguments are considered to be
509 * read only unless the Variant is a By Reference Variant type.
511 * @return the result of the method or null if the method failed to give result information
513 public Variant invoke(int dispIdMember, Variant[] rgvarg) {
514 Variant pVarResult = new Variant();
515 int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, null, pVarResult);
516 return (result == COM.S_OK) ? pVarResult : null;
519 * Invokes a method on the OLE Object; the method has optional parameters. It is not
520 * necessary to specify all the optional parameters, only include the parameters for which
521 * you are providing values.
523 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
524 * value for the ID can be obtained using OleAutomation.getIDsOfNames
526 * @param rgvarg an array of arguments for the method. All arguments are considered to be
527 * read only unless the Variant is a By Reference Variant type.
529 * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
530 * parameter IDs must be in the same order as their corresponding values;
531 * all arguments must have an identifier - identifiers can be obtained using
532 * OleAutomation.getIDsOfNames
534 * @return the result of the method or null if the method failed to give result information
536 public Variant invoke(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs) {
537 Variant pVarResult = new Variant();
538 int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, rgdispidNamedArgs, pVarResult);
539 return (result == COM.S_OK) ? pVarResult : null;
541 private int invoke(int dispIdMember, int wFlags, Variant[] rgvarg, int[] rgdispidNamedArgs, Variant pVarResult) {
543 // get the IDispatch interface for the control
544 if (objIDispatch == null) return COM.E_FAIL;
546 // create a DISPPARAMS structure for the input parameters
547 DISPPARAMS pDispParams = new DISPPARAMS();
548 // store arguments in rgvarg
549 if (rgvarg != null && rgvarg.length > 0) {
550 pDispParams.cArgs = rgvarg.length;
551 pDispParams.rgvarg = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, VARIANT.sizeof * rgvarg.length);
553 for (int i = rgvarg.length - 1; i >= 0 ; i--) {
554 rgvarg[i].getData(pDispParams.rgvarg + offset);
555 offset += VARIANT.sizeof;
559 // if arguments have ids, store the ids in rgdispidNamedArgs
560 if (rgdispidNamedArgs != null && rgdispidNamedArgs.length > 0) {
561 pDispParams.cNamedArgs = rgdispidNamedArgs.length;
562 pDispParams.rgdispidNamedArgs = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, 4 * rgdispidNamedArgs.length);
564 for (int i = rgdispidNamedArgs.length; i > 0; i--) {
565 OS.MoveMemory(pDispParams.rgdispidNamedArgs + offset, new int[] {rgdispidNamedArgs[i-1]}, 4);
571 EXCEPINFO excepInfo = new EXCEPINFO();
572 int[] pArgErr = new int[1];
573 long pVarResultAddress = 0;
574 if (pVarResult != null) pVarResultAddress = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof);
575 int result = objIDispatch.Invoke(dispIdMember, new GUID(), COM.LOCALE_USER_DEFAULT, wFlags, pDispParams, pVarResultAddress, excepInfo, pArgErr);
577 if (pVarResultAddress != 0){
578 pVarResult.setData(pVarResultAddress);
579 COM.VariantClear(pVarResultAddress);
580 OS.GlobalFree(pVarResultAddress);
583 // free the Dispparams resources
584 if (pDispParams.rgdispidNamedArgs != 0){
585 OS.GlobalFree(pDispParams.rgdispidNamedArgs);
587 if (pDispParams.rgvarg != 0) {
589 for (int i = 0, length = rgvarg.length; i < length; i++){
590 COM.VariantClear(pDispParams.rgvarg + offset);
591 offset += VARIANT.sizeof;
593 OS.GlobalFree(pDispParams.rgvarg);
596 // save error string and cleanup EXCEPINFO
597 manageExcepinfo(result, excepInfo);
602 * Invokes a method on the OLE Object; the method has no parameters. In the early days of OLE,
603 * the IDispatch interface was not well defined and some applications (mainly Word) did not support
604 * a return value. For these applications, call this method instead of calling
605 * <code>public void invoke(int dispIdMember)</code>.
607 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
608 * value for the ID can be obtained using OleAutomation.getIDsOfNames
610 * @exception org.eclipse.swt.SWTException <ul>
611 * <li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
614 public void invokeNoReply(int dispIdMember) {
615 int result = invoke(dispIdMember, COM.DISPATCH_METHOD, null, null, null);
616 if (result != COM.S_OK)
617 OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
620 * Invokes a method on the OLE Object; the method has no optional parameters. In the early days of OLE,
621 * the IDispatch interface was not well defined and some applications (mainly Word) did not support
622 * a return value. For these applications, call this method instead of calling
623 * <code>public void invoke(int dispIdMember, Variant[] rgvarg)</code>.
625 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
626 * value for the ID can be obtained using OleAutomation.getIDsOfNames
628 * @param rgvarg an array of arguments for the method. All arguments are considered to be
629 * read only unless the Variant is a By Reference Variant type.
631 * @exception org.eclipse.swt.SWTException <ul>
632 * <li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
635 public void invokeNoReply(int dispIdMember, Variant[] rgvarg) {
636 int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, null, null);
637 if (result != COM.S_OK)
638 OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
641 * Invokes a method on the OLE Object; the method has optional parameters. It is not
642 * necessary to specify all the optional parameters, only include the parameters for which
643 * you are providing values. In the early days of OLE, the IDispatch interface was not well
644 * defined and some applications (mainly Word) did not support a return value. For these
645 * applications, call this method instead of calling
646 * <code>public void invoke(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs)</code>.
648 * @param dispIdMember the ID of the method as specified by the IDL of the ActiveX Control; the
649 * value for the ID can be obtained using OleAutomation.getIDsOfNames
651 * @param rgvarg an array of arguments for the method. All arguments are considered to be
652 * read only unless the Variant is a By Reference Variant type.
654 * @param rgdispidNamedArgs an array of identifiers for the arguments specified in rgvarg; the
655 * parameter IDs must be in the same order as their corresponding values;
656 * all arguments must have an identifier - identifiers can be obtained using
657 * OleAutomation.getIDsOfNames
659 * @exception org.eclipse.swt.SWTException <ul>
660 * <li>ERROR_ACTION_NOT_PERFORMED when method invocation fails
663 public void invokeNoReply(int dispIdMember, Variant[] rgvarg, int[] rgdispidNamedArgs) {
664 int result = invoke(dispIdMember, COM.DISPATCH_METHOD, rgvarg, rgdispidNamedArgs, null);
665 if (result != COM.S_OK)
666 OLE.error(OLE.ERROR_ACTION_NOT_PERFORMED, result);
668 private void manageExcepinfo(int hResult, EXCEPINFO excepInfo) {
670 if (hResult == COM.S_OK){
671 exceptionDescription = "No Error"; //$NON-NLS-1$
675 // extract exception info
676 if (hResult == COM.DISP_E_EXCEPTION) {
677 if (excepInfo.bstrDescription != 0){
678 int size = COM.SysStringByteLen(excepInfo.bstrDescription);
679 char[] buffer = new char[(size + 1) /2];
680 OS.MoveMemory(buffer, excepInfo.bstrDescription, size);
681 exceptionDescription = new String(buffer);
683 exceptionDescription = "OLE Automation Error Exception "; //$NON-NLS-1$
684 if (excepInfo.wCode != 0){
685 exceptionDescription += "code = "+excepInfo.wCode; //$NON-NLS-1$
686 } else if (excepInfo.scode != 0){
687 exceptionDescription += "code = "+excepInfo.scode; //$NON-NLS-1$
691 exceptionDescription = "OLE Automation Error HResult : " + hResult; //$NON-NLS-1$
694 // cleanup EXCEPINFO struct
695 if (excepInfo.bstrDescription != 0)
696 COM.SysFreeString(excepInfo.bstrDescription);
697 if (excepInfo.bstrHelpFile != 0)
698 COM.SysFreeString(excepInfo.bstrHelpFile);
699 if (excepInfo.bstrSource != 0)
700 COM.SysFreeString(excepInfo.bstrSource);
703 * Sets the property specified by the dispIdMember to a new value.
705 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
706 * value for the ID can be obtained using OleAutomation.getIDsOfNames
707 * @param rgvarg the new value of the property
709 * @return true if the operation was successful
711 public boolean setProperty(int dispIdMember, Variant rgvarg) {
712 Variant[] rgvarg2 = new Variant[] {rgvarg};
713 int[] rgdispidNamedArgs = new int[] {COM.DISPID_PROPERTYPUT};
714 int dwFlags = COM.DISPATCH_PROPERTYPUT;
715 if ((rgvarg.getType() & COM.VT_BYREF) == COM.VT_BYREF)
716 dwFlags = COM.DISPATCH_PROPERTYPUTREF;
717 Variant pVarResult = new Variant();
718 int result = invoke(dispIdMember, dwFlags, rgvarg2, rgdispidNamedArgs, pVarResult);
719 return (result == COM.S_OK);
722 * Sets the property specified by the dispIdMember to a new value.
724 * @param dispIdMember the ID of the property as specified by the IDL of the ActiveX Control; the
725 * value for the ID can be obtained using OleAutomation.getIDsOfNames
726 * @param rgvarg an array of arguments for the method. All arguments are considered to be
727 * read only unless the Variant is a By Reference Variant type.
729 * @return true if the operation was successful
733 public boolean setProperty(int dispIdMember, Variant[] rgvarg) {
734 int[] rgdispidNamedArgs = new int[] {COM.DISPID_PROPERTYPUT};
735 int dwFlags = COM.DISPATCH_PROPERTYPUT;
736 for (int i = 0; i < rgvarg.length; i++) {
737 if ((rgvarg[i].getType() & COM.VT_BYREF) == COM.VT_BYREF)
738 dwFlags = COM.DISPATCH_PROPERTYPUTREF;
740 Variant pVarResult = new Variant();
741 int result = invoke(dispIdMember, dwFlags, rgvarg, rgdispidNamedArgs, pVarResult);
742 return (result == COM.S_OK);