IDispatch接口代码参考:

IDispatch及双接口的调用

1,使用API方式调用:

 1     ::CoInitialize( NULL );        // COM 初始化
 2 
 3     CLSID clsid;                // 通过 ProgID 得到 CLSID
 4     HRESULT hr = ::CLSIDFromProgID( L"Simple8.DispSimple.1", &clsid );
 5     ASSERT( SUCCEEDED( hr ) );    // 如果失败,说明没有注册组件
 6 
 7     IDispatch * pDisp = NULL;    // 由 CLSID 启动组件,并得到 IDispatch 指针
 8     hr = ::CoCreateInstance( clsid, NULL, CLSCTX_ALL, IID_IDispatch, (LPVOID *)&pDisp );
 9     ASSERT( SUCCEEDED( hr ) );    // 如果失败,说明没有初始化 COM
10 
11     LPOLESTR pwFunName = L"Add";    // 准备取得 Add 函数的序号 DispID
12     DISPID dispID;                    // 取得的序号,准备保存到这里
13     hr = pDisp->GetIDsOfNames(        // 根据函数名,取得序号的函数
14         IID_NULL,
15         &pwFunName,                    // 函数名称的数组
16         1,                            // 函数名称数组中的元素个数
17         LOCALE_SYSTEM_DEFAULT,        // 使用系统默认的语言环境
18         &dispID );                    // 返回值
19     ASSERT( SUCCEEDED( hr ) );        // 如果失败,说明组件根本就没有 ADD 函数
20 
21     VARIANTARG v[2];                    // 调用 Add(1,2) 函数所需要的参数
22     v[0].vt = VT_I4;    v[0].lVal = 2;    // 第二个参数,整数2
23     v[1].vt = VT_I4;    v[1].lVal = 1;    // 第一个参数,整数1
24 
25     DISPPARAMS dispParams = { v, NULL, 2, 0 };    // 把参数包装在这个结构中
26     VARIANT vResult;            // 函数返回的计算结果
27 
28     hr = pDisp->Invoke(            // 调用函数
29         dispID,                    // 函数由 dispID 指定
30         IID_NULL,
31         LOCALE_SYSTEM_DEFAULT,    // 使用系统默认的语言环境
32         DISPATCH_METHOD,        // 调用的是方法,不是属性
33         &dispParams,            // 参数
34         &vResult,                // 返回值
35         NULL,                    // 不考虑异常处理
36         NULL);                    // 不考虑错误处理
37     ASSERT( SUCCEEDED( hr ) );    // 如果失败,说明参数传递错误
38 
39     CString str;            // 显示一下结果
40     str.Format("1 + 2 = %d", vResult.lVal );
41     AfxMessageBox( str );
42 
43     pDisp->Release();        // 释放接口指针
44     ::CoUninitialize();        // 释放 COM

2,使用智能指针包装类:

 1     // 在 App 类,InitInstance 中,已经调用 AfxOleInit() 进行了 COM 初始化
 2 
 3     CLSID clsid;                // 通过 ProgID 取得组件的 CLSID
 4     HRESULT hr = ::CLSIDFromProgID( L"Simple8.DispSimple.1", &clsid );
 5     ASSERT( SUCCEEDED( hr ) );    // 如果失败,说明没有注册组件
 6 
 7     CComPtr < IUnknown > spUnk;    // 由 CLSID 启动组件,并取得 IUnknown 指针
 8     hr = ::CoCreateInstance( clsid, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID *)&spUnk );
 9     ASSERT( SUCCEEDED( hr ) );
10 
11     CComDispatchDriver spDisp( spUnk );    // 构造只能指针
12     CComVariant v1(1), v2(2), vResult;    // 参数
13     hr = spDisp.Invoke2(    // 调用2个参数的函数
14         L"Add",                // 函数名是 Add
15         &v1,                // 第一个参数,值为整数1
16         &v2,                // 第二个参数,值为整数2
17         &vResult);            // 返回值
18     ASSERT( SUCCEEDED( hr ) );    // 如果失败,说明或者没有 ADD 函数,或者参数错误
19 
20     CString str;            // 显示一下结果
21     str.Format("1 + 2 = %d", vResult.lVal );
22     AfxMessageBox( str );
23 
24     // spUnk 和 spDisp 都是智能指针,会自动释放
25     // 如果使用 CoInitialize(NULL) 初始化,则必须在 CoUninitialize() 之前
26     // 调用 spUnk.Release() 和 spDisp.Release() 释放

3,加载类型库、产生包装类来使用。

添加类->类型库中的MFC类;选择组件文件(dll或者tlb文件)和需要包装的接口。

调用代码:

 1 #include "CDispSimple.h"    // 包装类的头文件
 2 
 3 void demo()
 4 {
 5     // 已经进行过了 COM 初始化
 6 
 7     CDispSimple spDisp;    // 包装类的对象
 8     spDisp.CreateDispatch( _T("Simple8.DispSimple.1") )    // 启动组件
 9     spDisp.xxx(...);    // 调用函数
10 
11     spDisp.ReleaseDispatch();    // 释放接口
12 }

4,使用#import方式调用组件(效率最高)。

posted on 2012-04-16 17:55  Joshua Leung  阅读(2321)  评论(0编辑  收藏  举报

导航