>>>对面的高手看过来:如何取得控件的LPDISPATCH???

RickeyLau 2002-05-15 10:03:23
当向工程添加了一个控件A后,vc会自动为控件生成一些包装类,其中一个最主要的控件类CA是从CWnd派生,其他的是从COleDispatchDriver派生,现在我为控件定义了一个变量m_ca,其类型当然是那个从CWnd派生的控件类CA。但后来有一个问题,另外一个控件类的成员函数需要一个LPDISPATCH类型的参数,如何将m_ca转化为LPDISPATCH类型??可以吗?
...全文
155 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zxs218 2002-05-17
  • 打赏
  • 举报
回复
我说这样的语句是不会出错的,是因为这时的IDispatch对象不可能被释放,
因为我们是引用了控件的IDispatch接口对象,这时控件是不可能被释放的。

当然这种做法也有一定的危险,最好是

lpunknown->QueryInterface(IID_IDispatch,(void**)&lpdisp);

...

pV->m_ddacQueryResult.GetPreview().SetViewer(lpdisp);
pV->m_ddacQueryResult.GetPreview().Refresh();
lpdisp->Release();

但这样会要求保存一个类范围的变量,为了省事所以没有那样做。

但我想这样做是不会有问题的。
zxs218 2002-05-17
  • 打赏
  • 举报
回复
楼上 看看rickeylau(RickeyLau)的贴子。

The interface pointer returned by GetControlUnknown is not reference-counted.
Lostinet 2002-05-17
  • 打赏
  • 举报
回复
不是把。。楼上
lpdisp是Query回来的
IDispatch不释放是lpunknown还没有释放的原因
你能保证这样不?出错?
这样写才行吧?

lpunknown->QueryInterface(IID_IDispatch,(void**)&lpdisp);
lpunknown->Release();

pV->m_ddacQueryResult.GetPreview().SetViewer(lpdisp);
pV->m_ddacQueryResult.GetPreview().Refresh();
lpdisp->Release();
RickeyLau 2002-05-16
  • 打赏
  • 举报
回复
但msdn上说:
The interface pointer returned by GetControlUnknown is not reference-counted. Do not callIUnknown::Release on the pointer unless you have previously calledIUnknown::AddRef on it.

zxs218 2002-05-16
  • 打赏
  • 举报
回复
CWnd::GetControlUnknown这个得到的是IUnknown接口,

通过IUnknown的QueryInterface方法获取IDispatch接口。

LPUNKNOWN lpunknown=m_arviewPrintPreview.GetControlUnknown();
LPDISPATCH lpdisp=NULL;
lpunknown->QueryInterface(IID_IDispatch,(void**)&lpdisp);
// 这时需要调用
lpunknown->Release();

...

// 在LPDISPATCH使用完成后也要调用
lpdisp->Release();
zxs218 2002-05-16
  • 打赏
  • 举报
回复
sorry ,
我弄错了,你说得对。

但是QueryInterface的接口还是必须调用Release()的;

你可以这样:

lpunknown->QueryInterface(IID_IDispatch,(void**)&lpdisp);

lpdisp->Release();

pV->m_ddacQueryResult.GetPreview().SetViewer(lpdisp);
pV->m_ddacQueryResult.GetPreview().Refresh();

这样的语句是不会出错的,因为这时的IDispatch对象不会被释放。
RickeyLau 2002-05-15
  • 打赏
  • 举报
回复
我刚测试了一下,发现对于同一个自动化对象,使用

CCmdTarget::GetIDispatch的IDispatch指针,和使用

CWnd::GetControlUnknown,得到的IDispatch指针不相等,

到底哪个是对的呢?为什么会有这样的情况,???
RickeyLau 2002-05-15
  • 打赏
  • 举报
回复
多谢啦!!!
基本上可以啦,但还是有一个小问题,就是该窗口退出的时候会出错,是在控件的析构函数中,好像是关于引用计数的问题。
以下是我的代码:
LPUNKNOWN lpunknown=m_arviewPrintPreview.GetControlUnknown();
LPDISPATCH lpdisp=NULL;
lpunknown->QueryInterface(IID_IDispatch,(void**)&lpdisp);
//是不是这样用???

pV->m_ddacQueryResult.GetPreview().SetViewer(lpdisp);
pV->m_ddacQueryResult.GetPreview().Refresh();


另外一个问题,为什么用GetIDispatch直接取得控件对象的IDispatch接口就不行呢?而用GetControlUnknown得到IUnknown接口再查询出IDispatch就可以呢?

arxing 2002-05-15
  • 打赏
  • 举报
回复
CWnd::GetControlUnknown()。

3,248

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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