1 注意: 在atl做active控件时,事件参数 不能用 USHORT ULONG等类型,因为不支持这种类型,导致事件不调用
2. 情况如下:
事件接口为
dispinterface _ITestEvents{
properties:
methods:
[id(1), helpstring("method TestEvent")] void TestEvent([in] long a, [in] long b, [in] BSTR Text);
};
在连接点代理类中:
template <class T>
class CProxy_ITestEvents : public IConnectionPointImpl<T, &DIID__ITestEvents, CComDynamicUnkArray>
{
//Warning this class may be recreated by the wizard.
public:
VOID Fire_TestEvent()
{
T* pT = static_cast<T*>(this);
int nConnectionIndex;
CComVariant* pvars = new CComVariant[3];
int nConnections = m_vec.GetSize();
for( nConnectionIndex=0; nConnectionIndex<nConnections; ++nConnectionIndex)
{
pT->Lock();
CComPtr<IUnknown> sp = m_vec.GetAt(nConnectionIndex);
pT->Unlock();
IDispatch* pDispatch = reinterpret_cast<IDispatch*>(sp.p);
if( pDispatch!=NULL )
{
pvars[0].vt = VT_I4;
pvars[0].lVal = pInfo->IsSuccessful();
pvars[1].vt = VT_I4;
pvars[1].lVal = pInfo->ErrorCode();
//通过下面的pDispatch->Invoke(0x01, ...)回调客户的事件代码,但是当有中文字符时却无法触发客户端的事件,错误:Warning: automation argument coercion
//方法1:
pvars[2] = "abbbbdd"; //不行, Warning: automation argument coercion failed.
//方法2:
pvars[2].vt = VT_BSTR;
pvars[2].bstrVal = _com_util::ConvertStringToBSTR("23456"); //可以,没有中文字符。
//方法3:
pvars[2].vt = VT_BSTR;
pvars[2].bstrVal = _com_util::ConvertStringToBSTR("哈哈"); //不可以,有中文字符。Warning: automation argument coercion failed.
DISPPARAMS disp = { pvars, NULL, 3, 0 };
pDispatch->Invoke(0x01, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
}
}
delete [] pvars;
}
原因分析:参数的顺序颠倒了.
接口声明为:[id(1), helpstring("method TestEvent")] void TestEvent([in] long a, [in] long b, [in] BSTR Text);
pvars[0] 应该对应Test,pvars[1] 应该对应b,pvars[3] 应该对应a
使用CComBSTR() 或 _com_util::ConvertStringToBSTR("哈哈") 或 SysAllocString(L"哈哈") 都可以。