local.cpp
上传用户:bjlvip
上传日期:2010-02-08
资源大小:744k
文件大小:17k
源码类别:

Windows编程

开发平台:

Visual C++

  1. // local.cpp
  2. #define _WIN32_DCOM
  3. #include <iostream.h>  // For cout
  4. #include <olectl.h>    // For connection point interfaces
  5. #include "Componentcomponent.h" // Generated by MIDL
  6. #include "registry.h"  // For registration functions
  7. long g_cComponents = 0;
  8. long g_cServerLocks = 0;
  9. HANDLE g_hEvent;
  10. IOutGoing* g_pOutGoing;
  11. const NUM_CONNECTION_POINTS = 1;
  12. const CCONNMAX = 2;
  13. class CEnumConnectionPoints : public IEnumConnectionPoints
  14. {
  15. public:
  16. // IUnknown
  17. ULONG __stdcall AddRef();
  18. ULONG __stdcall Release();
  19. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  20. // IEnumConnectionPoints
  21. HRESULT __stdcall Next(ULONG cConnections, IConnectionPoint** rgpcn, ULONG* pcFetched); 
  22. HRESULT __stdcall Skip(ULONG cConnections);
  23. HRESULT __stdcall Reset();
  24. HRESULT __stdcall Clone(IEnumConnectionPoints** ppEnum);
  25. CEnumConnectionPoints(IUnknown* pUnkRef, void** rgpCP);
  26. ~CEnumConnectionPoints();
  27. private:
  28. long m_cRef;
  29.     IUnknown* m_pUnkRef;         // IUnknown for ref counting
  30.     int m_iCur;                  // Current element
  31.     IConnectionPoint* m_rgpCP[NUM_CONNECTION_POINTS];  // Array of connection points
  32. };
  33. // void** rpgCP is used so that this constructor can accept either CConnectionPoint**
  34. // from CInsideCOM::EnumConnectionPoints or IConnectionPoint** from CEnumConnectionPoints::Clone
  35. // This could also be done by overloading the constructor and duplicating some of this code
  36. CEnumConnectionPoints::CEnumConnectionPoints(IUnknown* pUnkRef, void** rgpCP) : m_cRef(0)
  37. {
  38. g_cComponents++;
  39. m_iCur = 0;
  40.     m_pUnkRef = pUnkRef;
  41. // m_rgpCP is a pointer to an array of IConnectionPoints or CConnectionPoints
  42. for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
  43. ((IUnknown*)rgpCP[count])->QueryInterface(IID_IConnectionPoint, (void**)&m_rgpCP[count]);
  44. }
  45. CEnumConnectionPoints::~CEnumConnectionPoints()
  46. {
  47. g_cComponents--;
  48. if(m_rgpCP != NULL)
  49. for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
  50. m_rgpCP[count]->Release();
  51. }
  52. ULONG CEnumConnectionPoints::AddRef()
  53. {
  54. m_pUnkRef->AddRef();
  55. return ++m_cRef;
  56. }
  57. ULONG CEnumConnectionPoints::Release()
  58. {
  59. m_pUnkRef->Release();
  60. if(--m_cRef != 0)
  61.         return m_cRef;
  62.     delete this;
  63.     return 0;
  64. }
  65. HRESULT CEnumConnectionPoints::QueryInterface(REFIID riid, void** ppv)
  66. {
  67. if(riid == IID_IUnknown || riid == IID_IEnumConnectionPoints)
  68. *ppv = (IEnumConnectionPoints*)this;
  69. else 
  70. {
  71. *ppv = NULL;
  72. return E_NOINTERFACE;
  73. }
  74. AddRef();
  75. return S_OK;
  76. }
  77. HRESULT CEnumConnectionPoints::Next(ULONG cConnections, IConnectionPoint** rgpcn, ULONG* pcFetched)
  78. {
  79. if(rgpcn == NULL)
  80. return E_POINTER;
  81. if(pcFetched == NULL && cConnections != 1)
  82. return E_INVALIDARG;
  83. if(pcFetched != NULL)
  84. *pcFetched = 0;
  85. while(m_iCur < NUM_CONNECTION_POINTS && cConnections > 0)
  86. {
  87. *rgpcn = m_rgpCP[m_iCur++];
  88. if(*rgpcn != NULL)
  89. (*rgpcn)->AddRef();
  90. if(pcFetched != NULL)
  91. (*pcFetched)++;
  92. cConnections--;
  93. rgpcn++;
  94. }
  95. return S_OK;
  96. }
  97. HRESULT CEnumConnectionPoints::Skip(ULONG cConnections)
  98. {
  99. if(m_iCur + cConnections >= NUM_CONNECTION_POINTS)
  100. return S_FALSE;
  101.     m_iCur += cConnections;
  102.     return S_OK;
  103. }
  104. HRESULT CEnumConnectionPoints::Reset()
  105. {
  106.     m_iCur = 0;
  107.     return S_OK;
  108. }
  109. HRESULT CEnumConnectionPoints::Clone(IEnumConnectionPoints** ppEnum)
  110. {
  111. if(ppEnum == NULL)
  112. return E_POINTER;
  113. *ppEnum = NULL;
  114.     // Create the clone
  115.     CEnumConnectionPoints* pNew = new CEnumConnectionPoints(m_pUnkRef, (void**)m_rgpCP);
  116.     if(pNew == NULL)
  117.         return E_OUTOFMEMORY;
  118.     pNew->AddRef();
  119.     pNew->m_iCur = m_iCur;
  120.     *ppEnum = pNew;
  121.     return S_OK;
  122. }
  123. class CConnectionPoint;
  124. class CInsideCOM : public ISum, public IConnectionPointContainer, public IProvideClassInfo2
  125. {
  126. public:
  127. // IUnknown
  128. ULONG __stdcall AddRef();
  129. ULONG __stdcall Release();
  130. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  131. // IConnectionPointContainer
  132. HRESULT __stdcall EnumConnectionPoints(IEnumConnectionPoints** ppEnum);
  133. HRESULT __stdcall FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP);
  134. // IProvideClassInfo2
  135. HRESULT __stdcall GetClassInfo(ITypeInfo** pTypeInfo);
  136. HRESULT __stdcall GetGUID(DWORD dwGuidKind, GUID* pGUID);
  137. // ISum
  138. HRESULT __stdcall Sum(int x, int y, int* retval);
  139. CInsideCOM();
  140. ~CInsideCOM();
  141. private:
  142. long m_cRef;
  143. CConnectionPoint* m_rgpConnPt[NUM_CONNECTION_POINTS];
  144. };
  145. class CConnectionPoint : public IConnectionPoint
  146. {
  147. public:
  148. // IUnknown
  149. ULONG __stdcall AddRef();
  150. ULONG __stdcall Release();
  151. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  152. // IConnectionPoint
  153. HRESULT __stdcall GetConnectionInterface(IID *pIID);
  154. HRESULT __stdcall GetConnectionPointContainer(IConnectionPointContainer** ppCPC);
  155. HRESULT __stdcall Advise(IUnknown* pUnknownSink, DWORD* pdwCookie);
  156. HRESULT __stdcall Unadvise(DWORD dwCookie);
  157. HRESULT __stdcall EnumConnections(IEnumConnections** ppEnum);
  158. CConnectionPoint(CInsideCOM* pObj, REFIID refiid);
  159. ~CConnectionPoint();
  160. private:
  161. int m_cRef;
  162. CInsideCOM* m_pObj;
  163. IID m_iid;
  164.     int m_cConn;
  165.     int m_nCookieNext;
  166. unsigned m_rgnCookies[CCONNMAX];
  167. IUnknown* m_rgpUnknown[CCONNMAX];
  168. };
  169. class CEnumConnections : public IEnumConnections
  170. {
  171. public:
  172. // IUnknown
  173. ULONG __stdcall AddRef();
  174. ULONG __stdcall Release();
  175. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  176. // IEnumConnections
  177. HRESULT __stdcall Next(ULONG cConnections, CONNECTDATA* rgpcd, ULONG* pcFetched);
  178. HRESULT __stdcall Skip(ULONG cConnections);
  179. HRESULT __stdcall Reset();
  180. HRESULT __stdcall Clone(IEnumConnections** ppEnum);
  181. CEnumConnections(IUnknown* pUnknown, int cConn, CONNECTDATA* pConnData);
  182. ~CEnumConnections();
  183. private:
  184. int m_cRef;
  185.     IUnknown* m_pUnkRef;       // IUnknown for ref counting
  186.     unsigned m_iCur;           // Current element
  187.     unsigned m_cConn;          // Number of connections
  188.     CONNECTDATA* m_rgConnData; // Source of connections
  189. };
  190. CInsideCOM::CInsideCOM() : m_cRef(0)
  191. {
  192. g_cComponents++;
  193.     m_cRef = 0;
  194.     // Initialize all the connection points to NULL
  195. for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
  196.         m_rgpConnPt[count] = NULL;
  197. // Create our connection point
  198. m_rgpConnPt[0] = new CConnectionPoint(this, IID_IOutGoing);
  199. m_rgpConnPt[0]->AddRef();
  200. // Additional connection points could be instantiated here
  201. }
  202. CInsideCOM::~CInsideCOM()
  203. {
  204. g_cComponents--;
  205.     for(int count = 0; count < NUM_CONNECTION_POINTS; count++)
  206.         if(m_rgpConnPt[count] != NULL)
  207.         delete m_rgpConnPt[count];
  208. }
  209. CEnumConnections::CEnumConnections(IUnknown* pUnknown, int cConn, CONNECTDATA* pConnData) : m_cRef(0)
  210. {
  211. g_cComponents++;
  212. m_pUnkRef = pUnknown;
  213. m_iCur = 0;
  214. m_cConn = 0;
  215. m_rgConnData = new CONNECTDATA[cConn];
  216. if(m_rgConnData != NULL)
  217. for(int count = 0; count < cConn; count++)
  218. {
  219. m_rgConnData[count] = pConnData[count];
  220. m_rgConnData[count].pUnk->AddRef();
  221. }
  222. }
  223. CEnumConnections::~CEnumConnections()
  224. {
  225. g_cComponents--;
  226. if(m_rgConnData != NULL)
  227. {
  228. for(unsigned count = 0; count < m_cConn; count++)
  229. m_rgConnData[count].pUnk->Release();
  230. delete [] m_rgConnData;
  231. }
  232. }
  233. HRESULT CEnumConnections::Next(ULONG cConnections, CONNECTDATA* rgpcd, ULONG* pcFetched)
  234. {
  235. if(pcFetched == NULL && cConnections != 1)
  236. return E_INVALIDARG;
  237. if(pcFetched != NULL)
  238. *pcFetched = 0;
  239.     if(rgpcd == NULL || m_iCur >= m_cConn)
  240.         return S_FALSE;
  241.     unsigned cReturn = 0;
  242.     while(m_iCur < m_cConn && cConnections > 0)
  243.     {
  244.         *rgpcd++ = m_rgConnData[m_iCur];
  245.         m_rgConnData[m_iCur++].pUnk->AddRef();
  246.         cReturn++;
  247.         cConnections--;
  248.     } 
  249.     if(pcFetched != NULL)
  250.         *pcFetched = cReturn;
  251.     return S_OK;
  252. }
  253. HRESULT CEnumConnections::Skip(ULONG cConnections)
  254. {
  255.     if(m_iCur + cConnections >= m_cConn)
  256.         return S_FALSE;
  257.     m_iCur += cConnections;
  258.     return S_OK;
  259. }
  260. HRESULT CEnumConnections::Reset()
  261. {
  262.     m_iCur = 0;
  263.     return S_OK;
  264. }
  265. HRESULT CEnumConnections::Clone(IEnumConnections** ppEnum)
  266. {
  267. if(ppEnum == NULL)
  268. return E_POINTER;
  269. *ppEnum = NULL;
  270.     // Create the clone
  271.     CEnumConnections* pNew = new CEnumConnections(m_pUnkRef, m_cConn, m_rgConnData);
  272.     if(NULL == pNew)
  273.         return E_OUTOFMEMORY;
  274.     pNew->AddRef();
  275.     pNew->m_iCur = m_iCur;
  276.     *ppEnum = pNew;
  277.     return S_OK;
  278. }
  279. HRESULT CEnumConnections::QueryInterface(REFIID riid, void** ppv)
  280. {
  281.     if(IID_IUnknown == riid || IID_IEnumConnections == riid)
  282.         *ppv = (IEnumConnections*)this;
  283.     else
  284. {
  285. *ppv = NULL;
  286. return E_NOINTERFACE;
  287. }
  288. AddRef();
  289. return S_OK;
  290. }
  291. ULONG CEnumConnections::AddRef()
  292.     {
  293.     return ++m_cRef;
  294.     }
  295. ULONG CEnumConnections::Release()
  296.     {
  297.     if(--m_cRef != 0)
  298.         return m_cRef;
  299.     delete this;
  300.     return 0;
  301.     }
  302. CConnectionPoint::CConnectionPoint(CInsideCOM* pObj, REFIID riid) : m_cRef(0)
  303. {
  304. g_cComponents++;
  305.     m_iid = riid;
  306. // Don't need AddRef/Release since we are nested inside CInsideCOM
  307.     m_pObj = pObj;
  308.     for(int count = 0; count < CCONNMAX; count++)
  309.         {
  310.         m_rgpUnknown[count] = NULL;
  311.         m_rgnCookies[count] = 0;
  312.         }
  313.     m_cConn = 0;
  314.     m_nCookieNext = 10; // Arbitrary starting cookie value
  315. }
  316. CConnectionPoint::~CConnectionPoint()
  317. {
  318. g_cComponents--;
  319.     for(int count = 0; count < CCONNMAX; count++)
  320. if(m_rgpUnknown[count] != NULL)
  321. {
  322.         m_rgpUnknown[count]->Release();
  323. m_rgpUnknown[count] = NULL;
  324. }
  325. }
  326. HRESULT CConnectionPoint::QueryInterface(REFIID riid, void** ppv)
  327. {
  328.     if(IID_IUnknown == riid || IID_IConnectionPoint == riid)
  329.         *ppv = (IConnectionPoint*)this;
  330.     else
  331. {
  332. *ppv = NULL;
  333. return E_NOINTERFACE;
  334. }
  335. AddRef();
  336. return S_OK;
  337. }
  338. ULONG CConnectionPoint::AddRef()
  339.     {
  340.     return ++m_cRef;
  341.     }
  342. ULONG CConnectionPoint::Release()
  343.     {
  344.     if(--m_cRef != 0)
  345.         return m_cRef;
  346.     delete this;
  347.     return 0;
  348.     }
  349. HRESULT CConnectionPoint::GetConnectionInterface(IID *pIID)
  350. {
  351. if(pIID == NULL)
  352. return E_POINTER;
  353. *pIID = m_iid;
  354. return S_OK;
  355. }
  356. HRESULT CConnectionPoint::GetConnectionPointContainer(IConnectionPointContainer** ppCPC)
  357. {
  358. return m_pObj->QueryInterface(IID_IConnectionPointContainer, (void**)ppCPC);
  359. }
  360. HRESULT CConnectionPoint::Advise(IUnknown* pUnknownSink, DWORD* pdwCookie)
  361. {
  362. IUnknown* pSink;
  363. *pdwCookie = 0;
  364. if(m_cConn == CCONNMAX)
  365. return CONNECT_E_ADVISELIMIT;
  366. if(FAILED(pUnknownSink->QueryInterface(m_iid, (void**)&pSink)))
  367. return CONNECT_E_CANNOTCONNECT;
  368. for(int count = 0; count < CCONNMAX; count++)
  369. if(m_rgpUnknown[count] == NULL)
  370. {
  371. m_rgpUnknown[count] = pSink;
  372. m_rgnCookies[count] = ++m_nCookieNext;
  373. *pdwCookie = m_nCookieNext;
  374. break;
  375. }
  376. m_cConn++;
  377. // Hack here to copy pointer to a global variable so that we can use it from main()
  378. g_pOutGoing = (IOutGoing*)pSink;
  379. return NOERROR;
  380. }
  381. HRESULT CConnectionPoint::Unadvise(DWORD dwCookie)
  382. {
  383. if(dwCookie == 0)
  384. return E_INVALIDARG;
  385. for(int count = 0; count < CCONNMAX; count++)
  386. if(dwCookie == m_rgnCookies[count])
  387. {
  388. if(m_rgpUnknown[count] != NULL)
  389. {
  390. m_rgpUnknown[count]->Release();
  391. m_rgpUnknown[count] = NULL;
  392. }
  393. m_cConn--;
  394. return NOERROR;
  395. }
  396. return CONNECT_E_NOCONNECTION;
  397. }
  398. HRESULT CConnectionPoint::EnumConnections(IEnumConnections** ppEnum)
  399. {
  400. *ppEnum = NULL;
  401. CONNECTDATA* pCD = new CONNECTDATA[m_cConn];
  402. for(int count1 = 0, count2 = 0; count1 < CCONNMAX; count1++)
  403. if(m_rgpUnknown[count1] != NULL)
  404. {
  405. pCD[count2].pUnk = (IUnknown*)m_rgpUnknown[count1];
  406. pCD[count2].dwCookie = m_rgnCookies[count1];
  407. count2++;
  408. }
  409. CEnumConnections* pEnum = new CEnumConnections(this, m_cConn, pCD);
  410. delete [] pCD;
  411. return pEnum->QueryInterface(IID_IEnumConnections, (void**)ppEnum);
  412. }
  413. HRESULT CInsideCOM::EnumConnectionPoints(IEnumConnectionPoints** ppEnum)
  414. {
  415. cout << "Component: CInsideCOM::EnumConnectionPoints()" << endl;
  416. CEnumConnectionPoints* pEnum = new CEnumConnectionPoints(reinterpret_cast<IUnknown*>(this), (void**)m_rgpConnPt);
  417. return pEnum->QueryInterface(IID_IEnumConnectionPoints, (void**)ppEnum);
  418. }
  419. HRESULT CInsideCOM::FindConnectionPoint(REFIID riid, IConnectionPoint** ppCP)
  420. {
  421. if(riid == IID_IOutGoing)
  422. {
  423. cout << "Component: CInsideCOM::FindConnectionPoint() for IID_IOutGoing" << endl;
  424. return m_rgpConnPt[0]->QueryInterface(IID_IConnectionPoint, (void**)ppCP);
  425. }
  426. return E_NOINTERFACE;
  427. }
  428. HRESULT CInsideCOM::GetClassInfo(ITypeInfo** pTypeInfo)
  429. {
  430. ITypeLib* pTypeLib;
  431. LoadRegTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, &pTypeLib);
  432. HRESULT hr = pTypeLib->GetTypeInfoOfGuid(CLSID_InsideCOM, pTypeInfo);
  433. pTypeLib->Release();
  434. return hr;
  435. }
  436. HRESULT CInsideCOM::GetGUID(DWORD dwGuidKind, GUID* pGUID)
  437. {
  438. if(pGUID == NULL)
  439. return E_INVALIDARG;
  440. *pGUID = IID_IOutGoing;
  441. return S_OK;
  442. }
  443. ULONG CInsideCOM::AddRef()
  444. {
  445. return ++m_cRef;
  446. }
  447. ULONG CInsideCOM::Release()
  448. {
  449.     if(--m_cRef != 0)
  450.         return m_cRef;
  451. SetEvent(g_hEvent);
  452.     delete this;
  453.     return 0;
  454. }
  455. HRESULT CInsideCOM::QueryInterface(REFIID riid, void** ppv)
  456. {
  457. if(riid == IID_IUnknown)
  458. *ppv = reinterpret_cast<IUnknown*>(this);
  459. else if(riid == IID_ISum)
  460. {
  461. cout << "Component: CInsideCOM::QueryInterface() for ISum returning " << this << endl;
  462. *ppv = (ISum*)this;
  463. }
  464. else if(riid == IID_IConnectionPointContainer)
  465. {
  466. cout << "Component: CInsideCOM::QueryInterface() for IConnectionPointContainer" << endl;
  467. *ppv = (IConnectionPointContainer*)this;
  468. }
  469. else if(riid == IID_IProvideClassInfo)
  470. {
  471. MessageBox(NULL, "QueryInterface", "IProvideClassInfo", MB_OK);
  472. *ppv = NULL;
  473. return E_NOINTERFACE;
  474. }
  475. else 
  476. {
  477. *ppv = NULL;
  478. return E_NOINTERFACE;
  479. }
  480. AddRef();
  481. return S_OK;
  482. }
  483. HRESULT CInsideCOM::Sum(int x, int y, int* retval)
  484. {
  485. cout << "Component: CInsideCOM::Sum() " << x << " + " << y << " = " << x + y << endl;
  486. *retval = x + y;
  487. return S_OK;
  488. }
  489. class CFactory : public IClassFactory
  490. {
  491. public:
  492. // IUnknown
  493. ULONG __stdcall AddRef();
  494. ULONG __stdcall Release();
  495. HRESULT __stdcall QueryInterface(REFIID iid, void** ppv);
  496. // IClassFactory
  497. HRESULT __stdcall CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv);
  498. HRESULT __stdcall LockServer(BOOL bLock);
  499. CFactory() : m_cRef(0) { g_cComponents++; }
  500. ~CFactory() { g_cComponents--; }
  501. private:
  502. long m_cRef;
  503. };
  504. ULONG CFactory::AddRef()
  505. {
  506. return ++m_cRef;
  507. }
  508. ULONG CFactory::Release()
  509. {
  510.     if(--m_cRef != 0)
  511.         return m_cRef;
  512.     delete this;
  513.     return 0;
  514. }
  515. HRESULT CFactory::QueryInterface(REFIID iid, void** ppv)
  516. {
  517. if((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  518. *ppv = (IClassFactory *)this;
  519. else
  520. {
  521. *ppv = NULL;
  522. return E_NOINTERFACE;
  523. }
  524. AddRef();
  525. return S_OK;
  526. }
  527. HRESULT CFactory::CreateInstance(IUnknown *pUnknownOuter, REFIID iid, void** ppv)
  528. {
  529. if(pUnknownOuter != NULL)
  530. return CLASS_E_NOAGGREGATION;
  531. CInsideCOM *pInsideCOM = new CInsideCOM;
  532. cout << "Component: CFactory::CreateInstance() " << pInsideCOM << endl;
  533. if(pInsideCOM == NULL)
  534. return E_OUTOFMEMORY;
  535. // QueryInterface probably for IID_IUNKNOWN
  536. return pInsideCOM->QueryInterface(iid, ppv);
  537. }
  538. HRESULT CFactory::LockServer(BOOL bLock)
  539. {
  540. if(bLock)
  541. g_cServerLocks++;
  542. else
  543. g_cServerLocks--;
  544. return S_OK;
  545. }
  546. void RegisterComponent()
  547. {
  548. ITypeLib* pTypeLib;
  549. LoadTypeLibEx(L"component.exe", REGKIND_DEFAULT, &pTypeLib);
  550. RegisterServer("component.exe", CLSID_InsideCOM, "Inside COM Sample #1", "Component.InsideCOM", "Component.InsideCOM.1", NULL);
  551. }
  552. void CommandLineParameters(int argc, char** argv)
  553. {
  554. RegisterComponent();
  555. if(argc < 2)
  556. {
  557. cout << "No parameter, but registered anyway..." << endl;
  558. exit(false);
  559. }
  560. char* szToken = strtok(argv[1], "-/"); 
  561. if(_stricmp(szToken, "RegServer") == 0)
  562. {
  563. RegisterComponent();
  564. cout << "RegServer" << endl;
  565. exit(true);
  566. }
  567. if(_stricmp(szToken, "UnregServer") == 0)
  568. {
  569. UnRegisterTypeLib(LIBID_Component, 1, 0, LANG_NEUTRAL, SYS_WIN32);
  570. UnregisterServer(CLSID_InsideCOM, "Component.InsideCOM", "Component.InsideCOM.1");
  571. cout << "UnregServer" << endl;
  572. exit(true);
  573. }
  574. if(_stricmp(szToken, "Embedding") != 0)
  575. {
  576. cout << "Invalid parameter" << endl;
  577. exit(false);
  578. }
  579. }
  580. void main(int argc, char** argv)
  581. {
  582. CommandLineParameters(argc, argv);
  583. g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  584. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  585. DWORD dwRegister;
  586. IClassFactory *pCFactory = new CFactory();
  587. CoRegisterClassObject(CLSID_InsideCOM, pCFactory, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegister);
  588. cout << "Press any key to fire an event at the client" << endl;
  589. HANDLE handles[2] = { g_hEvent, GetStdHandle(STD_INPUT_HANDLE) };
  590. while(WaitForMultipleObjects(2, handles, FALSE, INFINITE) - WAIT_OBJECT_0 == 1)
  591. {
  592. INPUT_RECORD ir;
  593. DWORD read;
  594. ReadConsoleInput(handles[1], &ir, 1, &read);
  595. if(ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown == TRUE)
  596. g_pOutGoing->GotMessage(ir.Event.KeyEvent.uChar.AsciiChar);
  597. }
  598. CoRevokeClassObject(dwRegister);
  599. CoUninitialize();
  600. }