Question1 : COM中事件池事件重载时Variant类型的获取问题

liulee 2002-11-18 03:58:51
COM中事件池函数重载如下:
HRESULT TMsgEventHandler::InvokeEvent(DISPID id, TVariant *params)
{
switch(id)
{
case 1:
.....
break;
default:
.....
}
}
我想做的事情是,在此重载方法中,根据服务器触发的ID来触发客户端相关事件,这些事件的参数都封装在 TVariant 类型的 params 中了.譬如可能有两个参数,一个是int,一个是IDispatch或IUnknown类型.

附InvokeEvent虚函数:
virtual void __fastcall InvokeEvent(int DispID, TVariantArray ¶ms)
实际定义时按照IDispatchEvent类模板,必须定义为:
void __fastcall InvokeEvent(DISPID id, TVariant *params)

现在的问题是,如何得到params有多少维?(即几个参数),各个参数的具体类型及转换方法.

望各位不吝赐教,在线等待.


...全文
67 51 打赏 收藏 转发到动态 举报
写回复
用AI写文章
51 条回复
切换为时间正序
请发表友善的回复…
发表回复
bcboy 2002-11-27
  • 打赏
  • 举报
回复
流方跑这儿来了?真乃高手也!

这么多星星,头晕。
bcb_fans 2002-11-20
  • 打赏
  • 举报
回复
既然参数需要IDispatch*,你把传过去就得了,为什么使用params[0].operator long()而不用params[0].operator IDispatch*() ?
liulee 2002-11-20
  • 打赏
  • 举报
回复
运行环境比较复杂,不然就把源码帖上来了.
liulee 2002-11-20
  • 打赏
  • 举报
回复
OnMyStatusChange(params[0].operator long(),params[1].operator long());
break;
中参数和API的参数顺序是倒置的,不理解Ms为何这样处理.

liulee 2002-11-20
  • 打赏
  • 举报
回复
今天出去了,没时间上网.

是这样的问题:
我利用MSN Messenger提供的COM服务,想写自己的一些控制程序,于是才有上面的问题.

API中如是说:
void OnContactStatusChange(
IDispatch* pMContact,
MISTATUS mStatus
);

就是要在InvokeEvent中,依照ID来触发该事件,把参数带入.
其中,IDispatch*只是一个泛型,实际类型为IMessengerContact,我只把地址传过去完事,然后到事件中通过 (IMessengerContact *)(pMContact)强制转换得到的.

关键问题是,我这样的代码:
HRESULT TMsgEventHandler::InvokeEvent(DISPID id, TVariant *params)
{
switch(id)
{
case DISPID_MUAE_ONMYSTATECHANGE:
OnMyStatusChange(params[0].operator long(),params[1].operator long());
break;

连执行都不执行,debug进去,看不出所以然.



Behard 2002-11-19
  • 打赏
  • 举报
回复
先 mark 一下
等有空再看
RomanticProgrammer 2002-11-18
  • 打赏
  • 举报
回复
等不到楼主了..先灌一桶再说...
我来一桶------->矿泉水..
RomanticProgrammer 2002-11-18
  • 打赏
  • 举报
回复
一霎那,深拥一吻...........
RomanticProgrammer 2002-11-18
  • 打赏
  • 举报
回复
to cker:这样用是有点累...是楼主这样用的.我的代码是这样的啊:
OnMyStatusChange(long(params[0]),long(params[1]);
呵呵....
  • 打赏
  • 举报
回复
嘿嘿。。。
bcb_fans 2002-11-18
  • 打赏
  • 举报
回复
回复人: cker(〖烟波浩淼三千里、人鬼殊途五百年〗) ( ) 信誉:110 2002-11-18 20:59:00 得分:0


高潮总是短暂的啊


=======

:)))
  • 打赏
  • 举报
回复
问个跑题的话?operator这么用累不累啊?
  • 打赏
  • 举报
回复
高潮总是短暂的啊
bcb_fans 2002-11-18
  • 打赏
  • 举报
回复
楼主也真是的,讨论正到高潮的时候,又跑去哪了:)
RomanticProgrammer 2002-11-18
  • 打赏
  • 举报
回复
楼主怎么不出现了..?
:)
bcb_fans 2002-11-18
  • 打赏
  • 举报
回复
看来没有戏了 :( ,InvokeEvent()是由Invoke()调用的,它把原来的多个参数放在一个数组里边,然后把数组的地址传递到InvokeEvent()里边,光凭数组的地址是无法得到数组的大小的,这个只能由你自己来确定,因为事件是你设计的,你应该知道参数的多少!

下面是Invoke调用InvokeEvent的源代码:
=================================


template <class T, const IID *pEVENTSIID, class BASE> HRESULT STDMETHODCALLTYPE
TEventDispatcher<T, pEVENTSIID, BASE>::Invoke(DISPID dispid, REFIID /*iid*/, LCID /*lcid*/,
WORD /*wFlags*/, DISPPARAMS* pDispParams,
VARIANT* /*pVarResult*/, EXCEPINFO* /*pExcepInfo*/,
UINT* /*puArgError*/)
{
TAPtr<TVariant> pParamArray;
TVariant *pArrayPtr = 0;
if (pDispParams->cArgs)
{
int count = pDispParams->cArgs;
pParamArray = new TVariant[count];
// NOTE: row vs. column major!
for (UINT i=0; i<pDispParams->cArgs; i++)
pParamArray[count-(i+1)] = pDispParams->rgvarg[i];
pArrayPtr = pParamArray;
}
return InvokeEvent(dispid, pArrayPtr);
};
RomanticProgrammer 2002-11-18
  • 打赏
  • 举报
回复
他正在看这个帖子..呵呵.
RomanticProgrammer 2002-11-18
  • 打赏
  • 举报
回复
听听AKing的高见..
RomanticProgrammer 2002-11-18
  • 打赏
  • 举报
回复
我认为他在服务端的参数数组的构造可能有问题...刚开始我就让他把服务端贴出来看看.他没有贴...呵呵....
bcb_fans 2002-11-18
  • 打赏
  • 举报
回复
我明白楼主在说什么了,不过我一时也想不出个所以然来,先让头脑清醒一下!
加载更多回复(31)

13,822

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧