//Inside Com+ Base Service 中的例子..// component.idl
import "unknwn.idl";[ object, uuid(10000001-0000-0000-0000-000000000001),
  oleautomation ]
interface ISum : IUnknown
{
HRESULT Sum(int x, int y, [out, retval] int* retval);
}[ object, uuid(10000005-0000-0000-0000-000000000001),
  oleautomation ]
interface IOutGoing : IUnknown
{
HRESULT GotMessage(int Message);
}[ uuid(10000003-0000-0000-0000-000000000001),
  helpstring("Inside COM+ Component Type Library"),
  version(1.0) ]
library Component
{
importlib("stdole32.tlb"); interface ISum;
interface IOutGoing; [ uuid(10000002-0000-0000-0000-000000000001) ]
coclass InsideCOM
{
interface ISum;
[source] interface IOutGoing;
}
};
// 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 functionslong 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()
    {
    if(--m_cRef != 0)
        return m_cRef;
    delete this;
    return 0;
    }CConnectionPoint::CConnectionPoint(CInsideCOM* pObj, REFIID riid) : m_cRef(0)
{
g_cComponents++;
    m_iid = riid; // Don't need AddRef/Release since we are nested inside CInsideCOM
    m_pObj = pObj;
    for(int count = 0; count < CCONNMAX; count++)
        {
        m_rgpUnknown[count] = NULL;
        m_rgnCookies[count] = 0;
        }
    m_cConn = 0;
    m_nCookieNext = 10; // Arbitrary starting cookie value
}CConnectionPoint::~CConnectionPoint()
{
g_cComponents--;
    for(int count = 0; count < CCONNMAX; count++)
if(m_rgpUnknown[count] != NULL)
{
        m_rgpUnknown[count]->Release();
m_rgpUnknown[count] = NULL;
}
}HRESULT CConnectionPoint::QueryInterface(REFIID riid, void** ppv)
{
    if(IID_IUnknown == riid || IID_IConnectionPoint == riid)
        *ppv = (IConnectionPoint*)this;
    else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}ULONG CConnectionPoint::AddRef()
    {
    return ++m_cRef;
    }ULONG CConnectionPoint::Release()
    {
    if(--m_cRef != 0)
        return m_cRef;
    delete this;
    return 0;
    }HRESULT CConnectionPoint::GetConnectionInterface(IID *pIID)
{
if(pIID == NULL)
return E_POINTER;
*pIID = m_iid;
return S_OK;
}HRESULT CConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer** ppCPC)
{
return m_pObj->QueryInterface(IID_IConnectionPointContainer, (void**)ppCPC);
}HRESULT CConnectionPoint::Advise(IUnknown* pUnknownSink, DWORD* pdwCookie)
{
IUnknown* pSink;
*pdwCookie = 0;
if(m_cConn == CCONNMAX)
return CONNECT_E_ADVISELIMIT;
if(FAILED(pUnknownSink->QueryInterface(m_iid, (void**)&pSink)))
return CONNECT_E_CANNOTCONNECT;
for(int count = 0; count < CCONNMAX; count++)
if(m_rgpUnknown[count] == NULL)
{
m_rgpUnknown[count] = pSink;
m_rgnCookies[count] = ++m_nCookieNext;
*pdwCookie = m_nCookieNext;
break;
}
m_cConn++; // Hack here to copy pointer to a global variable so that we can use it from main()
g_pOutGoing = (IOutGoing*)pSink; return NOERROR;
}HRESULT CConnectionPoint::Unadvise(DWORD dwCookie)
{
if(dwCookie == 0)
return E_INVALIDARG;
for(int count = 0; count < CCONNMAX; count++)
if(dwCookie == m_rgnCookies[count])
{
if(m_rgpUnknown[count] != NULL)
{
m_rgpUnknown[count]->Release();
m_rgpUnknown[count] = NULL;
}
m_cConn--;
return NOERROR;
}
return CONNECT_E_NOCONNECTION;
}HRESULT CConnectionPoint::EnumConnections(IEnumConnections** ppEnum)
{
*ppEnum = NULL;
CONNECTDATA* pCD = new CONNECTDATA[m_cConn];
for(int count1 = 0, count2 = 0; count1 < CCONNMAX; count1++)
if(m_rgpUnknown[count1] != NULL)
{
pCD[count2].pUnk = (IUnknown*)m_rgpUnknown[count1];
pCD[count2].dwCookie = m_rgnCookies[count1];
count2++;
}
CEnumConnections* pEnum = new CEnumConnections(this, m_cConn, pCD);
delete [] pCD;
return pEnum->QueryInterface(IID_IEnumConnections, (void**)ppEnum);
}HRESULT CInsideCOM::EnumConnectionPoints(IEnumConnectionPoints** ppEnum)
{
cout << "Component: CInsideCOM::EnumConnectionPoints()" << endl;
CEnumConnectionPoints* pEnum = new CEnumConnectionPoints(reinterpret_cast<IUnknown*>(this), (void**)m_rgpConnPt);
return pEnum->QueryInterface(IID_IEnumConnectionPoints, (void**)ppEnum);
}HRESULT CInsideCOM::FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP)
{
if(riid == IID_IOutGoing)
{
cout << "Component: CInsideCOM::FindConnectionPoint() for IID_IOutGoing" << endl;
return m_rgpConnPt[0]->QueryInterface(IID_IConnectionPoint, (void**)ppCP);
}
return E_NOINTERFACE;
}HRESULT CInsideCOM::GetClassInfo(ITypeInfo** pTypeInfo)
{
ITypeLib* pTypeLib;
LoadRegTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, &pTypeLib);
HRESULT hr = pTypeLib->GetTypeInfoOfGuid(CLSID_InsideCOM, pTypeInfo);
pTypeLib->Release();
return hr;
}HRESULT CInsideCOM::GetGUID(DWORD dwGuidKind, GUID* pGUID)
{
if(pGUID == NULL)
return E_INVALIDARG;
*pGUID = IID_IOutGoing;
return S_OK;
}ULONG CInsideCOM::AddRef()
{
return ++m_cRef;
}ULONG CInsideCOM::Release()
{
    if(--m_cRef != 0)
        return m_cRef;
SetEvent(g_hEvent);
    delete this;
    return 0;
}HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown)
*ppv = reinterpret_cast<IUnknown*>(this);
else if(riid == IID_ISum)
{
cout << "Component: CInsideCOM::QueryInterface() for ISum returning " << this << endl;
*ppv = (ISum*)this;
}
else if(riid == IID_IConnectionPointContainer)
{
cout << "Component: CInsideCOM::QueryInterface() for IConnectionPointContainer" << endl;
*ppv = (IConnectionPointContainer*)this;
}
else if(riid == IID_IProvideClassInfo)
{
MessageBox(NULL, "QueryInterface", "IProvideClassInfo", MB_OK);
*ppv = NULL;
return E_NOINTERFACE;
}
else 
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}HRESULT CInsideCOM::Sum(int x, int y, int* retval)
{
cout << "Component: CInsideCOM::Sum() " << x << " + " << y << " = " << x + y << endl;
*retval = x + y;
return S_OK;
}class CFactory : public IClassFactory
{
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv); // IClassFactory
HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv);
HRESULT __stdcall LockServer(BOOL bLock); CFactory() : m_cRef(0) { g_cComponents++; }
~CFactory() { g_cComponents--; }private:
long m_cRef;
};ULONG CFactory::AddRef()
{
return ++m_cRef;
}ULONG CFactory::Release()
{
    if(--m_cRef != 0)
        return m_cRef;
    delete this;
    return 0;
}HRESULT CFactory::QueryInterface(REFIID iid, void** ppv)
{
if((iid == IID_IUnknown) || (iid == IID_IClassFactory))
*ppv = (IClassFactory *)this;
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv)
{
if(pUnknownOuter != NULL)
return CLASS_E_NOAGGREGATION; CInsideCOM *pInsideCOM = new CInsideCOM;
cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl; if(pInsideCOM == NULL)
return E_OUTOFMEMORY; // QueryInterface probably for IID_IUNKNOWN
return pInsideCOM->QueryInterface(iid, ppv);
}HRESULT CFactory::LockServer(BOOL bLock)
{
if(bLock)
g_cServerLocks++;
else
g_cServerLocks--;
return S_OK;
}void RegisterComponent()
{
ITypeLib* pTypeLib;
LoadTypeLibEx(L"component.exe", REGKIND_DEFAULT, &pTypeLib);
RegisterServer("component.exe", CLSID_InsideCOM, "Inside COM Sample #1", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
}void CommandLineParameters(int argc, char** argv)
{
RegisterComponent();
if(argc < 2)
{
cout << "No parameter, but registered anyway..." << endl;
exit(false);
}
char* szToken = strtok(argv[1], "-/"); 
if(_stricmp(szToken, "RegServer") == 0)
{
RegisterComponent();
cout << "RegServer" << endl;
exit(true);
}
if(_stricmp(szToken, "UnregServer") == 0)
{
UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
cout << "UnregServer" << endl;
exit(true);
}
if(_stricmp(szToken, "Embedding") != 0)
{
cout << "Invalid parameter" << endl;
exit(false);
}
}void main(int argc, char** argv)
{
CommandLineParameters(argc, argv);
g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); CoInitializeEx(NULL, COINIT_MULTITHREADED); DWORD dwRegister;
IClassFactory *pCFactory = new CFactory();
CoRegisterClassObject(CLSID_InsideCOM, pCFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); cout << "Press any key to fire an event at the client" << endl;
HANDLE handles[2] = { g_hEvent, GetStdHandle(STD_INPUT_HANDLE) };
while(WaitForMultipleObjects(2, handles, FALSE, INFINITE) - WAIT_OBJECT_0 == 1)
{
INPUT_RECORD ir;
DWORD read;
ReadConsoleInput(handles[1], &ir, 1, &read);
if(ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown == TRUE)
g_pOutGoing->GotMessage(ir.Event.KeyEvent.uChar.AsciiChar);
} CoRevokeClassObject(dwRegister);
CoUninitialize();
}
// client.cpp
#define _WIN32_DCOM
#include <olectl.h>
#include <conio.h>
#include <iostream.h>
#include "Component\component.h"class CSink : public IOutGoing
{
public:
// IUnknown
ULONG __stdcall AddRef();
ULONG __stdcall Release();
HRESULT __stdcall QueryInterface(REFIID iid, void** ppv); // IOutGoing
HRESULT __stdcall GotMessage(int Message); CSink() : m_cRef(0) {  }
~CSink() { }private:
long m_cRef;
};ULONG CSink::AddRef()
{
return ++m_cRef;
}ULONG CSink::Release()
{
if(--m_cRef != 0)
return m_cRef;
delete this;
return 0;
}HRESULT CSink::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown)
{
*ppv = (IUnknown*)this;
}
else if(riid == IID_IOutGoing)
{
cout << "Component: CInsideCOM::QueryInterface() for IOutGoing" << endl;
*ppv = (IOutGoing*)this;
}
else 
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}HRESULT CSink::GotMessage(int Message)
{
if(Message == (int)'b' || Message == (int)'B')
PlaySound("BrockschmidtQuack", NULL, SND_RESOURCE|SND_ASYNC);
cout << "CSink::GotMessage is " << (char)Message << endl;
return S_OK;
}void main()
{
cout << "Client: Calling CoInitialize()" << endl;
CoInitializeEx(NULL, COINIT_MULTITHREADED);

IUnknown* pUnknown;
cout << "Client: Calling CoCreateInstance() " << endl;
CoCreateInstance(CLSID_InsideCOM, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pUnknown); IConnectionPointContainer* pConnectionPointContainer;
HRESULT hr = pUnknown->QueryInterface(IID_IConnectionPointContainer, (void**)&pConnectionPointContainer);
if(FAILED(hr))
cout << "Not a connectable object, going to crash now" << endl; IEnumConnectionPoints* pEnumConnectionPoints;
IEnumConnectionPoints* pEnumConnectionPoints2;
hr = pConnectionPointContainer->EnumConnectionPoints(&pEnumConnectionPoints); ULONG num_fetched;
IConnectionPoint* pConnectionPoint;
hr = pEnumConnectionPoints->Clone(&pEnumConnectionPoints2);
hr = pEnumConnectionPoints2->Next(1, &pConnectionPoint, &num_fetched);
cout << "Next hr = " << hr << " num_fetched = " << num_fetched << endl;
pEnumConnectionPoints->Release();
pEnumConnectionPoints2->Release(); IID my_iid;
pConnectionPoint->GetConnectionInterface(&my_iid); char buffer[39];
OLECHAR ppsz[39];
StringFromGUID2(my_iid, ppsz, 39);
WideCharToMultiByte(CP_ACP, 0, ppsz, 39, buffer, 39, NULL, NULL);
cout << "IID: " << buffer << endl; IConnectionPointContainer* CPC;
pConnectionPoint->GetConnectionPointContainer(&CPC);
if(CPC == pConnectionPointContainer)
cout << " THEY EQUAL " << endl;
CPC->Release();// IConnectionPoint* pConnectionPoint;
// hr = pConnectionPointContainer->FindConnectionPoint(IID_IOutGoing, &pConnectionPoint);
// cout << "FindConnectionPoint returns " << hr << " pConnectionPoint = " << pConnectionPoint << endl; CSink* mySink = new CSink;
DWORD dwCookie;
pConnectionPoint->Advise((IUnknown*)mySink, &dwCookie);
cout << "CLIENT CALLED ADVISE" << hr << endl; IEnumConnections* pEnumConnections;
pConnectionPoint->EnumConnections(&pEnumConnections);
CONNECTDATA my_cd;
ULONG dd;
pEnumConnections->Next(1, &my_cd, &dd);
cout << "MY COOKIE = " << my_cd.dwCookie << endl;
cout << "MY COOKIE2 = " << dwCookie << endl;
pEnumConnections->Release(); cout << "Press any key to exit" << endl;
_getch(); pConnectionPoint->Unadvise(dwCookie);
pConnectionPoint->Release();
pConnectionPointContainer->Release(); cout << "Client: Calling Release() for pUnknown" << endl;
hr = pUnknown->Release(); cout << "Client: Calling CoUninitialize()" << endl;
CoUninitialize();
}