传入和调用ocx的参数类型必须一致,但mfc导入字符串时自动实现了转换
编者:李国帅
背景原因:
传入和调用ocx的参数必须一致,不能直接把char* 转换为bstr。
但是在mfc如果直接导入接口,ole自己实现从char*到bstr的转换。
所需资源:
VC, ATL
调用的时候不需要如下写法:
BSTR bstrURL=m_strURL[nUrlIndex].AllocSysString();
BSTR bstrUserName=m_strUserName[nUrlIndex].AllocSysString();
BSTR bstrPassWord=m_strPassWord[nUrlIndex].AllocSysString();
m_ctrl.PlayXXXEx(ptCursor.x,ptCursor.y,bstrURL,bstrUserName,bstrPassWord);
::SysFreeString(bstrURL);
::SysFreeString(bstrUserName);
::SysFreeString(bstrPassWord);
直接使用
m_ctrl.PlayXXXEx(ptCursor.x,ptCursor.y,strURL,strUserName,strPassWord);
注意参数类型
long PlayXXXEx(long nPosX, long nPosY, LPCTSTR strURL, LPCTSTR strUserName, LPCTSTR strPassword)
{
long result;
static BYTE parms[] = VTS_I4 VTS_I4 VTS_BSTR VTS_BSTR VTS_BSTR ;
InvokeHelper(0x3, DISPATCH_METHOD, VT_I4, (void*)&result, parms, nPosX, nPosY, strURL, strUserName, strPassword);
return result;
}
D:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\oledisp2.cpp
void COleDispatchDriver::InvokeHelperV
#if !defined(_UNICODE)
case VT_BSTRA:
{
LPCSTR lpsz = va_arg(argList, LPSTR);
CStringW strMBToUnicode(lpsz);
pArg->bstrVal = ::SysAllocString(static_cast<LPCWSTR>(strMBToUnicode));
if (lpsz != NULL && pArg->bstrVal == NULL)
AfxThrowMemoryException();
pArg->vt = VT_BSTR;
}
break;
#endif
ocx内部 参数类型为bstr
[id(3), helpstring("方法")] LONG PlayXXXEx(LONG nPosX, LONG nPosY, BSTR strURL, BSTR strUserName, BSTR strPassword);
DISP_FUNCTION_ID(CPlayerXXXCtrl, "PlayXXXEx", dispidPlayXXXEx, PlayXXXEx, VT_I4, VTS_I4 VTS_I4 VTS_BSTR VTS_BSTR VTS_BSTR)
定义函数的时候
LONG PlayXXXEx(LONG nPosX, LONG nPosY, LPCTSTR strURL, LPCTSTR strUserName, LPCTSTR strPassword);
LONG CPlayerXXXCtrl::PlayXXXEx(LONG nPosX, LONG nPosY, LPCTSTR strURL, LPCTSTR strUserName, LPCTSTR strPassword)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// TODO: 在此添加调度处理程序代码
int nIndex = GetIndexFromPos(nPosX, nPosY);
int nret = IsValidPlayer(nIndex);
if (nret == -1)return -1;
//CString strURL1 = (char*)_bstr_t(strURL,false);//BSTR 不需要这样做。mfc已经对com接口进行了类型转换
//CString strUserName1 = (char*)_bstr_t(strUserName);
//CString strPassword1 = (char*)_bstr_t(strPassword);
//LONG nRet = m_paryPlayer[nIndex]->PlayXXX(strURL1,strUserName1,strPassword1);
LONG nRet = m_paryPlayer[nIndex]->PlayXXX(strURL,strUserName,strPassword);
return nRet;
}
事件也是一样
//CHAR tTime[20]
FireEvent(eventidOnSeekRecordUrl, EVENT_PARAM(VTS_I4 VTS_I4 VTS_BSTR), iPlayer,pEvent->nRecordId, pEvent->tTime);