从 UNO 中使用 Automation 对象

From Apache OpenOffice Wiki
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 函数。要调用方法,需要使用 invoke。也可使用 invoke 来访问带有附加参数的属性。方法 setValuegetValue 可以设定或获取属性值。这些方法只能与不带有附加参数的属性一起使用。

对于表示方法或带有参数的属性的名称,hasMethod 将返回 true。最后,对于表示不带有参数的属性的名称,hasProperty 将返回 true。有关 XInvocation 的详细信息,请参阅 IDL 文档。

带有参数的属性

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

桥必须识别针对属性的写操作。为此,调用程序必须在类型 com.sun.star.bridge.oleautomation.PropertyPutArgument 的结构中提供实际的属性值(而不是附加参数)。与 IDispatch::Invoke 类似,属性值必须是参数列表中的最后一个。例如:

 // 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);


在 StarBasic 中,隐式使用 PropertyPutArgument

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

在属性 get 操作中获取的属性值是 invoke 返回的值。


可选参数、默认值、可变参数列表

桥支持所有这些特殊参数。可选参数可以不列入 invoke 的参数列表。但是,如果某个值被忽略,则也必须忽略参数列表中其后面的所有参数。这仅适用于定位参数,而不适用于命名参数。

如果 Automation 对象为可选参数指定了默认值,而调用程序没有提供任何参数,则桥将提供该默认值。

如果某方法接受可变参数列表,则可以提供相应的 UNO 参数作为普通的 invoke 参数。IDispatch::Invoke 要求 SAFEARRAY 中包含这些参数。


命名参数

要在 invoke 调用中提供命名参数,每个参数都必须使用 com.sun.star.bridge.oleautomation.NamedArgument 实例。以下是 UNO IDL 中的结构:

 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;
 }; 
 
 }; }; }; }; }; 

在调用中,可以同时使用命名参数和定位参数。其顺序是:首先是 定位参数(普通参数),然后是命名参数。如果使用命名参数,即使忽略的参数后提供了参数,也可以忽略此参数。例如,假定某个方法接受 5 个参数(都是可选参数),则 XInvocation 的参数列表可以有如下形式:

  • 全部提供:{A, B, C, D, E}
  • 忽略的参数: {A,B,C,D} 或 {A,B} 但不是 {A, C, D}
  • 命名参数:{nA, nC, nB, nD}, {nC, nD}
  • 混合参数:{ A, B, nD}, {A, nC}

命名参数也可以与带有附加参数的属性一起使用。但是,属性值本身不可以是命名参数,因为属性已被认为是命名参数。因此,它始终是最后一个参数。

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