下面我们将把前面所提到过和各代码段组合起来,以构成一个说明QueryInterface 实现及使用的完整例子。
总的来说可以将这些代码分成三部分。
第一部分是接口IX、 IY 和 IZ 的定义部分。接口 IUnknown 的定义在 Win32 SDK 的头文件 1 见UNKNWN . H 中。
第二部分是组件的实现。类 CA 实现了一个支持 IX 和 IY 接口的组件。QueryInterface的实现同前一节中给出的实现是一样的。在类CA的末尾给出了CreateInstance 的定义。客户可以使用此函数来创建类 CA 所代表的组件并返回一个指向其 IUnknown 接口的指针。
在定义好 CreateInstance函数之后,下面定义的是各接口的 IID 结构。从这些定义可以看出 IID 结构是一个相当大的结构。
清单中的第三部分也就是最后一部分是main 函数,它表示示例程序中的客户。
#include <iostream>
#include <objbase.h>
#include <windows.h>
using namespace std;
void trace(const char *msg){cout<<msg<<endl;}
//interfaces
interface IX:IUnknown
{
virtual void _stdcall Fx()=0;
};
interface IY:IUnknown
{
virtual void _stdcall Fy()=0;
};
interface IZ:IUnknown
{
virtual void _stdcall Fz()=0;
};
//forward references for guids
extern const IID IID_IX;
extern const IID IID_IY;
extern const IID IID_IZ;
//component
class CA:public IX,public IY
{
//IUnknown implementation
virtual HRESULT _stdcall QueryInterface(const IID& iid,void ** ppv);
virtual ULONG _stdcall AddRef(){return 0;}
virtual ULONG _stdcall Release(){return 0;}
//interface IX implementation
virtual void _stdcall Fx() {cout<<"FX"<<endl;MessageBox(NULL,"hello world","caption",MB_OK);};
//interface IY implementation
virtual void _stdcall Fy(){cout<<"FY"<<endl;}
};
HRESULT _stdcall CA::QueryInterface(const IID& iid,void ** ppv)
{
if(iid==IID_IUnknown)
{
trace("QueryInterface:return pointer to IUnknown");
*ppv=static_cast<IX *>(this);
}
else if(iid==IID_IX)
{
trace("QueryInterface:Return pointer to IX.");
*ppv=static_cast<IX *>(this);
}
else if(iid==IID_IY)
{
trace("QuertyInterface:Return pointer to IY");
*ppv=static_cast<IY *>(this);
}
else
{
trace("QuertyInterface:Interface not supported");
*ppv=NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
return S_OK;
}
//creation function
IUnknown * CreateInstance()
{
IUnknown * pI=static_cast<IX *>(new CA);
pI->AddRef();
return pI;
}
//IIDS
// {C225EDDE-ACFE-4349-AD2B-C7068731F8B3}
static const IID IID_IX =
{ 0xc225edde, 0xacfe, 0x4349, { 0xad, 0x2b, 0xc7, 0x6, 0x87, 0x31, 0xf8, 0xb3 } };
// {6E3A34D9-1E23-433b-A393-1A4A6A965C80}
static const IID IID_IY =
{ 0x6e3a34d9, 0x1e23, 0x433b, { 0xa3, 0x93, 0x1a, 0x4a, 0x6a, 0x96, 0x5c, 0x80 } };
// {D8CDFA09-D552-41b9-AA44-8A70D8554A5C}
static const IID IID_IZ =
{ 0xd8cdfa09, 0xd552, 0x41b9, { 0xaa, 0x44, 0x8a, 0x70, 0xd8, 0x55, 0x4a, 0x5c } };
//client
int main()
{
HRESULT hr;
trace("client: Get an IUnknown pointer");
IUnknown * pIUnKnown=CreateInstance();
trace("client: Get interface IX");
IX* pIX=NULL;
hr=pIUnKnown->QueryInterface(IID_IX,(void **) &pIX);
if(SUCCEEDED(hr))
{
trace("client:Succeeded getting IX");
pIX->Fx();//use interface IX
}
trace("client: Get interface IY");
IY *pIY=NULL;
hr=pIUnKnown->QueryInterface(IID_IY,(void **) &pIY);
if(SUCCEEDED(hr))
{
trace("client: Succeeded get IY");
pIY->Fy();//use interface IY
}
trace("client:ask for an unsupporte interface");
IZ * pIZ=NULL;
hr=pIUnKnown->QueryInterface(IID_IZ,(void **) &pIZ);
if(SUCCEEDED(hr))
{
trace("client:succeeded in geting interface iz");
pIZ->Fz();
}
else
{
trace("client: could not get interface IZ");
}
trace("client: get interface IY from interface IX");
IY *pIYfromIX=NULL;
hr=pIX->QueryInterface(IID_IY,(void **)&pIYfromIX);
if(SUCCEEDED(hr))
{
trace("client:succeeded getting IY");
pIYfromIX->Fy();
}
trace("client: get interface IUNkown from IY");
IUnknown * pIUnknownFromIY=NULL;
hr=pIY->QueryInterface(IID_IUnknown,(void **) &pIUnknownFromIY);
if(SUCCEEDED(hr))
{
cout<<"Are the IUnknown pointers equal";
if(pIUnknownFromIY==pIUnKnown)
{
cout<<"Yes,pIUnknownFromIY==pIUnknown"<<endl;
}
else
{
cout<<"No,pIUnknownFrom IY!=pIUnknown"<<endl;
}
}
//Delete the component
delete pIUnKnown;
system("pause");
return 0;
}
#include <objbase.h>
#include <windows.h>
using namespace std;
void trace(const char *msg){cout<<msg<<endl;}
//interfaces
interface IX:IUnknown
{
virtual void _stdcall Fx()=0;
};
interface IY:IUnknown
{
virtual void _stdcall Fy()=0;
};
interface IZ:IUnknown
{
virtual void _stdcall Fz()=0;
};
//forward references for guids
extern const IID IID_IX;
extern const IID IID_IY;
extern const IID IID_IZ;
//component
class CA:public IX,public IY
{
//IUnknown implementation
virtual HRESULT _stdcall QueryInterface(const IID& iid,void ** ppv);
virtual ULONG _stdcall AddRef(){return 0;}
virtual ULONG _stdcall Release(){return 0;}
//interface IX implementation
virtual void _stdcall Fx() {cout<<"FX"<<endl;MessageBox(NULL,"hello world","caption",MB_OK);};
//interface IY implementation
virtual void _stdcall Fy(){cout<<"FY"<<endl;}
};
HRESULT _stdcall CA::QueryInterface(const IID& iid,void ** ppv)
{
if(iid==IID_IUnknown)
{
trace("QueryInterface:return pointer to IUnknown");
*ppv=static_cast<IX *>(this);
}
else if(iid==IID_IX)
{
trace("QueryInterface:Return pointer to IX.");
*ppv=static_cast<IX *>(this);
}
else if(iid==IID_IY)
{
trace("QuertyInterface:Return pointer to IY");
*ppv=static_cast<IY *>(this);
}
else
{
trace("QuertyInterface:Interface not supported");
*ppv=NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
return S_OK;
}
//creation function
IUnknown * CreateInstance()
{
IUnknown * pI=static_cast<IX *>(new CA);
pI->AddRef();
return pI;
}
//IIDS
// {C225EDDE-ACFE-4349-AD2B-C7068731F8B3}
static const IID IID_IX =
{ 0xc225edde, 0xacfe, 0x4349, { 0xad, 0x2b, 0xc7, 0x6, 0x87, 0x31, 0xf8, 0xb3 } };
// {6E3A34D9-1E23-433b-A393-1A4A6A965C80}
static const IID IID_IY =
{ 0x6e3a34d9, 0x1e23, 0x433b, { 0xa3, 0x93, 0x1a, 0x4a, 0x6a, 0x96, 0x5c, 0x80 } };
// {D8CDFA09-D552-41b9-AA44-8A70D8554A5C}
static const IID IID_IZ =
{ 0xd8cdfa09, 0xd552, 0x41b9, { 0xaa, 0x44, 0x8a, 0x70, 0xd8, 0x55, 0x4a, 0x5c } };
//client
int main()
{
HRESULT hr;
trace("client: Get an IUnknown pointer");
IUnknown * pIUnKnown=CreateInstance();
trace("client: Get interface IX");
IX* pIX=NULL;
hr=pIUnKnown->QueryInterface(IID_IX,(void **) &pIX);
if(SUCCEEDED(hr))
{
trace("client:Succeeded getting IX");
pIX->Fx();//use interface IX
}
trace("client: Get interface IY");
IY *pIY=NULL;
hr=pIUnKnown->QueryInterface(IID_IY,(void **) &pIY);
if(SUCCEEDED(hr))
{
trace("client: Succeeded get IY");
pIY->Fy();//use interface IY
}
trace("client:ask for an unsupporte interface");
IZ * pIZ=NULL;
hr=pIUnKnown->QueryInterface(IID_IZ,(void **) &pIZ);
if(SUCCEEDED(hr))
{
trace("client:succeeded in geting interface iz");
pIZ->Fz();
}
else
{
trace("client: could not get interface IZ");
}
trace("client: get interface IY from interface IX");
IY *pIYfromIX=NULL;
hr=pIX->QueryInterface(IID_IY,(void **)&pIYfromIX);
if(SUCCEEDED(hr))
{
trace("client:succeeded getting IY");
pIYfromIX->Fy();
}
trace("client: get interface IUNkown from IY");
IUnknown * pIUnknownFromIY=NULL;
hr=pIY->QueryInterface(IID_IUnknown,(void **) &pIUnknownFromIY);
if(SUCCEEDED(hr))
{
cout<<"Are the IUnknown pointers equal";
if(pIUnknownFromIY==pIUnKnown)
{
cout<<"Yes,pIUnknownFromIY==pIUnknown"<<endl;
}
else
{
cout<<"No,pIUnknownFrom IY!=pIUnknown"<<endl;
}
}
//Delete the component
delete pIUnKnown;
system("pause");
return 0;
}