📄 local.cpp
字号:
// local.cpp
#define _WIN32_DCOM
#include <iostream.h> // For cout
#include <olectl.h> // For connection point interfaces
#include "Component\component.h" // Generated by MIDL
#include "registry.h" // For registration functions
long g_cComponents = 0;
long g_cServerLocks = 0;
HANDLE g_hEvent;
IOutGoing* g_pOutGoing;
const NUM_CONNECTION_POINTS = 1;
const CCONNMAX = 2;
class CEnumConnectionPoints : public IEnumConnectionPoints
{
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
// IEnumConnectionPoints
HRESULT __stdcall Next(ULONG cConnections, IConnectionPoint** rgpcn, ULONG* pcFetched);
HRESULT __stdcall Skip(ULONG cConnections);
HRESULT __stdcall Reset();
HRESULT __stdcall Clone(IEnumConnectionPoints** ppEnum);
CEnumConnectionPoints(IUnknown* pUnkRef, void** rgpCP);
~CEnumConnectionPoints();
private:
long m_cRef;
IUnknown* m_pUnkRef; // IUnknown for ref counting
int m_iCur; // Current element
IConnectionPoint* m_rgpCP[NUM_CONNECTION_POINTS]; // Array of connection points
};
// void** rpgCP is used so that this constructor can accept either CConnectionPoint**
// from CInsideCOM::EnumConnectionPoints or IConnectionPoint** from CEnumConnectionPoints::Clone
// This could also be done by overloading the constructor and duplicating some of this code
CEnumConnectionPoints::CEnumConnectionPoints(IUnknown* pUnkRef, void** rgpCP) : m_cRef(0)
{
g_cComponents++;
m_iCur = 0;
m_pUnkRef = pUnkRef;
// m_rgpCP is a pointer to an array of IConnectionPoints or CConnectionPoints
for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
((IUnknown*)rgpCP[count])->QueryInterface(IID_IConnectionPoint, (void**)&m_rgpCP[count]);
}
CEnumConnectionPoints::~CEnumConnectionPoints()
{
g_cComponents--;
if(m_rgpCP != NULL)
for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
m_rgpCP[count]->Release();
}
ULONG CEnumConnectionPoints::AddRef()
{
m_pUnkRef->AddRef();
return ++m_cRef;
}
ULONG CEnumConnectionPoints::Release()
{
m_pUnkRef->Release();
if(--m_cRef != 0)
return m_cRef;
delete this;
return 0;
}
HRESULT CEnumConnectionPoints::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown || riid == IID_IEnumConnectionPoints)
*ppv = (IEnumConnectionPoints*)this;
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
HRESULT CEnumConnectionPoints::Next(ULONG cConnections, IConnectionPoint** rgpcn, ULONG* pcFetched)
{
if(rgpcn == NULL)
return E_POINTER;
if(pcFetched == NULL && cConnections != 1)
return E_INVALIDARG;
if(pcFetched != NULL)
*pcFetched = 0;
while(m_iCur < NUM_CONNECTION_POINTS && cConnections > 0)
{
*rgpcn = m_rgpCP[m_iCur++];
if(*rgpcn != NULL)
(*rgpcn)->AddRef();
if(pcFetched != NULL)
(*pcFetched)++;
cConnections--;
rgpcn++;
}
return S_OK;
}
HRESULT CEnumConnectionPoints::Skip(ULONG cConnections)
{
if(m_iCur + cConnections >= NUM_CONNECTION_POINTS)
return S_FALSE;
m_iCur += cConnections;
return S_OK;
}
HRESULT CEnumConnectionPoints::Reset()
{
m_iCur = 0;
return S_OK;
}
HRESULT CEnumConnectionPoints::Clone(IEnumConnectionPoints** ppEnum)
{
if(ppEnum == NULL)
return E_POINTER;
*ppEnum = NULL;
// Create the clone
CEnumConnectionPoints* pNew = new CEnumConnectionPoints(m_pUnkRef, (void**)m_rgpCP);
if(pNew == NULL)
return E_OUTOFMEMORY;
pNew->AddRef();
pNew->m_iCur = m_iCur;
*ppEnum = pNew;
return S_OK;
}
class CConnectionPoint;
class CInsideCOM : public ISum, public IConnectionPointContainer, public IProvideClassInfo2
{
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
// IConnectionPointContainer
HRESULT __stdcall EnumConnectionPoints(IEnumConnectionPoints** ppEnum);
HRESULT __stdcall FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP);
// IProvideClassInfo2
HRESULT __stdcall GetClassInfo(ITypeInfo** pTypeInfo);
HRESULT __stdcall GetGUID(DWORD dwGuidKind, GUID* pGUID);
// ISum
HRESULT __stdcall Sum(int x, int y, int* retval);
CInsideCOM();
~CInsideCOM();
private:
long m_cRef;
CConnectionPoint* m_rgpConnPt[NUM_CONNECTION_POINTS];
};
class CConnectionPoint : public IConnectionPoint
{
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
// IConnectionPoint
HRESULT __stdcall GetConnectionInterface(IID *pIID);
HRESULT __stdcall GetConnectionPointContainer(IConnectionPointContainer** ppCPC);
HRESULT __stdcall Advise(IUnknown* pUnknownSink, DWORD* pdwCookie);
HRESULT __stdcall Unadvise(DWORD dwCookie);
HRESULT __stdcall EnumConnections(IEnumConnections** ppEnum);
CConnectionPoint(CInsideCOM* pObj, REFIID refiid);
~CConnectionPoint();
private:
int m_cRef;
CInsideCOM* m_pObj;
IID m_iid;
int m_cConn;
int m_nCookieNext;
unsigned m_rgnCookies[CCONNMAX];
IUnknown* m_rgpUnknown[CCONNMAX];
};
class CEnumConnections : public IEnumConnections
{
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
// IEnumConnections
HRESULT __stdcall Next(ULONG cConnections, CONNECTDATA* rgpcd, ULONG* pcFetched);
HRESULT __stdcall Skip(ULONG cConnections);
HRESULT __stdcall Reset();
HRESULT __stdcall Clone(IEnumConnections** ppEnum);
CEnumConnections(IUnknown* pUnknown, int cConn, CONNECTDATA* pConnData);
~CEnumConnections();
private:
int m_cRef;
IUnknown* m_pUnkRef; // IUnknown for ref counting
unsigned m_iCur; // Current element
unsigned m_cConn; // Number of connections
CONNECTDATA* m_rgConnData; // Source of connections
};
CInsideCOM::CInsideCOM() : m_cRef(0)
{
g_cComponents++;
m_cRef = 0;
// Initialize all the connection points to NULL
for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
m_rgpConnPt[count] = NULL;
// Create our connection point
m_rgpConnPt[0] = new CConnectionPoint(this, IID_IOutGoing);
m_rgpConnPt[0]->AddRef();
// Additional connection points could be instantiated here
}
CInsideCOM::~CInsideCOM()
{
g_cComponents--;
for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
if(m_rgpConnPt[count] != NULL)
delete m_rgpConnPt[count];
}
CEnumConnections::CEnumConnections(IUnknown* pUnknown, int cConn, CONNECTDATA* pConnData) : m_cRef(0)
{
g_cComponents++;
m_pUnkRef = pUnknown;
m_iCur = 0;
m_cConn = 0;
m_rgConnData = new CONNECTDATA[cConn];
if(m_rgConnData != NULL)
for(int count = 0; count < cConn; count++)
{
m_rgConnData[count] = pConnData[count];
m_rgConnData[count].pUnk->AddRef();
}
}
CEnumConnections::~CEnumConnections()
{
g_cComponents--;
if(m_rgConnData != NULL)
{
for(unsigned count = 0; count < m_cConn; count++)
m_rgConnData[count].pUnk->Release();
delete [] m_rgConnData;
}
}
HRESULT CEnumConnections::Next(ULONG cConnections, CONNECTDATA* rgpcd, ULONG* pcFetched)
{
if(pcFetched == NULL && cConnections != 1)
return E_INVALIDARG;
if(pcFetched != NULL)
*pcFetched = 0;
if(rgpcd == NULL || m_iCur >= m_cConn)
return S_FALSE;
unsigned cReturn = 0;
while(m_iCur < m_cConn && cConnections > 0)
{
*rgpcd++ = m_rgConnData[m_iCur];
m_rgConnData[m_iCur++].pUnk->AddRef();
cReturn++;
cConnections--;
}
if(pcFetched != NULL)
*pcFetched = cReturn;
return S_OK;
}
HRESULT CEnumConnections::Skip(ULONG cConnections)
{
if(m_iCur + cConnections >= m_cConn)
return S_FALSE;
m_iCur += cConnections;
return S_OK;
}
HRESULT CEnumConnections::Reset()
{
m_iCur = 0;
return S_OK;
}
HRESULT CEnumConnections::Clone(IEnumConnections** ppEnum)
{
if(ppEnum == NULL)
return E_POINTER;
*ppEnum = NULL;
// Create the clone
CEnumConnections* pNew = new CEnumConnections(m_pUnkRef, m_cConn, m_rgConnData);
if(NULL == pNew)
return E_OUTOFMEMORY;
pNew->AddRef();
pNew->m_iCur = m_iCur;
*ppEnum = pNew;
return S_OK;
}
HRESULT CEnumConnections::QueryInterface(REFIID riid, void** ppv)
{
if(IID_IUnknown == riid || IID_IEnumConnections == riid)
*ppv = (IEnumConnections*)this;
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
ULONG CEnumConnections::AddRef()
{
return ++m_cRef;
}
ULONG CEnumConnections::Release()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -