home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / com / connect / drive / drive.cpp next >
C/C++ Source or Header  |  1998-04-02  |  4KB  |  142 lines

  1. // Drive.cpp : Implementation of WinMain
  2.  
  3. // You will need the NT SUR Beta 2 SDK or VC 4.2 in order to build this 
  4. // project.  This is because you will need MIDL 3.00.15 or higher and new
  5. // headers and libs.  If you have VC 4.2 installed, then everything should
  6. // already be configured correctly.
  7.  
  8. #include "predrive.h"
  9.  
  10. void dump_com_error(_com_error &e)
  11. {
  12.     _tprintf(_T("Oops - hit an error!\n"));
  13.     _tprintf(_T("\a\tCode = %08lx\n"), e.Error());
  14.     _tprintf(_T("\a\tCode meaning = %s\n"), e.ErrorMessage());
  15.     _bstr_t bstrSource(e.Source());
  16.     _bstr_t bstrDescription(e.Description());
  17.     _tprintf(_T("\a\tSource = %s\n"), (LPCTSTR) bstrSource);
  18.     _tprintf(_T("\a\tDescription = %s\n"), (LPCTSTR) bstrDescription);
  19. }
  20.  
  21. class CCriticalSection
  22. {
  23. public:
  24.     void Lock() { EnterCriticalSection(&m_sec); }
  25.     void Unlock() { LeaveCriticalSection(&m_sec); }
  26.     CCriticalSection() { InitializeCriticalSection(&m_sec); } 
  27.     ~CCriticalSection() { DeleteCriticalSection(&m_sec); }
  28.     CRITICAL_SECTION m_sec;
  29. };
  30.  
  31. extern LONG g_cObjCnt;
  32. class CRandomEvent : public IRandomEvent
  33. {
  34. public:
  35.     CRandomEvent() { m_cnt = 0L; }
  36.  
  37.     STDMETHOD(GetTypeInfoCount)(UINT*) { return E_NOTIMPL; }
  38.     STDMETHOD(GetTypeInfo)(UINT, LCID, ITypeInfo**) { return E_NOTIMPL; }
  39.     STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, UINT, LCID, DISPID*) { return E_NOTIMPL; }
  40.     STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) { return E_NOTIMPL; }
  41.     STDMETHOD(QueryInterface)(REFIID iid, LPVOID* ppv)
  42.     { 
  43.         if ((iid == __uuidof(IRandomEvent)) ||
  44.         (iid == __uuidof(IDispatch)) ||
  45.         (iid == __uuidof(IUnknown)))
  46.             *ppv = this;
  47.         else
  48.         {
  49.             *ppv = 0;
  50.             return E_NOINTERFACE;
  51.         }
  52.         AddRef();
  53.         return S_OK;
  54.     }
  55.     STDMETHOD_(ULONG,AddRef)() { return InterlockedIncrement(&m_cnt); }
  56.     STDMETHOD_(ULONG,Release)()
  57.     { 
  58.     InterlockedDecrement(&m_cnt);
  59.     if (m_cnt != 0)
  60.         return m_cnt;
  61.     InterlockedDecrement(&g_cObjCnt);
  62.     delete this;
  63.     return 0;
  64.     }
  65.         
  66. // IRandomEvent
  67.     STDMETHOD(put_Fire)(long l)
  68.     {
  69.         m_cs.Lock();
  70.         // Fake out multiple conection points
  71.         static cnt = 0;
  72.         _tprintf(_T("%d\n"), cnt++);
  73.         m_cs.Unlock();
  74.         return S_OK;
  75.     }
  76.     STDMETHOD(put_ID)(int n) { return S_OK; }
  77.  
  78. private:
  79. // data
  80.     LONG m_cnt;    
  81.     CCriticalSection m_cs;
  82. };
  83.  
  84. /////////////////////////////////////////////////////////////////////////////
  85. //
  86.  
  87. // Force template instantiation outside C-linkage
  88. int Drive()
  89. {
  90.     CoInitializeEx(NULL, COINIT_MULTITHREADED);
  91.     try {
  92.     IRandomPtr pM(__uuidof(CoRandom));
  93.  
  94.     long nID;
  95.     nID = pM->Start;
  96.     DWORD dwTick = GetTickCount();
  97.     while (GetTickCount()-dwTick < 3000)
  98.     {   
  99.         // Fake out CoCreateInstance
  100.         CRandomEvent* pRandomEvent = new CRandomEvent;
  101.         assert(pRandomEvent != NULL);
  102.         InterlockedIncrement(&g_cObjCnt);
  103.         pRandomEvent->AddRef();
  104.  
  105.         DWORD dwAdvise = 0;
  106.         IConnectionPointContainerPtr pCPC;
  107.         IConnectionPointPtr pCP;
  108.         pCPC = pM;
  109.         if (FAILED(pCPC->FindConnectionPoint(__uuidof(IRandomEvent), &pCP)))
  110.             continue;
  111.         if (FAILED(pCP->Advise(pRandomEvent, &dwAdvise)))
  112.             continue;
  113.         puts("Connect");
  114.         Sleep(1);
  115.         if (FAILED(pCP->Unadvise(dwAdvise)))
  116.             continue;
  117.         puts("Disconnect");
  118.         Sleep(1);
  119.         pRandomEvent->Release();
  120.     }
  121.     pM->Stop = nID;
  122.     pM = 0;
  123.     } catch (_com_error& e) {
  124.     dump_com_error(e);
  125.     }
  126.  
  127.     assert(g_cObjCnt == 0L);
  128.     CoUninitialize();
  129.     return 0;
  130. }
  131.  
  132. extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  133.     LPTSTR lpCmdLine, int nShowCmd)
  134. {
  135.     return Drive();
  136. }
  137.  
  138. /////////////////////////////////////////////////////////////////////////////
  139.  
  140.  
  141.  
  142.