描述:
            void CPart::addPt(LPDISPATCH pt) 
{
	IDispatch   *pp;   
    pt->QueryInterface(IID_IDispatch,   (void**)&pp);   
	CPt *ppt;//=pt->QueryInterface(;
	ppt=(CPt*)pp;
如何改正,这里面有问题,
解决方案1:
            QueryInterface(你的查询的接口的ID,接收查询到的接口的指针的指针)
你要搞清楚(你的查询的接口的ID,接收查询到的接口的指针的指针)是一一对应的
        
            你是使用的别人的控件吗
楼主需要贴出错误信息
解决方案4:            控件项目的.idl文件编译后都会生成一个.c和.h的文件,.c文件就包含了接口ID的实际值,你可以把它加入你的客户项目,或者直接把ID定义拷贝过去,形如:
DEFINE_GUID(IID_IReceiverFace, 
0xb57cef65, 0x5b3, 0x4bd5, 0xa7, 0x2a, 0xf0, 0x97, 0x60, 0x6a, 0x8c, 0xec);
每个接口ID都有个GUID的定义值,你调用该接口时,需要把该接口的定义引入进来。
解决方案6:            感觉你好像有些迷糊。 呵呵
首先你要先定义在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
我就纳闷了, VC都提供了CComPtr/CComQIPtr/_com_ptr_t等智能类。怎么好多人都不用呢?
解决方案8:            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的
        
            http://www.vckbase.com/document/viewdoc/?id=212
看能不能找到你要的!
        
            IPt *ppt; //这里应该是IPt,而不是CPt,
ATL暴露的是接口,而部是类
    pt->QueryInterface(ppt对应的接口ID就可以了, reinterpret_cast <void**>(&ppt));  
        
            CPt *ppt;
pt->QueryInterface(IID_IDispatch,reinterpret_cast<void**>(&ppt));
这样就可以直接得到了!!
        
            接口直接没法转到你的实线对象,如果你要操作CPart对象就用你对应的IPart的IID(eg:IID_IYourPart)去 
pt->QueryInterface(IID_IYourPart,  (void**)&pp); 
应该可以解决你的问题. 
        
您可能想查找下面的文章:
- 如何修改ATL自动生成的COM方法呢?比如QueryInterface,CreateInstence
- 重写QueryInterface,AddRef,Release应该注意些什么?我这段代码怎么总是有问题。
- 使用COM组件时,QueryInterface调用失败是什么原因
- tempRs->QueryInterface__uuidof_Recordset,voidm_Recordset编译没错,vb调用报自动化错误
- 在线等待关于queryinterface的问题
- 关于QueryInterface,求助啊!
- 奇怪:成功激活也能成功调用,为什么queryinterface查询第二个接口报告“拒绝访问”?
- 为什么Queryinterface返回的IUnknown指针总是相同的
- 求QueryInterface例子
- 请问QueryInterface有什么用呢?

