示例一、IDispatch 调用原理篇
void demo() { ::CoInitialize( NULL ); // COM 初始化 CLSID clsid; // 通过 ProgID 得到 CLSID HRESULT hr = ::CLSIDFromProgID( L"Simple8.DispSimple.1", &clsid ); ASSERT( SUCCEEDED( hr ) ); // 如果失败,说明没有注册组件 IDispatch * pDisp = NULL; // 由 CLSID 启动组件,并得到 IDispatch 指针 hr = ::CoCreateInstance( clsid, NULL, CLSCTX_ALL, IID_IDispatch, (LPVOID *)&pDisp ); ASSERT( SUCCEEDED( hr ) ); // 如果失败,说明没有初始化 COM LPOLESTR pwFunName = L"Add"; // 准备取得 Add 函数的序号 DispID DISPID dispID; // 取得的序号,准备保存到这里 hr = pDisp->GetIDsOfNames( // 根据函数名,取得序号的函数 IID_NULL, &pwFunName, // 函数名称的数组 1, // 函数名称数组中的元素个数 LOCALE_SYSTEM_DEFAULT, // 使用系统默认的语言环境 &dispID ); // 返回值 ASSERT( SUCCEEDED( hr ) ); // 如果失败,说明组件根本就没有 ADD 函数 VARIANTARG v[2]; // 调用 Add(1,2) 函数所需要的参数 v[0].vt = VT_I4; v[0].lVal = 2; // 第二个参数,整数2 v[1].vt = VT_I4; v[1].lVal = 1; // 第一个参数,整数1 DISPPARAMS dispParams = { v, NULL, 2, 0 }; // 把参数包装在这个结构中 VARIANT vResult; // 函数返回的计算结果 hr = pDisp->Invoke( // 调用函数 dispID, // 函数由 dispID 指定 IID_NULL, LOCALE_SYSTEM_DEFAULT, // 使用系统默认的语言环境 DISPATCH_METHOD, // 调用的是方法,不是属性 &dispParams, // 参数 &vResult, // 返回值 NULL, // 不考虑异常处理 NULL); // 不考虑错误处理 ASSERT( SUCCEEDED( hr ) ); // 如果失败,说明参数传递错误 CString str; // 显示一下结果 str.Format("1 + 2 = %d", vResult.lVal ); AfxMessageBox( str ); pDisp->Release(); // 释放接口指针 ::CoUninitialize(); // 释放 COM }
示例二、CComDispatchDriver 智能指针包装类的使用方法
void demo() { // 已经进行过了 COM 初始化 CLSID clsid; // 通过 ProgID 取得组件的 CLSID HRESULT hr = ::CLSIDFromProgID( L"Simple8.DispSimple.1", &clsid ); ASSERT( SUCCEEDED( hr ) ); // 如果失败,说明没有注册组件 CComPtr < IUnknown > spUnk; // 由 CLSID 启动组件,并取得 IUnknown 指针 hr = ::CoCreateInstance( clsid, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID *)&spUnk ); ASSERT( SUCCEEDED( hr ) ); CComDispatchDriver spDisp( spUnk ); // 构造只能指针 CComVariant v1(1), v2(2), vResult; // 参数 hr = spDisp.Invoke2( // 调用2个参数的函数 L"Add", // 函数名是 Add &v1, // 第一个参数,值为整数1 &v2, // 第二个参数,值为整数2 &vResult); // 返回值 ASSERT( SUCCEEDED( hr ) ); // 如果失败,说明或者没有 ADD 函数,或者参数错误 CString str; // 显示一下结果 str.Format("1 + 2 = %d", vResult.lVal ); AfxMessageBox( str ); }