⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aggregate.cpp

📁 《DCOM入门》随书源码 Chapter 1 (Distributed Computing) N/A Chapter 2 (DCOM Overview) N/A Chapter 3 (Objec
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   // support aggregation...
   // the unknown of the object we're aggregating
   // must be IUnknown for aggregation...
   IUnknown *m_pUnkAggregate;  
};

//-------------------------------------------------------------------
// Creating the inner object for reuse...
// CoMyEngine::CreateInnerObject
//-------------------------------------------------------------------
void CoThesaurus::CreateInnerObject()
{
   // support aggregation...
   // The aggregation law of COM require us to create
   // the inner object, and requesting only for IUnknown
   // and nothing else!!!
   MULTI_QI mqi[] = { {&IID_IUnknown, NULL, S_OK} };

   // Notice "this" as the second argument... 
   // reuse by aggregation!!!
   // Outer unknown is this object--uses the inner object.
   // This argument is the magic that get's our 
   // object (CLSID_Thesaurus) to reuse the 
   // inner object (CLSID_OcrEngine)

   // Special support here in case the inner object
   // code happened to cause a delete of this object.
   // Remember at this moment, the reference count
   // that we are keeping for this object is 0, since
   // we're still in the constructor.
   // Here's a potential probelm:  The inner object
   // QIs for one of our (this object's) interfaces
   // (refcount=1) and releases it (refcount=0),
   // causing a premature delete of this object.
   // To prevent this, we temporarily increment and decrement our
   // reference count.  However, don't call Release, since
   // it deletes our object.  You'd have to use this technique:
   InterlockedIncrement(&m_lRefCount);
   HRESULT hr = CoCreateInstanceEx(CLSID_OcrEngine, 
        this, 
        CLSCTX_SERVER, 
        NULL,
        sizeof(mqi)/sizeof(mqi[0]), 
        mqi);
   InterlockedDecrement(&m_lRefCount);

   if (SUCCEEDED(hr) && SUCCEEDED(mqi[0].hr)) {
      m_pUnkAggregate = reinterpret_cast<IUnknown *>(mqi[0].pItf);
   } else {
      DisplayStatus(TEXT("Failed to create inner object..."), S_OK);
      wprintf(TEXT("You need to use the Aggregatable")
                TEXT("Version of CLSID_OcrEngine\n")
                TEXT("It lives in code\\basics\\reuse\\inner\n")
                TEXT("Version of CLSID_OcrEngine\n"));
      assert(false);
   }
}
 

//-------------------------------------------------------------------
// CoThesaurus::CreateObject - static function to create an
// CoThesaurus object
//-------------------------------------------------------------------
HRESULT CoThesaurus::CreateObject(LPUNKNOWN pUnkOuter, 
                                  REFIID riid, 
                                  void** ppv)
{
   *ppv = NULL;

   // CoThesaurus doesn't support aggregation
   if (pUnkOuter != NULL) { return CLASS_E_NOAGGREGATION; }

   CoThesaurus * pThesaurus = new CoThesaurus;
   if (pThesaurus == NULL) { return E_OUTOFMEMORY; }

   HRESULT hr = pThesaurus->QueryInterface(riid, ppv);
   if (FAILED(hr)) { delete pThesaurus; }

   return hr;
}

//-------------------------------------------------------------------
// CoThesaurus::QueryInterface
//-------------------------------------------------------------------
STDMETHODIMP
CoThesaurus::QueryInterface(REFIID riid, void** ppv)
{
   if (ppv==NULL) { return E_INVALIDARG; }

   if (riid==IID_IUnknown) {
      *ppv= static_cast<IThesaurus *>(this);
   } else if (riid==IID_IThesaurus) {
      *ppv= static_cast<IThesaurus *>(this);
   }  else if (riid==IID_IOcr||riid==IID_ISpell) {
      // Support Aggregation...
      // interfaces belong to the reused object
      // let the inner object handle this request!
      return m_pUnkAggregate->QueryInterface(riid, ppv) ;
   } else {
      *ppv=NULL; return E_NOINTERFACE ;
   }

   reinterpret_cast<IUnknown *>(*ppv)->AddRef();

   return S_OK;
}

//*******************************************************************
//*******************************************************************
//***  Class Factory: manufacturing CoThesaurus objects
//*******************************************************************
//*******************************************************************
class CoThesaurusFactory : public IClassFactory 
{
public:
   // IUnknown Methods
   STDMETHODIMP QueryInterface (REFIID riid, void** ppv);
   STDMETHODIMP_(ULONG) AddRef(void)
   { return 1; }
   STDMETHODIMP_(ULONG) Release(void) 
   { return 1; }

   // IClassFactory Methods
   STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, 
                               REFIID riid, 
                               void **ppv)
  {
     // call CoThesaurus's static function to create
     // a CoThesaurus component object
     return CoThesaurus::CreateObject(pUnkOuter, riid, ppv);
  }

   STDMETHODIMP LockServer(BOOL fLock)
   {
      if (fLock) {
         ComponentAddRef();
      } else {
         ComponentRelease();
      }
      return S_OK;        
   }   
};

//-------------------------------------------------------------------
//  Singleton factory instance that manufacture CoCorEngine
//  component objects
//-------------------------------------------------------------------
CoThesaurusFactory g_ThesaurusClassFactory;

//-------------------------------------------------------------------
//  CoThesaurusFactory::QueryInterface
//-------------------------------------------------------------------
STDMETHODIMP 
CoThesaurusFactory::QueryInterface(REFIID riid, void** ppv)
{
   if (ppv==NULL) { return E_INVALIDARG; }

   if (riid==IID_IUnknown) {
      *ppv= static_cast<IClassFactory *>(this);
   } else if (riid==IID_IClassFactory) {
      *ppv= static_cast<IClassFactory *>(this);
   } else {
      *ppv=NULL; return E_NOINTERFACE ;
   }

   reinterpret_cast<IUnknown *>(*ppv)->AddRef();

   return S_OK;
}

//*******************************************************************
//*******************************************************************
//***  Main Program
//*******************************************************************
//*******************************************************************
void main(int argc, char **argv)
{
   DisplayStatus(TEXT("Server: Started"), S_OK);

   g_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
   assert(g_hExitEvent);

   // registration if required
   if (argc > 1) {
      if (_stricmp(argv[1], "-RegServer")==0){
         RegisterComponent();
         DisplayStatus(TEXT("Registered..."), S_OK);
         return ;
      }
      if (_stricmp(argv[1], "-UnRegServer")==0){
         UnregisterComponent();
         DisplayStatus(TEXT("Unregistered..."), S_OK);
         return ;
      }
   }

   // Init COM
   HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
   assert(SUCCEEDED(hr));

   // Register Thesaurus Class Factory with COM
   DWORD dwRegister;
   hr = CoRegisterClassObject(CLSID_Thesaurus, 
                              &g_ThesaurusClassFactory,
                              CLSCTX_SERVER, 
                              REGCLS_MULTIPLEUSE, 
                              &dwRegister);
   assert(SUCCEEDED(hr));
   // we don't have to do this, but it's a good habit
   g_ThesaurusClassFactory.Release();  

   // sit and wait until CoThesaurus object is used
   WaitForSingleObject(g_hExitEvent, INFINITE);

   // revoke the factory from public view
   CoRevokeClassObject(dwRegister);

   // uninitialize
   CoUninitialize();

   DisplayStatus(TEXT("Server shutting down in 5 seconds..."), S_OK);

   Sleep(5000);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -