QueryInterface如何使用?

djliu221 2009-06-15 10:37:31
void CPart::addPt(LPDISPATCH pt)
{
IDispatch *pp;
pt->QueryInterface(IID_IDispatch, (void**)&pp);
CPt *ppt;//=pt->QueryInterface(;
ppt=(CPt*)pp;
如何改正,这里面有问题,
...全文
351 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
Afterwards_ 2012-07-29
  • 打赏
  • 举报
回复
求学就这种态度?我以为你放高利贷的呢...
nodiebirdcomeback 2009-06-17
  • 打赏
  • 举报
回复
QueryInterface(你的查询的接口的ID,接收查询到的接口的指针的指针)
你要搞清楚(你的查询的接口的ID,接收查询到的接口的指针的指针)是一一对应的
djliu221 2009-06-17
  • 打赏
  • 举报
回复
你看我单位问题,回答,不要这样说半截话, 如果知道的话, 给个简单的例子,让大家都学习
djliu221 2009-06-16
  • 打赏
  • 举报
回复
你用的是atl方式,我的开发环境是MFC,这个环境该如何处理?
bdzwj 2009-06-16
  • 打赏
  • 举报
回复
感觉你好像有些迷糊。 呵呵
首先你要先定义在IDL中定义IPt/IPart等双接口类型

然后实现IPt,
class ATL_NO_VTABLE CPt : public CComCoClass<....>,IDispatchImpl<...> ....
{
BEGIN_COM_MAP(CPt)
COM_INTERFACE_ENTRY(IPt)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
.......
};

实现IPart
class ATL_NO_VTABLE CPart : public CComCoClass<....>,IDispatchImpl<...> ....
{
vector<CAdapt<CComPtr<IPt> > > m_pPos;

BEGIN_COM_MAP(CPt)
COM_INTERFACE_ENTRY(IPart)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()

LRESULT addPos(LPDISPATCH pt)
{
CComPtr<IPt> p = pt;
if (p)
{
m_pPos.push_back(p);
return S_OK;
}
else
{
return E_INVALIDARG;
}
}

// 假设你有一个并不是直接传递IPt类型接口的
LRESULT addPot(LONG x, LONG y)
{
CComPtr<IPt> p = NULL;
HRESULT hr = CPat::CreateInstance(&p);
if (SUCCEEDED(hr) && p)
{
p->SetX(x);
p->SetY(y);
hr = addPos(p);
}
return hr;
}
// 假设你想获取一个IPt接口
LRESULT getPt(UINT nIndex, IDispatch **ppt)
{
if (nIndex >= m_pPos.size())
return E_INVALIDARG;
else
{
CComPtr<IPt> p = m_pPos[nIndex];
return p->CopyTo(ppt);
}
}

};


// vb 测试

dim objPt as new YouLib.CPt
dim objPart as new YouLib.CPart

objPt.x = 100
objPart.addPos(objPt) // 直接添加对象到集合

objPart.addPot(100,200) // 不直接添加对象,利用参数让COM组件自己创建对象并添加到集合

dim objP as YouLib.Cpt
objPart.getPt 0,objP ' 测试返回IPt
bdzwj 2009-06-16
  • 打赏
  • 举报
回复
我就纳闷了, VC都提供了CComPtr/CComQIPtr/_com_ptr_t等智能类。怎么好多人都不用呢?
djliu221 2009-06-16
  • 打赏
  • 举报
回复
如何修改
我的 意思
是在一个点集合里添加一个点这个实现.
CPt--》IPt,
CPart-->IPart
void CPart::addPt(LPDISPATCH pt)
实现这个功能
LPDISPATCH pt需要转化为CPt (IPt),
LensFlare 2009-06-16
  • 打赏
  • 举报
回复
void CPart::addPt(LPDISPATCH pt)
{
//IDispatch *pp;
CPt *ppt;
pt->QueryInterface(IID_IDispatch, reinterpret_cast <void**>(&ppt));
Pos ppos;
ppos.x=ppt->GetX();
ppos.y=ppt->GetY();
ppos.z=ppt->GetZ();
CString str;
str.Format("%f,%f,%f",ppos.x,ppos.y,ppos.z);
AfxMessageBox(str);
m_pPos.push_back(ppos);

}

这样肯定是不对的, 你查询的是IDispatch接口,IDispatch接口是不可能转化成CPt的
djliu221 2009-06-16
  • 打赏
  • 举报
回复
void CPart::addPt(LPDISPATCH pt)
{
//IDispatch *pp;
CPt *ppt;
pt->QueryInterface(IID_IDispatch, reinterpret_cast<void**>(&ppt));
Pos ppos;
ppos.x=ppt->GetX();
ppos.y=ppt->GetY();
ppos.z=ppt->GetZ();
CString str;
str.Format("%f,%f,%f",ppos.x,ppos.y,ppos.z);
AfxMessageBox(str);
m_pPos.push_back(ppos);

}
在 vb下测试还是有问题
弹出的信息不对,奇怪
djliu221 2009-06-16
  • 打赏
  • 举报
回复
不是,这2个都是基于mfc 的
class CPart : public CCmdTarget
class CPt : public CCmdTarget
bdzwj 2009-06-16
  • 打赏
  • 举报
回复
你是使用的别人的控件吗
djliu221 2009-06-16
  • 打赏
  • 举报
回复
你有msn 或qq吗?
我的msn djliu221@163.com
qq 412925762
直接交流
贪玩的老鼠 2009-06-16
  • 打赏
  • 举报
回复
CPt *ppt;
pt->QueryInterface(IID_IDispatch,reinterpret_cast<void**>(&ppt));
这样就可以直接得到了!!
djliu221 2009-06-16
  • 打赏
  • 举报
回复
D:\三维\33维控件\TDMap\Part.cpp(88) : error C2065: 'IPt' : undeclared identifier
D:\三维\33维控件\TDMap\Part.cpp(88) : error C2065: 'ppt' : undeclared identifier
D:\三维\33维控件\TDMap\Part.cpp(88) : warning C4552: '*' : operator has no effect; expected operator with side-effect
D:\三维\33维控件\TDMap\Part.cpp(91) : error C2227: left of '->GetX' must point to class/struct/union
D:\三维\33维控件\TDMap\Part.cpp(92) : error C2227: left of '->GetY' must point to class/struct/union
D:\三维\33维控件\TDMap\Part.cpp(93) : error C2227: left of '->GetZ' must point to class/struct/union
wangweixing2000 2009-06-16
  • 打赏
  • 举报
回复
接口直接没法转到你的实线对象,如果你要操作CPart对象就用你对应的IPart的IID(eg:IID_IYourPart)去
pt->QueryInterface(IID_IYourPart, (void**)&pp);

应该可以解决你的问题.
瓶盒 2009-06-16
  • 打赏
  • 举报
回复
楼主需要贴出错误信息
djliu221 2009-06-16
  • 打赏
  • 举报
回复
我在Part.h中添加static const IID IID_IPt =
{ 0xba7676f2, 0x66bb, 0x40a5, { 0x83, 0x2a, 0x70, 0x3b, 0xe7, 0xdc, 0xe4, 0xb1 } };

void CPart::addPt(LPDISPATCH pt)
{
//IDispatch *pp;
IPt *ppt;
pt->QueryInterface(IID_IPt, reinterpret_cast<void**>(&ppt));
Pos ppos;
ppos.x=ppt->GetX();
ppos.y=ppt->GetY();
ppos.z=ppt->GetZ();
CString str;
str.Format("%f,%f,%f",ppos.x,ppos.y,ppos.z);
AfxMessageBox(str);
m_pPos.push_back(ppos);

}
编译还是有错误。
瓶盒 2009-06-16
  • 打赏
  • 举报
回复
控件项目的.idl文件编译后都会生成一个.c和.h的文件,.c文件就包含了接口ID的实际值,你可以把它加入你的客户项目,或者直接把ID定义拷贝过去,形如:
DEFINE_GUID(IID_IReceiverFace,
0xb57cef65, 0x5b3, 0x4bd5, 0xa7, 0x2a, 0xf0, 0x97, 0x60, 0x6a, 0x8c, 0xec);
djliu221 2009-06-16
  • 打赏
  • 举报
回复
如何接口的定义引入进来?
给个例子
瓶盒 2009-06-16
  • 打赏
  • 举报
回复
每个接口ID都有个GUID的定义值,你调用该接口时,需要把该接口的定义引入进来。
加载更多回复(4)

3,245

社区成员

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

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