从 UNO 中使用 Automation 对象

From Apache OpenOffice Wiki
< Zh‎ | Documentation
Revision as of 09:26, 9 July 2008 by Jirong (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


该语言绑定提供了一种从 UNO 访问 Automation 对象的途径。为了能够使用 Automation 对象,必须在系统中正确注册该对象,并且必须有一个可用于创建实例的编程标识符 (ProgId)。在 UNO 中,所有 Automation 对象都是通过 com.sun.star.script.XInvocation 进行访问。XInvocation 是一个脚本接口,主要用于动态执行 IDispatch 之类的调用。由于 StarBasic 使用 XInvocation 与对象进行通信,因此可以在 StarBasic 中使用 Automation 对象。


实例化

要获取 Automation 对象的实例,最简便的方法是使用服务 com.sun.star.bridge.oleautomation.Factory。其中包含的 XMultiServiceFactory 接口可用于获取所需的对象。例如:

 //C++
 
 Reference<XInterface> xInt = serviceManager->createInstance(
 OUString::createFromAscii("com.sun.star.bridge.oleautomation.Factory"));
 
 Reference<XMultiServiceFactory> automationFactory(xInt, UNO_QUERY);
 
 if(automationFactory.is())
 {
     Reference<XInterface> xIntApp = automationFactory->createInstance(
       OUString::createFromAscii("Word.Application"));
 
     Reference< XInvocation > xInvApp( xIntApp, UNO_QUERY);
     // call methods on the Automation object.
     ...
 }


相比之下在 StarBasic 中就简单的多:

 'StarBasic
 
 Dim automationFactory As Object
 Set automationFactory = createUnoService("com.sun.star.bridge.oleautomation.Factory")
 
 Dim objApp As Objects
   Set objApp = automationFactory.createInstance("Word.Application")
 'call methods on the Automation object


访问 Automation 对象

所有 Automation 对象都是通过 com.sun.star.script.XInvocation 接口进行访问。尚未实现 getIntrospection 函数。要调用方法,需要使用 invokeinvoke。也可使用 invoke 来访问带有附加参数的属性。方法 setValuegetValue 可以设定或获取属性值。这些方法只能与不带有附加参数的属性一起使用。

对于表示方法或带有参数的属性的名称,hasMethod 将返回 true。最后,对于表示不带有参数的属性的名称,hasProperty 将返回 true。有关 带有参数的属性

与 UNO 属性不同,Automation 属性可以包含参数。因此,setValuegetValue 方法就不适用于这些属性。而是会使用 invoke。如果某个属性接受参数,则 hasProperty 返回 false,hasMethod 返回 true。如果属性的参数可选且未在调用中提供,则还必须使用 invoke

桥必须识别针对属性的写操作。为此,调用程序必须在类型 com.sun.star.bridge.oleautomation.PropertyPutArgument 的结构中提供实际的属性值(而不是附加参数)。与 IDispatch::Invoke 类似,属性值必须是参数列表中的最后一个。例如: The bridge must recognize a write operation on a property/ To achieve this, the caller has to provide the actual property value (not additional arguments) in a structure of type com.sun.star.bridge.oleautomation.PropertyPutArgument/ Similar to IDispatch::Invoke, the property value must be the last in the argument list/ For example:

 // MIDL 
 [propget,///] HRESULT Item([in] VARIANT val1, [out, retval] VARIANT* pVal);
 [propput,///] HRESULT Item([in] VARIANT val1, [in] VARIANT newVal);
 
 // C++
 Sequence< sal_Int16> seqIndices;
 Sequence<Any> seqOut;
 //Prepare arguments
 Any arArgs[2];
 arArgs[0] <<= makeAny((sal_Int32) 0);
 arArgs[1] <<= PropertyPutArgument(makeAny((sal_Int32) 0));
 Sequence<Any> seqArgs(arArgs, 2);
 
 //obj is a XInvocation of an Automation object
 obj->invoke(OUString::createFromAscii("Item"), seqArgs, seqIndices, seqOut);
 
 //now get the property value
 Any arGet[1];
 arGet[0] <<= makeAny((sal_Int32) 0);
 Sequence<Any> seqGet(arGet, 1);
 Any retVal = obj->invoke(OUString::createFromAscii("Item"), seqGet, seqIndices, seqOut);

In StarBasic, PropertyPutArgument.html" class="external text">XInvocation</idls 的详细信息,请参阅 IDL 文档。


带有参数的属性

与 UNO 属性不同,Automation 属性可以包含参数。因此,setValuegetValue 方法就不适用于这些属性。而是会使用 invoke。如果某个属性接受参数,则 hasProperty 返回 false,hasMethod 返回 true。如果属性的参数可选且未在调用中提供,则还必须使用 invoke

桥必须识别针对属性的写操作。为此,调用程序必须在类型 com.sun.star.bridge.oleautomation.PropertyPutArgument 的结构中提供实际的属性值(而不是附加参数)。与 IDispatch::Invoke 类似,属性值必须是参数列表中的最后一个。例如: The bridge must recognize a write operation on a property. To achieve this, the caller has to provide the actual property value (not additional arguments) in a structure of type com.sun.star.bridge.oleautomation.PropertyPutArgument. Similar to IDispatch::Invoke, the property value must be the last in the argument list. For example:

 // MIDL 
 [propget,...] HRESULT Item([in] VARIANT val1, [out, retval] VARIANT* pVal);
 [propput,...] HRESULT Item([in] VARIANT val1, [in] VARIANT newVal);
 
 // C++
 Sequence< sal_Int16> seqIndices;
 Sequence<Any> seqOut;
 //Prepare arguments
 Any arArgs[2];
 arArgs[0] <<= makeAny((sal_Int32) 0);
 arArgs[1] <<= PropertyPutArgument(makeAny((sal_Int32) 0));
 Sequence<Any> seqArgs(arArgs, 2);
 
 //obj is a XInvocation of an Automation object
 obj->invoke(OUString::createFromAscii("Item"), seqArgs, seqIndices, seqOut);
 
 //now get the property value
 Any arGet[1];
 arGet[0] <<= makeAny((sal_Int32) 0);
 Sequence<Any> seqGet(arGet, 1);
 Any retVal = obj->invoke(OUString::createFromAscii("Item"), seqGet, seqIndices, seqOut);

In StarBasic, PropertyPutArgument is implicitly used:

 'StarBasic
 
 obj.Item(0) = 0
 
 Dim propval As Variant
 propval = obj.Item(0)

The property value that is obtained in a property get operation is the return value of invoke.

Optional Parameters, Default Values, Variable Argument Lists

The bridge supports all these special parameters. Optional parameters can be left out of the argument list of invoke. However, if a value is omitted, then all following arguments from the parameter list must also be omitted. This only applies for positional arguments and not for named arguments.

If the Automation object specifies a default value for an optional parameter, then the bridge supplies it, if no argument was provided by the caller.

If a method takes a variable argument list, then one can provide the respective UNO arguments as ordinary arguments to invoke. IDispatch::Invoke would require those arguments in a SAFEARRAY.

Named Arguments

To provide named arguments in an invoke call, one has to use instances of com.sun.star.bridge.oleautomation.NamedArgument for each argument. This is the struct in UNOIDL:

 module com { module sun { module star { module bridge { module oleautomation {
 struct NamedArgument
 {
     /** The name of the argument, for which
     <member>NamedArgument::Value</member> is intended.
     */
     string Name;
 
     /** The value of the argument whoose name is the one as contained in the
     member <member>Name</member>.
     */
     any Value;
 }; 
 
 }; }; }; }; }; 

In a call both, named arguments and positional arguments can be used together. The order is, first the positional arguments (the ordinary arguments), followed by named arguments. When named arguments are used, then arguments can be omitted even if arguments are provided that follow the omitted parameter. For example, assume that a method takes five arguments, which are all optional, then the argument lists for XInvocation could be as follows:

  • all provided: {A, B, C, D, E}
  • arguments omitted: {A,B,C,D} or {A,B} but not {A, C, D}
  • named arguments : {nA, nC, nB, nD}, {nC, nD}
  • mixed arguments: { A, B, nD}, {A, nC}

Named arguments can also be used with properties that have additional arguments. However, the property value itself cannot be a named argument, since it is already regarded as a named argument. Therefore, is is always the last argument.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages