Difference between revisions of "Zh/Documentation/DevGuide/ProUNO/Bridge/Calling Functions and Accessing Properties"
(New page: {{Documentation/DevGuide/ProUNOTOC |ProUNO2c=block |ABridgeSvcMgr=block |UNOAuto=block |ShowPrevNext=block |PrevPage=Documentation/DevGuide/ProUNO/Bridge/Using UNO from Automation |NextPag...) |
|||
Line 1: | Line 1: | ||
− | {{Documentation/DevGuide/ProUNOTOC | + | {{Documentation/DevGuide/ProUNOTOC/Zh |
|ProUNO2c=block | |ProUNO2c=block | ||
|ABridgeSvcMgr=block | |ABridgeSvcMgr=block | ||
|UNOAuto=block | |UNOAuto=block | ||
|ShowPrevNext=block | |ShowPrevNext=block | ||
− | |PrevPage=Documentation/DevGuide/ProUNO/Bridge/Using UNO from Automation | + | |PrevPage=Zh/Documentation/DevGuide/ProUNO/Bridge/Using UNO from Automation |
− | |NextPage=Documentation/DevGuide/ProUNO/Bridge/Return Values | + | |NextPage=Zh/Documentation/DevGuide/ProUNO/Bridge/Return Values |
}} | }} | ||
− | + | {{Documentation/DevGuideLanguages|Documentation/DevGuide/ProUNO/Bridge/{{SUBPAGENAME}}}} | |
{{DISPLAYTITLE:调用函数并访问属性}} | {{DISPLAYTITLE:调用函数并访问属性}} | ||
Latest revision as of 02:58, 14 May 2009
Automation 对象的实质是 IDispatch 接口。所有函数调用(包括访问属性)最终需要调用 IDispatch::Invoke
。在 C++ 中,IDispatch 使用起来相当麻烦。例如,以下代码调用 createInstance("com.sun.star.reflection.CoreReflection")
:
OLECHAR* funcname = L"createInstance"; DISPID id; IDispatch* pdispFactory= NULL; CLSID clsFactory= {0x82154420,0x0FBF,0x11d4,{0x83, 0x13,0x00,0x50,0x04,0x52,0x6A,0xB4}}; HRESULT hr= CoCreateInstance( clsFactory, NULL, CLSCTX_ALL, __uuidof(IDispatch), (void**)&pdispFactory); if( SUCCEEDED(pdispFactory->GetIDsOfNames( IID_NULL, &funcName, 1, LOCALE_USER_DEFAULT, &id))) { VARIANT param1; VariantInit( ¶m1); param1.vt= VT_BSTR; param1.bstrVal= SysAllocString( L"com.sun.star.reflection.CoreReflection"); DISPPARAMS dispparams= { ¶m1, 0, 1, 0}; VARIANT result; VariantInit( &result); hr= pdispFactory->Invoke( id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &result, NULL, 0); }
首先通过 GetIdsOfNames
获取方法名称 createInstance()
的 COM ID,然后使用该 ID 来 invoke()
方法: createInstance()
。
在调用 IDispatch
接口中的某个具体函数之前,通过调用 GetIDsOfNames
来获取 DISPID
。必要时,由桥生成 DISPID
。不存在从成员名称到 DISPID
的固定映射,也就是说,某个对象的第二个实例的同一函数可能具有不同的 DISPID
。一旦为某个函数或属性名称创建了一个 DISPID
,该 DISPID
在对象的生存期内将保持不变。
Helper 类可以简化该程序。下面的示例说明使用动态模板库中的 Helper 类来实现相同的调用:
CComDispatchDriver spDisp(pdispFactory); CComVariant param(L"com.sun.star.reflection.CoreReflection"); CComVariant result; hr= spUnk.Invoke1(L"createInstance",param, result);
有些框架允许包含 COM 类型库,这是一种在开发期间连接 Automation 对象的简便接口。不能将这些 Helper 类与 UNO 一起使用,因为 SDK 没有提供用于 UNO 组件的 COM 类型库。COM 提供了各种方法来调用 COM 对象中的函数,而 UNO 仅支持 IDispatch
。
使用 VB 或 JScript 进行 Automation 对象的编程较为容易,因为隐藏了 IDispatch
接口,而且可以直接调用函数。而且,在 VARIANT
中无需包括参数。
//VB Dim objRefl As Object Set objRefl= dispFactory.createInstance("com.sun.star.reflection.CoreReflection") //JScript var objRefl= dispFactory.createInstance("com.sun.star.reflection.CoreReflection");
符合以下模式的 get/set 函数对
SomeType getSomeProperty() void setSomeProperty(SomeType aValue)
被作为 COM 对象属性处理。
在 C++ 中访问这类属性与调用方法类似。首先,获取一个 DISPID
,然后用正确的参数调用 IDispatch::Invoke
。
DISPID dwDispID; VARIANT value; VariantInit(&value); OLECHAR* name= L"AttrByte"; HRESULT hr = pDisp->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dwDispID); if (SUCCEEDED(hr)) { // Get the property DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; pDisp->Invoke(dwDispID, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &value, NULL, NULL); // The VARIANT value contains the value of the property // Sset the property VARIANT value2; VariantInit( value2); value2.vt= VT_UI1; value2.bval= 10; DISPPARAMS disparams; dispparams.rgvarg = &value2; DISPID dispidPut = DISPID_PROPERTYPUT; dispparams.rgdispidNamedArgs = &dispidPut; pDisp->Invoke(dwDispID, IID_NULL,LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &dispparams, NULL, NULL, NULL); }
当属性为 IUnknown*、IDispatch*
或 SAFEARRAY*
时,必须使用标志 DISPATCH_PROPERTYPUTREF
。当通过引用 (VARIANT.vt = VT_BYREF | ...
) 传递值时,情况也是如此。
下面的示例显示使用 ATL Helper 类时,程序看起来比较简单:
CComVariant prop; CComDispatchDriver spDisp( pDisp); // get the property spDisp.GetPropertyByName(L"AttrByte",&prop); //set the property CComVariant newVal( (BYTE) 10); spDisp.PutPropertyByName(L"AttrByte",&newVal);
以下示例显示使用 VB 和 JScript 时,程序看起来更简单:
//VB Dim prop As Byte prop= obj.AttrByte Dim newProp As Byte newProp= 10 obj.AttrByte= newProp 'or obj.AttrByte= 10 //JScript var prop= obj.AttrByte; obj.AttrByte= 10;
没有将服务属性映射成 COM 对象属性。使用接口(如 com.sun.star.beans.XPropertySet)来管理服务属性。
Content on this page is licensed under the Public Documentation License (PDL). |