下面我们将把前面所提到过和各代码段组合起来,以构成一个说明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 ;
}