1.在下面的连接中下载<<COM技术内幕>>电子版图书,此书为.PDG格式文件,可以使用超星阅览器打开阅读.
http://218.108.41.12/vchome/book/allbook.asp
2.书中的代码整理:
1)
#include <iostream.h>
#include <objbase.h>
void trace(const char* pMsg)
{
cout<<pMsg<<endl;
}
interface IX
{
virtual void _stdcall Fx1() = 0;
virtual void _stdcall Fx2() = 0;
};
interface IY
{
virtual void _stdcall Fy1() = 0;
virtual void _stdcall Fy2() = 0;
};
class CA:public IX,
public IY
{
public:
virtual void _stdcall Fx1()
{
cout<<"CA::Fx1"<<endl;
}
virtual void _stdcall Fx2()
{
cout<<"CA::Fx2"<<endl;
}
virtual void _stdcall Fy1()
{
cout<<"CA::Fy1"<<endl;
}
virtual void _stdcall Fy2()
{
cout<<"CA::Fy2"<<endl;
}
};
int main()
{
trace("clinet: create an instance of the component.");
CA* pA = new CA;
IX* pIX = pA;
trace("client: use the IX interface.");
pIX->Fx1();
pIX->Fx2();
IY* pIY = pA;
trace("client: use the IY interfacea.");
pIY->Fy1();
pIY->Fy2();
trace("client: Delet the component.");
delete pA;
return 0;
}
2)
#include <iostream.h>
#include <objbase.h>
void trace(const char* msg)
{
cout<<msg<<endl;
}
interface IX: IUnknown
{
virtual void _stdcall Fx() = 0;
};
interface IY:IUnknown
{
virtual void _stdcall Fy() = 0;
};
interface IZ:IUnknown
{
virtual void _stdcall Fz() = 0;
};
extern const IID IID_IX;
extern const IID IID_IY;
extern const IID IID_IZ;
class CA:public IX,
public IY
{
virtual HRESULT _stdcall QueryInterface(const IID& iid, void **ppv);
virtual ULONG _stdcall AddRef() {return 0;}
virtual ULONG _stdcall Release() {return 0;}
virtual void _stdcall Fx() {cout<<"Fx"<<endl;}
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("QueryInterface: Return pointer to IY.");
*ppv = static_cast<IY*>(this);
}
else
{
trace("QueryInterface: Interface not supported.");
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
IUnknown* CreateInstance()
{
IUnknown* PI = static_cast<IX*>(new CA);
PI->AddRef();
return PI;
}
static const IID IID_IX =
{0x32bb8320,0xb41b,0x11cf,{0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82}};
static const IID IID_IY =
{0x32bb8321,0xb41b,0x11cf,{0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82}};
static const IID IID_IZ =
{0x32bb8322,0xb41b,0x11cf,{0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82}};
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();
}
trace("client: Get interface IY.");
IY* pIY = NULL;
hr = pIUnknown->QueryInterface(IID_IY,(void**)&pIY);
if(SUCCEEDED(hr))
{
trace("client: succeeded getting IY.");
pIY->Fy();
}
trace("client: Get interface IZ.");
IZ* pIZ = NULL;
hr = pIUnknown->QueryInterface(IID_IZ,(void**)&pIZ);
if(SUCCEEDED(hr))
{
trace("client: succeeded getting 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 IUnknown from IY.");
IUnknown* pIUnknownFromIY = NULL;
hr = pIY->QueryInterface(IID_IUnknown,(void**)&pIUnknownFromIY);
if(SUCCEEDED(hr))
{
cout<<"Are the IUnknown pointers equal?"<<endl;
if(pIUnknownFromIY == pIUnknown)
{
cout<<"yes,pIUnknownFromIY == pIUnknown."<<endl;
}
else
{
cout<<"no,pIUnknownFromIY != pIUnknown."<<endl;
}
}
delete pIUnknown;
return 0;
}
3)
#include <iostream.h>
#include <objbase.h>
void trace(const char* msg)
{
cout<<msg<<endl;
}
interface IX: IUnknown
{
virtual void _stdcall Fx() = 0;
};
interface IY:IUnknown
{
virtual void _stdcall Fy() = 0;
};
interface IZ:IUnknown
{
virtual void _stdcall Fz() = 0;
};
extern const IID IID_IX;
extern const IID IID_IY;
extern const IID IID_IZ;
class CA:public IX,
public IY
{
virtual HRESULT _stdcall QueryInterface(const IID& iid, void **ppv);
virtual ULONG _stdcall AddRef();
virtual ULONG _stdcall Release();
virtual void _stdcall Fx() {cout<<"Fx"<<endl;}
virtual void _stdcall Fy() {cout<<"Fy"<<endl;}
public:
CA():m_cRef(0){}
~CA(){trace("CA: Destroy self.");}
private:
long m_cRef;
};
HRESULT _stdcall CA::QueryInterface(const IID& iid, void** ppv)
{
if(iid == IID_IUnknown)
{
trace("CA QI: Return pointer to IUnknown.");
*ppv = static_cast<IX*>(this);
}
else if(iid == IID_IX)
{
trace("CA QI: Return pointer to IX.");
*ppv = static_cast<IX*>(this);
}
else if (iid == IID_IY)
{
trace("CA QI: Return pointer to IY.");
*ppv = static_cast<IY*>(this);
}
else
{
trace("QueryInterface: Interface not supported.");
*ppv = NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef();
return S_OK;
}
ULONG _stdcall CA::AddRef()
{
cout<<"CA: AddRef = "<<m_cRef + 1<<'.'<<endl;
return InterlockedIncrement(&m_cRef);
}
ULONG _stdcall CA::Release()
{
cout<<"CA: Release = "<<m_cRef - 1<<'.'<<endl;
if(InterlockedDecrement(&m_cRef) == 0)
{
delete this;
return 0;
}
return m_cRef;
}
IUnknown* CreateInstance()
{
IUnknown* PI = static_cast<IX*>(new CA);
PI->AddRef();
return PI;
}
static const IID IID_IX =
{0x32bb8320,0xb41b,0x11cf,{0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82}};
static const IID IID_IY =
{0x32bb8321,0xb41b,0x11cf,{0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82}};
static const IID IID_IZ =
{0x32bb8322,0xb41b,0x11cf,{0xa6,0xbb,0x0,0x80,0xc7,0xb2,0xd6,0x82}};
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();
pIX->Release();
}
trace("client: Get interface IY.");
IY* pIY = NULL;
hr = pIUnknown->QueryInterface(IID_IY,(void**)&pIY);
if(SUCCEEDED(hr))
{
trace("client: succeeded getting IY.");
pIY->Fy();
pIY->Release();
}
trace("client: Get interface IZ.");
IZ* pIZ = NULL;
hr = pIUnknown->QueryInterface(IID_IZ,(void**)&pIZ);
if(SUCCEEDED(hr))
{
trace("client: succeeded getting IZ.");
pIZ->Fz();
pIZ->Release();
}
else
{
trace("client: could not get interface IZ.");
}
pIUnknown->Release();
return 0;
}