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). | 

