libreOffice API是用于访问libreOffice的编程接口。可以使用libreOffice API创建、打开、修改和打印libreOffice文档。
LibreOffice API支持Basic、Java、C/C++、Javascript、Python语言。
这是通过一种称为通用网络对象 (Universal Network Objects, UNO) 的技术实现的,该技术可以为各种编程语言提供接口。
https://api.libreoffice.org/docs/idl/ref/index.html
一、uno概念
(一)类型
uno类型使用一种称为UNOIDL(UNO接口定义语言)的语言定义,这种语言与CORBA IDL或MIDL类似。
1.简单类型
UNO类型 | 说明 |
---|---|
void | 空类型,仅在any中用作方法返回类型。 |
boolean | 可以是true或false。 |
byte | 有符号的8位整数类型(范围从 -128到127,包括上下限)。 |
short | 有符号的16位整数类型(范围从 -32768到32767,包括上下限)。 |
unsigned short | 无符号的16位整数类型(已不再使用)。 |
long | 有符号的32位整数类型(范围从 -2147483648到2147483647,包括上下限)。 |
unsigned long | 无符号的32位整数类型(已不再使用)。 |
hyper | 有符号的64位整数类型(范围从 -9223372036854775808到9223372036854775807,包括上下限)。 |
unsigned hyper | 无符号的64位整数类型(已不再使用)。 |
float | IEC 60559单精度浮点类型。 |
double | IEC 60559双精度浮点类型。 |
char | 表示单个的Unicode字符(更确切地说是单个的UTF-16代码单元)。 |
string | 表示Unicode字符串(更确切地说是Unicode标量值的字符串)。 |
type | 说明所有UNO类型的元类型。 |
any | 能够表示其他所有类型值的特殊类型。 |
2.struct 类型
结构体包括一堆数据成员,但不能包括方法。
结构体支持单继承。
struct EventObject{
com::sun::star::uno::XInterface Source;
};
struct PropertyChangeEvent : com::sun::star::lang::EventObject {
string PropertyName;
boolean Further;
long PropertyHandle;
any OldValue;
any NewValue;
};
3.sequence
序列就是一个动态数组。就像c++的vector
sequence< com::sun::star::uno::XInterface >
sequence< string > getNamesOfIndex( sequence< long > indexes );
4.interface类型
接口就是个抽象类。接口是一系列方法的声明,一个接口只有方法的声明没有方法的实现,因此这些方法可以在不同的类实现,而这些实现可以是不同的行为。
严格说来,UNO服务不支持方法,方法只在接口中,而服务继承了接口。
因为不同的服务会继承相同接口,所以如果您熟悉某个接口,便可以迅速了解不同服务。
按照约定,所有接口名称都以字母X开头,以将接口类型与其他类型区分开来。所有接口类型最终都必须继承com.sun.star.uno.XInterface根接口
interface XInterface {
any queryInterface( [in] type aType );
[oneway] void acquire();
[oneway] void release();
};
interface XInputStream: com::sun::star::uno::XInterface {
long readBytes( [out] sequence
raises( com::sun::star::io::NotConnectedException, com::sun::star::io::BufferSizeExceededException, com::sun::star::io::IOException);
...
};
方法
就是接口的成员函数
Document.Save()
5.service
接口定义了方法;结构定义了数据;服务将它们组合在一起。
服务相当于类,不知道为啥非得叫服务。
通过服务,可以创建对象实例。
com.sun.star.frame.Desktop类似于一种对象类型,但在UNO术语中,将其称为“服务”而不是“类型”。按照UNO术语,Obj是支持com.sun.star.frame.Desktop服务的对象。因此,libreOffice Basic中使用的“服务”术语与其他编程语言中使用的“类型”和“类”术语相对应。
但存在一个主要区别:uno可以同时支持多种服务。例如,上面提到的obj对象不仅支持com.sun.star.frame.Desktop服务,还可以包括用于加载文档和结束程序的其他服务。
服务包括新式服务和旧式服务。
新式服务是通过仅支持一个多继承接口,该多继承接口再继承其他接口实现的
旧式服务是直接支持多个单继承接口实现的
新式服务
service SomeService: XSomeInterface;
interface XSomeInterface
{
interface XInterface1;
interface XInterface2;
interface XInterface3;
...
};
旧式服务
service SomeService{
interface XInterface1;
interface XInterface2;
interface XInterface3;
...
};
旧式服务可以包括其他旧式服务。如下例
service Paragraph
{
service com::sun::star::text::TextContent;
[optional] service com::sun::star::text::TextTable;
[optional] service com::sun::star::style::ParagraphProperties;
[optional] service com::sun::star::style::CharacterProperties;
[optional] service com::sun::star::style::CharacterPropertiesAsian;
[optional] service com::sun::star::style::CharacterPropertiesComplex;
...
};
如果上面示例中的所有旧式服务都使用多继承接口类型代替,则结构类似:
service Paragraph: XParagraph;
interface XParagraph
{
interface XTextContent;
[optional] interface XTextTable;
...
};
从用户的角度来看,无论对象提供一项服务或者多项服务,是新式还是旧式服务,由于方法仅由接口提供,因此,用户无需关心如何实现。
属性
属性是服务中的数据
(1)真实属性
就是服务的数据成员
Document.Title = "Basic Programmer's Guide"
Document.Filename = "basguide.odt"
(2)模拟属性
模拟属性就是通过get和set方法模拟的。
所以其实有两种方式访问属性:
通过Position属性直接访问。
通过getPosition和setPosition间接访问
旧式服务可直接列出支持的属性。
下面的旧式服务引用了一个接口和三个可选属性。属性可以是任何类型:
service TextContent{
interface com::sun::star::text::XTextContent;
[optional, property] com::sun::star::text::TextContentAnchorType AnchorType;
[optional, readonly, property] sequence
[optional, property] com::sun::star::text::WrapTextMode TextWrap;
};
6.预定义值
预定义值有两种不同的数据类型:常数和枚举。
const
const 定义有效UNO IDL类型的命名值。值取决于指定的类型,可以是常值(整数、浮点数或字符)、另一个const类型的标识符或包含以下运算符的算术项:+、-、*、/、~、&、|、%、^、 <<、>>。
由于可以在 const 中广泛选择类型和值,因此,const 有时用于生成对合并的值进行编码的位矢量。
const short ID = 23;
const boolean ERROR = true;
const double PI = 3.1415;
通常情况下,const定义是常数组的一部分。
constants
constants 类型定义的是包含多个 const 值的一个命名组。constants 组中的 const 用组名称加上 const 名称表示。在下面的UNO IDL示例中,ImageAlign.RIGHT 指的是值2:
constants ImageAlign {
const short LEFT = 0;
const short TOP = 1;
const short RIGHT = 2;
const short BOTTOM = 3;
};
enum
enum 类型与C++ 中的枚举类型相当。它包含一个已排序列表,列表中有一个或多个标识符,代表 enum 类型的各个值。默认情况下,值按顺序编号,以0开头,每增加一个新值就增加1。如果给某个 enum 值指定了一个值,则没有预定义值的所有后续 enum 值都以此指定值为基准来获得值。
// com.sun.star.uno.TypeClass
enum TypeClass {
VOID,
CHAR,
BOOLEAN,
BYTE,
SHORT,
...
};
enum Error {
SYSTEM = 10, // value 10
RUNTIME, // value 11
FATAL, // value 12
USER = 30, // value 30
SOFT // value 31
};
7.module
模块是命名空间,与C++ 中的命名空间或Java中的包类似
模块将服务、接口等类型组合在一起。形成良好的组织结构。
所以完整的类型名称由以下部分组成:com.sun.star是共同的模块名称,然后是特定模块名称,最后是实际的类型名称。
例如,服务Desktop的完整名称为:com.sun.star.frame.Desktop
接口XTextContent的完整名称为:com.sun.star.text.XTextContent
模块 com.sun.star.uno 包含接口 XInterface,IDL写法如下:
module com {module sun {module star {module uno {
interface XInterface {
...
};};};};};
(二)对象
广义的对象就是各种类型的实例。
狭义的对象只是服务的实例。
二、libreoffice basic语言绑定
语言绑定就是如何使用某种语言调用uno。
语言绑定有时称为UNO运行时环境 ( URE)。
uno支持c++、java、python、libreoffice basic语言绑定。
我们现在使用libreoffice basic语言,所以下面要讲解libreoffice basic绑定。
主要是下面这些
BasicLibraries | ccess Basic libraries stored in a document. |
CreateObject(obj_type) |
Able to create any standard type, more flexible than CreateUnoStruct and CreateUnoService. |
CreateUnoDialog() | Create an existing dialog. |
CreateUnoListener() | Create a listener. |
CreateUnoService() | Create a Universal Network Object Service. |
CreateUnoStruct() | Create a Universal Network Object Structure. |
CreateUnoValue() | Create a Universal Network Object value. |
DialogLibraries | Access dialog libraries stored in a document. |
EqualUNOObjects() | Determine if two UNO objects reference the same instance. |
FindObject() | Find a named object; do not use. |
FindPropertyObject() | Find object property based on name; do not use. |
GetDefaultContext() | Get a copy of the default context. |
GetProcessServiceManager() | Get service manager. |
GlobalScope | Application-level libraries. |
HasUnoInterfaces() | Does an object support specified interfaces? |
IsUnoStruct() | Is this variable a Universal Network Object? |
StarDesktop |
Special variable representing the desktop object. |
ThisComponent | Special variable representing the current document. |
(一)类型
Basic和UNO使用不同的类型系统,有必要映射这两种类型系统。
下面讲basic定义和使用各种类型变量
(1)简单类型
UNO | Basic |
---|---|
void | 内部类型 |
boolean | Boolean |
byte | Integer |
short | Integer |
unsigned short | 内部类型 |
long | Long |
unsigned long | 内部类型 |
hyper | 内部类型 |
unsigned hyper | 内部类型 |
float | Single |
double | Double |
char | 内部类型 |
string | String |
type | com.sun.star.reflection.XIdlClass |
any | Variant |
Basic类型系统并不严格。与C++ 和Java不同,Basic不要求声明变量,未声明的变量为Variant。
在未指定类型的情况下,声明的所有变量都为 Variant 类型。可以将任意Basic类型的值指定给类型为 Variant 的变量。
为了方便,尽量使用Variant类型,而且不必声明变量。
因为Basic会自动转换到uno类型。
当Basic不知道目标uno类型时,尤其是类型为any时。在这种情况下,Basic会机械地将Basic类型转换成上表中所示的UNO类型。Basic提供的唯一机制是自动向下转换数值:
Long和Integer值通常转换为尽可能短的整数类型:
如果Single/Double值不带小数位,则以同样的方式转换为整数。
(2)结构
可以通过Dim As New创建结构实例
' Instantiate a Property struct
Dim aProperty As New com.sun.star.beans.Property
' Instantiate an array of Locale structs
Dim Locales(10) As New com.sun.star.lang.Locale
也可以使用CreateUnoStruct函数创建UNO结构实例
Dim aProp
aProp = CreateUnoStruct("com.sun.star.beans.PropertyValue")
aProp.Name = "FirstName" 'Set the Name property
aProp.Value = "Andrew" 'Set the Value property
函数CreateUnoStruct过去是创建UNO结构的唯一方法。自从引入“Dim As New”语法,它很少使用了。
CreateObject函数比CreateUnoStruct更通用。它能够创建所有类型的实例。这包括用户定义的类型。
Dim aProp
aProp = CreateObject("com.sun.star.beans.PropertyValue")
aProp.Name = "FirstName" 'Set the Name property
aProp.Value = "Paterton" 'Set the Value property
创建用户定义类型实例
Type PersonType
FirstName As String
LastName As String
End Type
Sub ExampleCreateNewType
Dim Person As PersonType
Person.FirstName = "Andrew"
Person.LastName = "Pitonyak"
PrintPerson(Person)
Dim Me As Object
Me = CreateObject("PersonType")
Me.FirstName = "Andy"
Me.LastName = "Pitonyak"
PrintPerson(Me)
End Sub
Sub PrintPerson(x)
Print "Person = " & x.FirstName & " " & x.LastName
End Sub
对于用户定义的类型,“Dim As New”和“Dim As”都可以使用。但是,对于UNO结构, 你必须使用Dim As New
CreateObject与CreateUnoStruct有相同的参数,但它适用于所有支持的类型, 而CreateUnoStruct仅适用于UNO结构。所以尽量使用CreateObject。
可以使用 . 运算符访问结构成员。
结构支持Dbg_Properties属性。不支持属性Dbg_SupportedInterfaces和Dbg_Methods:
' Instantiate a Locale struct
Dim aLocale As New com.sun.star.lang.Locale
' Display properties
MsgBox aLocale.Dbg_Properties
' Access“Language”property
aLocale.Language = "en"
服务实例与结构实例不同。服务实例使用引用传递,而结构实例使用值传递。
在以下示例中,oExample是一个服务实例,具有属性MyObject和MyStruct。
oExample.MyObject.ObjectName和oExample.MyStruct.StructName都应该修改。
' Accessing the object
Dim oObject
oObject = oExample.MyObject
oObject.ObjectName = “Tim” ' Ok!
' or shorter
oExample.MyObject.ObjectName = “Tim” ' Ok!
' Accessing the struct
Dim aStruct
aStruct = oExample.MyStruct ' aStruct is a copy of oExample.MyStruct!
aStruct.StructName = “Tim” ' Affects only the property of the copy!
' If the code ended here, oExample.MyStruct wouldn't be modified!
oExample.MyStruct = aStruct ' Copy back the complete struct! Now it's ok!
' Here the other variant does NOT work at all, because
' only a temporary copy of the struct is modified!
oExample.MyStruct.StructName = “Tim” ' WRONG! oExample.MyStruct is not modified!
测试对象是否为一个结构
使用IsUnoStruct检查对象是否为UNO结构
Dim aProperty As New com.sun.star.beans.Property
bIsStruct = IsUnoStruct( aProperty )
MsgBox bIsStruct ' Displays True because aProperty is a struct
bIsStruct = IsUnoStruct( 42 )
MsgBox bIsStruct ' Displays False because 42 is NO struct
(3)序列和数组映射
Basic中,与序列相对应的是数组。数组是Basic语言的标准元素。
当UNO需要一个序列时,Basic程序员可以使用一个相应的数组。在以下示例中,oSequenceContainer是一个对象,其具有一个类型为sequence
Dim i%, a%( 9 ) ' Maximum index 9 -> 10 elements
for i% = 0 to 9 ' this loop initializes the array
a%(i%) = i%
next i%
oSequenceContainer.TheSequence = a%()
' If“TheSequence”is based on XPropertySet alternatively
oSequenceContainer.setPropertyValue( “TheSequence”, a%() )
Basic程序员在编程时,需要了解不同的索引语义。在以下示例中,程序员传送包含一个元素的序 列,但实际上传送了两个元素:
' Pass a sequence of length 1 to the TheSequence property:
Dim a%( 1 ) ' WRONG: The array has 2 elements, not only 1!
a%( 0 ) = 3 ' Only Element 0 is initialized,
' Element 1 remains 0 as initialized by Dim
' Now a sequence with two values (3,0) is passed what
' may result in an error or an unexpected behavior!
oSequenceContainer.setPropertyValue( “TheSequence”, a%() )
将Basic数组作为一个整体用于参数或用于属性访问时,在Basic代码中数组后面应始终跟有 '()',否则,某些情况下可能会发生错误。 |
使用一个称为Array()的Basic函数,通过一步就可以创建、初始化数组并将它指定给Variant变量,这非常有用,尤其是对于小型序列:
Dim a ' should be declared as Variant
a = Array( 1, 2, 3 )
' is the same as
Dim a(2)
a( 0 ) = 1
a( 1 ) = 2
a( 2 ) = 3
有时,有必要将空序列传送到UNO接口。在Basic中,可以通过在Dim命令中忽略索引来声明空序列:
Dim a%() ' empty array/sequence of type Integer
Dim b$() ' empty array/sequence of String
UNO返回的序列在Basic中也表示为数组,但不必事先声明这些数组。应该将用于接受序列的变量声明为Variant。要访问UNO返回的数组,需要LBound() 和UBound() 获得元素索引。
函数LBound() 返回下限索引,而UBound() 返回上限索引。以下代码示意了一个循环,该循环将遍历所返回序列的所有元素:
Dim aResultArray ' should be declared as Variant
aResultArray = oSequenceContainer.TheSequence
dim i%, iFrom%, iTo%
iFrom% = LBound( aResultArray() )
iTo% = UBound( aResultArray() )
for i% = iFrom% to iTo% ' this loop displays all array elements
msgbox aResultArray(i%)
next i%
UNO返回序列的索引通常从0开始。一般仅使用UBound(),这时上面的示例可以简化为:
Dim aResultArray ' should be declared as Variant
aResultArray = oSequenceContainer.TheSequence
Dim i%, iTo%
iTo% = UBound( aResultArray() )
For i% = 0 To iTo% ' this loop displays all array elements
MsgBox aResultArray(i%)
Next i%
序列/数组的元素数目非常容易计算:
u% = UBound( aResultArray() )
ElementCount% = u% + 1
对于空数组/序列,UBound返回 -1。这样,随后按如下所示计算元素数目时,UBound的语义就可以保持一致:
ElementCount% = u% + 1' = -1 + 1 = 0
UNO序列与Basic数组之间的映射前提二者都使用一个基于零的索引系统。为了避免出现问题,不要使用语法Dim a ( IndexMin to IndexMin ) 或Basic命令Option Base 1。这二者使所有Basic数组的索引都不是从0开始。 |
UNO还支持包含序列的序列。在Basic中,这对应于包含数组的数组。不要将包含序列的序列与多维数组相混淆。在多维数组中,所有子数组始终具有相同数目的元素,而在包含序列的序列中,每个序列可以具有不同的大小。示例:
Dim aArrayOfArrays ' should be declared as Variant
aArrayOfArrays = oExample.ShortSequences ' returns a sequence of sequences of short
Dim i%, NumberOfSequences%
Dim j%, NumberOfElements%
Dim aElementArray
NumberOfSequences% = UBound( aArrayOfArrays() ) + 1
For i% = 0 to NumberOfSequences% - 1' loop over all sequences
aElementArray = aArrayOfArrays( i% )
NumberOfElements% = UBound( aElementArray() ) + 1
For j% = 0 to NumberOfElements% - 1 ' loop over all elements
MsgBox aElementArray( j% )
Next j%
Next i%
要在Basic中创建一个包含数组的数组,可以将子数组作为主数组的元素::
' Declare master array
Dim aArrayOfArrays( 2 )
' Declare sub arrays
Dim aArray0( 3 )
Dim aArray1( 2 )
Dim aArray2( 0 )
' Initialise sub arrays
aArray0( 0 ) = 0
aArray0( 1 ) = 1
aArray0( 2 ) = 2
aArray0( 3 ) = 3
aArray1( 0 ) = 42
aArray1( 1 ) = 0
aArray1( 2 ) = -42
aArray2( 0 ) = 1
' Assign sub arrays to the master array
aArrayOfArrays( 0 ) = aArray0()
aArrayOfArrays( 1 ) = aArray1()
aArrayOfArrays( 2 ) = aArray2()
' Assign the master array to the array property
oExample.ShortSequences = aArrayOfArrays()
在这种情况下,运行时函数Array() 非常有用。这样,示例代码就可以变得更加简练:
' Declare master array
Dim aArrayOfArrays( 2 )
' Create and assign sub arrays
aArrayOfArrays( 0 ) = Array( 0, 1, 2, 3 )
aArrayOfArrays( 1 ) = Array( 42, 0, -42 )
aArrayOfArrays( 2 ) = Array( 1 )
' Assign the master array to the array property
oExample.ShortSequences = aArrayOfArrays()
如果嵌套使用Array(),就可以编写更简练的代码,但会使得人们难以理解将要生成的数组:
' Declare master array variable as variant
Dim aArrayOfArrays
' Create and assign master array and sub arrays
aArrayOfArrays = Array( Array( 0, 1, 2, 3 ), Array( 42, 0, -42 ), Array( 1 ) )
' Assign the master array to the array property
oExample.ShortSequences = aArrayOfArrays()
对于更高阶次的序列,也可以进行相应处理。
(4)常数和枚举映射
使用符合命名规则的名称对枚举类型的值进行寻址。以下示例假定oExample和oExample2支持 com.sun.star.beans.XPropertySet,并包含一个枚举类型为 com.sun.star.beans.PropertyState 的属性Status:
Dim EnumValue
EnumValue = com.sun.star.beans.PropertyState.DEFAULT_VALUE
MsgBox EnumValue ' displays 1
eExample.Status = com.sun.star.beans.PropertyState.DEFAULT_VALUE
Basic不支持枚举类型。在Basic中,来自UNO的枚举值被转换成Long值。只要Basic知道某个属性或某个接口方法参数是否需要一个枚举类型,就在内部将Long值转换为适当的枚举类型。当接口访问方法需要一个Any:
Dim EnumValue
EnumValue = oExample.Status ' EnumValue is of type Long
' Accessing the property implicitly
oExample2.Status = EnumValue ' Ok! EnumValue is converted to the right enum type
' Accessing the property explicitly using XPropertySet methods
oExample2.setPropertyValue( "Status", EnumValue ) ' WRONG! Will probably fail!
显式访问会失败,因为EnumValue是作为Any类型的参数传递到setPropertyValue(),因此,Basic不知道实际需要一个PropertyState类型的值。还有一个问题,在Basic中,com.sun.star.beans.PropertyState 的类型为Long。此问题在 com.sun.star.beans.XPropertySet 接口的实现中得以解决。对于枚举类型,使用Basic属性语法Object.Property来访问隐式属性优于使用类型Any来调用普通方法。如果仅存在需要Any类型的enum变量的普通接口方法,则没有适用于Basic的解决方案。
常数组用于在IDL中指定一组常数值。在Basic中,可以使用其全限定名称访问这些常数。以下代码显示了 com.sun.star.beans.PropertyConcept 中的一些常数:
MsgBox com.sun.star.beans.PropertyConcept.DANGEROUS ' Displays 1
MsgBox com.sun.star.beans.PropertyConcept.PROPERTYSET ' Displays 2
可以将常数组或枚举指定给对象。如果需要访问多个枚举或常数值,使用此方法可以缩短代码:
Dim oPropConcept
oPropConcept = com.sun.star.beans.PropertyConcept
msgbox oPropConcept.DANGEROUS ' Displays 1
msgbox oPropConcept.PROPERTYSET ' Displays 2
(5)接口
Basic将UNO接口映射成Basic对象方法
在Java和C++中,调用接口中的一个方法之前,需要获取接口。
在Basic中,可以直接调用该对象支持的任何接口的任何方法,而无需提前查询相应的接口。
使用的是 '.' 运算符:
' Basic
oExample = getExampleObjectFromSomewhere()
oExample.doNothing()' Calls method doNothing of XFoo1
oExample.doSomething()' Calls method doSomething of XFoo2
oExample.doSomethingElse(42)' Calls method doSomethingElse of XFoo2
此外,如果UNO对象的get和set方法符合以下模式,则Basic将它们映射为Basic对象属性:
SomeType getSomeProperty()
void setSomeProperty(SomeType aValue)
在此模式中,Basic提供了一个类型为SomeType、名称为SomeProperty的属性。
x = oExample.getIt() ' Calls getIt method of XFoo3
' is the same as
x = oExample.It ' Read property It represented by XFoo3
oExample.setIt( x ) ' Calls setIt method of XFoo3
' is the same as
oExample.It = x ' Modify property It represented by XFoo3
如果只有get方法,而没有set方法,则属性被视为只读。
x = oExample.getMore() ' Calls getMore method of XFoo1
y = oExample.getLess() ' Calls getLess method of XFoo1
' is the same as
x = oExample.More ' Read property More represented by XFoo1
y = oExample.Less ' Read property Less represented by XFoo1
' but
oExample.More = x ' Runtime error "Property is read only"
oExample.Less = y ' Runtime error "Property is read only"
可以直接访问com.sun.star.beans.XPropertySet提供的属性。
也可以使用com.sun.star.beans.XPropertySet中的方法访问属性。
x = oExample2.Value1
y = oExample2.Value2
z = oExample2.Value3
' is the same as
x = oExample2.getPropertyValue( "Value1" )
y = oExample2.getPropertyValue( "Value2" )
z = oExample2.getPropertyValue( "Value3" )
' and
oExample2.Value1 = x
oExample2.Value2 = y
oExample2.Value3 = z
' is the same as
oExample2.setPropertyValue( "Value1", x )
oExample2.setPropertyValue( "Value2", y )
oExample2.setPropertyValue( "Value3", z )
检查接口
尽管Basic不像C++ 和Java那样支持queryInterface概念,但有一个函数HasUnoInterfaces() 用于进行此项检测。
第一个参数HasUnoInterfaces() 需要的是应该接受测试的对象。接着可以将一个或多个全限定的接口名称参数传送到该函数。如果对象支持所有这些接口,则函数返回True,否则返回False。
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
IfaceName1$ = "com.sun.star.uno.XInterface"
IfaceName2$ = "com.sun.star.ucb.XSimpleFileAccess2"
IfaceName3$ = "com.sun.star.container.XPropertySet"
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$ )
MsgBox bSuccess ' Displays True because XInterface is supported
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$, IfaceName2$ )
MsgBox bSuccess ' Displays True because XInterface
' and XSimpleFileAccess2 are supported
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName3$ )
MsgBox bSuccess ' Displays False because XPropertySet is NOT supported
bSuccess = HasUnoInterfaces( oSimpleFileAccess, IfaceName1$, IfaceName2$, IfaceName3$ )
MsgBox bSuccess ' Displays False because XPropertySet is NOT supported
(6)服务
每个UNO对象都是服务的实例化。
uno对象映射为basic的variant类型,而不是object类型,因为object类型为纯粹basic对象。
有两种方法获得对象:
a.创建新对象
服务管理器com.sun.star.lang.ServiceManager,按服务名称实例化服务。
服务管理器的接口com.sun.star.lang.XMultiServiceFactory
它提供三个方法:createInstance()、createInstanceWithArguments() 和getAvailableServiceNames()。
使用GetProcessServiceManager()获取服务管理器
createInstance() 创建一个服务实例
oServiceMgr = GetProcessServiceManager()
oSimpleFileAccess = oServiceMgr.createInstance( "com.sun.star.ucb.SimpleFileAccess" )
createInstanceWithArguments() 使用参数创建一个服务实例。可能有些服务必须使用参数来实例化。
GetProcessServiceManager() 的优势是:使用服务管理器实例化服务时,可以接收附加信息和传入的参数。
Dim args(1)
args(0) = "Important information"
args(1) = "Even more important information"
oService = oServiceMgr.createInstanceWithArguments("com.sun.star.nowhere.ServiceThatNeedsInitialization", args() )
getAvailableServiceNames() 返回支持的所有服务名称。
sServices = GetProcessServiceManager().getAvailableServiceNames()
Print sServices
CreateUnoService函数是创建UNO服务实例的快捷方式,它本质上还是使用服务管理器创建实例。
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
此调用实例化 com.sun.star.ucb.SimpleFileAccess 服务。为确保函数成功,可以使用IsNull函数检查返回的对象:
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
bError = IsNull( oSimpleFileAccess )' bError is set to False
oNoService = CreateUnoService( "com.sun.star.nowhere.ThisServiceDoesNotExist" )
bError = IsNull( oNoService )' bError is set to True
CreateUnoServiceWithArguments实例化UNO服务,包括补充的可选参数。
dds = CreateUnoServiceWithArguments("com.sun.star.security.DocumentDigitalSignatures", Array("1.2", True))
插入到文档中的对象必须由该文档创建。例如,电子表格文档的绘图对象只能在这种文档中使用。
电子表格创建绘图对象:
RectangleShape = Spreadsheet.createInstance("com.sun.star.drawing.RectangleShape")
文本文档创建段落样式:
Style = Textdocument.createInstance("com.sun.star.style.ParagraphStyle")
b.获得现有对象
上下文是一个名称-值对的集合,您可以使用它来通过名称获取这些对象。默认上下文可通过函数GetDefaultContext获得。
MsgBox Join(GetDefaultContext().getElementNames(), CHR$(10))
libreoffice basic提供了一些全局对象,可以快捷使用
StarDesktop
StarDesktop对象代表LibreOffice应用程序。
Dim doc As Object, docProperties()
docURL = ConvertToURL("C:\My Documents\example.odt")
Rem com.sun.star.frame.Desktop
doc = StarDesktop.LoadComponentFromURL(docURL, "_blank", 0, docProperties)
GlobalScope
To manage personal or shared library containers (Application Macros or My Macros) from within a document, use the GlobalScope specifier.
要从文档中管理个人或共享库容器(应用程序宏或我的宏),请使用GlobalScope
' 调用文档库 Standard 中的 Dialog1
oDlgDesc = DialogLibraries.Standard.Dialog1
' 调用应用程序库 Library1 中的 Dialog2
oDlgDesc = GlobalScope.DialogLibraries.Library1.Dialog2
可以从活动文档中使用以下对象。
BasicLibraries对象
DialogLibraries对象
ThisComponent对象
ThisComponent表示宏中的当前文档。它寻找活动组件,其属性可以读取和设置,并且可以调用其方法。ThisComponent提供的属性和方法取决于文档类型。
ThisDatabaseDocument对象
ThisDatabaseDocument寻找活动的文档,该文档的属性可以读取和设置,并且可以调用其方法。
ThisDatabaseDocument返回一个类型为 com.sun.star.sdb.XOfficeDatabaseDocument 的对象。
使用名字访问下级对象
XNameAccess和XNameContainer接口用于包含下级对象的对象,可以使用名字访问下级对象
XNameAccess访问各个元素;而XNameContainer用于插入、修改和删除元素。
com.sun.star.container.XNameAccess 接口
1)getByName 方法
Sheets = Spreadsheet.Sheets
Sheet = Sheets.getByName("Sheet1")
2)getElementNames 方法
返回所有元素的名称。
Sheets = Spreadsheet.Sheets
SheetNames = Sheets.getElementNames
For I=LBound(SheetNames) To UBound(SheetNames)
MsgBox SheetNames(I)
Next I
3)hasByName 方法
是否存在特定名称的下级对象。
Sheets = Spreadsheet.Sheets
If Sheets.HasByName("Sheet1") Then
MsgBox " Sheet1 available"
Else
MsgBox "Sheet1 not available"
End If
com.sun.star.container.XNameContainer 接口
XNameContainer 接口用于插入、删除和修改对象中的下级对象。负责完成这些操作的函数为insertByName、removeByName、replaceByName。
该示例调用一个文本文档,该文档包含一个 StyleFamilies 对象,该对象包含段落样式 (ParagraphStyles)。
StyleFamilies = Textdoc.StyleFamilies
ParagraphStyles = StyleFamilies.getByName("ParagraphStyles")
ParagraphStyles.insertByName("NewStyle", NewStyle)
ParagraphStyles.replaceByName("ChangingStyle", NewStyle)
ParagraphStyles.removeByName("OldStyle")
insertByName 行在 ParagraphStyles 对象中的插入NewStyle样式。
replaceByName 行将 ChangingStyle对象更改为NewStyle。
removeByName 调用将 OldStyle对象从ParagraphStyles中删除。
使用索引访问下级对象
XIndexAccess和XIndexContainer接口用于包含下级对象并可使用索引访问下级对象的对象。
XIndexAccess提供了用于访问单个对象的方法。XIndexContainer 提供了用于插入和删除对象的方法。
com.sun.star.container.XIndexAccess 接口
XIndexAccess 提供了 getByIndex 和 getCount 方法。getByIndex 通过索引获得对象。getCount 返回对象的数目。
Sheets = Spreadsheet.Sheets
For I = 0 to Sheets.getCount() - 1
Sheet = Sheets.getByIndex(I)
' Editing sheet
Next I
该示例说明了一个循环,此循环遍历获得所有工作表。在使用索引时,请注意 getCount 返回元素的数目。不过,getByIndex 中的元素是从0开始编号的。因此,循环的计数变量是从0到 getCount()-1。
com.sun.star.container.XIndexContainer 接口
XIndexContainer 接口提供了 insertByIndex 和 removeByIndex 函数。这些参数的结构与 XNameContainer 中相应函数的结构相同。
对下级对象的遍历访问
在某些情况下,对象包含一个下级对象列表,但无法通过名称或索引访问这些下级对象。此时,应使用 XEnumeration 和 XenumerationAccess 接口。它们提供了一种机制来遍历某个对象的所有下级元素,而无需进行寻址。
com.sun.star.container.XEnumeration 和com.sun.star.container.XenumerationAccess 接口
对象必须提供 XEnumerationAccess 接口,该接口仅包含 createEnumeration 方法。此方法返回一个辅助对象,而该对象又提供了包含 hasMoreElements 和 nextElement 方法的 XEnumeration 接口。可通过这些方法来访问下级对象。
以下示例将遍历文本的所有段落:
ParagraphEnumeration = Textdoc.Text.createEnumeration
While ParagraphEnumeration.hasMoreElements()
Paragraph = ParagraphEnumeration.nextElement()
Wend
该示例首先创建了一个 ParagraphEnumeration 辅助对象。然后,借助此对象通过循环逐步返回文本的各个段落。在 hasMoreElements 方法返回 False 值(表示已到达文本末尾)时,将会立即终止循环。
检查对象
可以获取UNO对象的信息。
要查明两个对象是否引用同一个UNO对象,可以使用函数EqualUnoObjects()。在Basic中,不能对对象类型的参数应用比较运算符 =,例如If Obj1 = Obj2 Then会导致运行时错误。
oSimpleFileAccess = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
oSimpleFileAccess2 = oSimpleFileAccess
bIdentical = EqualUnoObjects( oSimpleFileAccess, oSimpleFileAccess2 )
MsgBox bIdentical ' Displays True
oSimpleFileAccess3 = CreateUnoService( "com.sun.star.ucb.SimpleFileAccess" )
bIdentical = EqualUnoObjects( oSimpleFileAccess, oSimpleFileAccess3 )
MsgBox bIdentical ' Displays False
Dbg_Properties和Dbg_Methods中使用的表示法是uno类型名称。可以忽略Sbx前缀。其他名称与一般Basic类型表示法对应。SbxEMPTY与Variant的类型相同。
DBG_properties
返回一个字符串,包括对象的所有属性
DBG_methods
返回一个字符串,包括对象的所有方法
DBG_supportedInterfaces
返回一个字符串,包括对象的所有接口
示例
Obj = createUnoService("com.sun.star.frame.Desktop")
MsgBox Obj.DBG_Properties
MsgBox Obj.DBG_methods
MsgBox Obj.DBG_supportedInterfaces
请注意,在使用DBG_properties时,返回理论上可以支持的所有属性。但不保证对象可以使用这些属性。因此,在使用属性之前,必须使用IsEmpty函数检查该属性是否确实可用。
supportsService方法
可以使用supportsService方法来确定对象是否支持特定服务。
例如,TextElement对象是否支持com.sun.star.text.Paragraph服务。
Ok = TextElement.supportsService("com.sun.star.text.Paragraph")
getsupportedservicenames方法
获取所有支持的服务
msgbox join(TextElement.getsupportedservicenames, chr(10))
工具 - 开发工具,能查看对象的服务,接口,方法,属性。
全局方法
CreateUnoDialog函数
创建一个基本Uno对象,该对象表示宏运行时的对话框。
CreateUnoListener函数
创建监听器实例。
CreateUnoValue函数
返回一个对象,该对象表示一个涉及Uno类型系统的精确类型值。