MFC 用 COM 方式调用 ActiveX 类型的 DLL
1 准备:
第三方提供给你一个文件 Hehex.dll ,你要调用其中的 MyFunc01 函数,函数原型为
int MyFunc01 ( long paramA, TCHAR* paramB, BOOL paramC) 。
如果要用 InvokeHelper 函数传送多个参数给 MyFunc01 。而且只知道 DLL 的注册名,没有 .odl 文件查看 MyFunc01 函数对应的属性 ID ,那么可以用下面的方法。
关键部分:
1.1 InvokeHelper 函数 pbParamInfo 的写法。
1.2 GetIDsOfNames 得到 DISPID 的 ID 号。
2 步骤:
2.1 先注册 DLL
2.1.1 假设在 Hehex.dll 放在 HaiActiveX 文件夹下。
2.1.2 DOS 命令窗口下切换到 Hehex.dll 所在目录输入注册命令: regsvr32 Hehex.dll
2.1.3 注册成功,在注册表中搜索到 Hehex.dll 对应的注册名比如为
“ Hehex. HaiActiveX ”
2.2 程序:
2.2.1 初始化 COM 组件:
// 初始化 COM, 创建 ADO 连接等操作
if(!AfxOleInit())// 这就是初始化 COM 库
{
AfxMessageBox(_T("KE 初始化出错 !"));
return FALSE;
}
2.2.2 简单程序如下:
void CHaiDlg::Haitest()
{
DISPID lDispID; //MyFunc01 对应的属性 ID
COleDispatchDriver m_calc;
COleException e;
CLSID clsid;
// 加载 Hehex.HaiActiveX
if (CLSIDFromProgID(OLESTR("Hehex.HaiActiveX"), &clsid) != NOERROR)
{
AfxMessageBox(_T(" 找 Hehex.HaiActiveX 失败 "));
return FALSE;
}
// try to get the active calculator before creating a new one
LPUNKNOWN lpUnk;
LPDISPATCH lpDispatch;
if (GetActiveObject(clsid, NULL, &lpUnk) == NOERROR)
{
HRESULT hr = lpUnk->QueryInterface(IID_IDispatch,
(LPVOID*)&lpDispatch);
lpUnk->Release();
if (hr == NOERROR)
m_calc.AttachDispatch(lpDispatch, TRUE);
HaiTestShow(_T(" 得到成员成功 "));
}
// if not dispatch ptr attached yet, need to create one
if (m_calc.m_lpDispatch == NULL &&
!m_calc.CreateDispatch(clsid, &e))
{
StatusShow(_T(" 创立成员失败 "));
AfxMessageBox(_T(" 创立失败 "));
return FALSE;
}
// 得到 MyFunc01 函数对应的 DISPID, 属性 ID
HRESULT hresult =0;
OLECHAR FAR* szMember = _T("MyFunc01");
hresult = m_calc.m_lpDispatch->GetIDsOfNames(
IID_NULL,
&szMember,
1, LOCALE_SYSTEM_DEFAULT,
&lDispID);
if (S_OK != hresult)
{
AfxMessageBox(_T(" 得到 DISPID 错误 "));
return FALSE;
}
// 使用 InvokeHelper 通过 MyFunc01 对应的属性 ID ,传入多个参数。
try
{
int resultFlag = 0;
static BYTE parms[] =VTS_PI4 VTS_PI1 VTS_BOOL; // 注意传入三个参数对应类型用空格分开,参数类型可以到 Afxdisp.h 中查找
m_calc.InvokeHelper(lDispID, DISPATCH_METHOD, VT_INT, (void*)&resultFlag,
parms,//pbParamInfo 传入的参数类型
125, // 输入参数 paramA
_T("heolw.sllsls"), // 输入参数 paramB
_variant_t(TRUE)); //// 输入参数 paramC
}
catch( CException *e)
{
TCHAR szError[1024];
e->GetErrorMessage(szError,1024);
::AfxMessageBox(szError);
return FALSE;
}
return TRUE;
}
3 结束