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

📄 inner.cpp

📁 《DCOM入门》随书源码 Chapter 1 (Distributed Computing) N/A Chapter 2 (DCOM Overview) N/A Chapter 3 (Objec
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//*******************************************************************
//*******************************************************************
//***  Implementation of the CoOcrEngine component object
//***  that supports aggregation
//*******************************************************************
//*******************************************************************

//-------------------------------------------------------------------
// Required macros
//-------------------------------------------------------------------
#define UNICODE         // UNICODE
#define _WIN32_DCOM     // DCOM

//-------------------------------------------------------------------
// includes
//-------------------------------------------------------------------
#include <assert.h>
#include <stdio.h>
#include <windows.h>
#include <initguid.h>
#include "..\..\idl\ocr.h"

//-------------------------------------------------------------------
// global event telling use wen to shutdown our application
//-------------------------------------------------------------------
HANDLE g_hExitEvent;
wchar_t g_wszModuleName[MAX_PATH];

// Number of living objects
LONG g_lComponentRefCounts = 0; // counts living objects and locks

//-------------------------------------------------------------------
// Component Level Reference count for the lifetime managment of 
// the whole component.
// These specific implementations are used for in-process servers
// There are a pair of functions like these that are used for
// out-of-process servers.
// Return values for debugging purpose only 
//-------------------------------------------------------------------
inline ULONG ComponentAddRef()
{
   return (InterlockedIncrement(&g_lComponentRefCounts));
}

inline ULONG ComponentRelease()  
{
   return (InterlockedDecrement(&g_lComponentRefCounts));
}

//*******************************************************************
//*******************************************************************
//***  UTILITY FUNCTIONS
//*******************************************************************
//*******************************************************************
void DisplayStatus(wchar_t *pwszMsg, HRESULT hr)
{

   if (hr == S_OK) {
      wprintf(TEXT("%s\n"), pwszMsg);
      return;
   }

   if (HRESULT_FACILITY(hr) == FACILITY_WINDOWS) {
      hr = HRESULT_CODE(hr);
   }

   wchar_t *pwszStatus;
   FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
       FORMAT_MESSAGE_FROM_SYSTEM,
       NULL,
       hr,
       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
       (LPWSTR)&pwszStatus,
       0,
       NULL );

   wprintf(TEXT("%s: %s (ECode: %lx)\n"), pwszMsg, pwszStatus, hr);

   LocalFree(pwszStatus);
}

//-------------------------------------------------------------------
// Given a unicode string, get the number of bytes needed to host it
//-------------------------------------------------------------------
inline long ByteLen(wchar_t *pwsz) 
{
   return (sizeof(wchar_t)*(wcslen(pwsz)+1));
}

//-------------------------------------------------------------------
// Automatic registration; for in-process server, do:
//    regsvr32.exe xxx.dll
//-------------------------------------------------------------------
void RegisterServerToSystem()
{
   wchar_t wszKey[MAX_PATH];
   wchar_t wszValue[MAX_PATH];
   HKEY hKey = 0;

   // CLSID_OcrEngine = {DF22A6B2-A58A-11d1-ABCC-00207810D5FE}
   // HKEY_CLASSES_ROOT\CLSID\{DF22A6B2-A58A-11d1-ABCC-00207810D5FE}
   //      @="OcrEngine"
   wcscpy(wszKey, TEXT("CLSID\\{DF22A6B2-A58A-11d1-ABCC-00207810D5FE}"));
   RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
   wcscpy(wszValue, TEXT("OcrEngine"));
   RegSetValueEx(hKey, 0, 0, REG_SZ, (BYTE*)wszValue, ByteLen(wszValue));
   RegCloseKey(hKey);

   // HKEY_CLASSES_ROOT\CLSID\{DF22A6B2-A58A-11d1-ABCC-00207810D5FE}\InprocServer32
   //      @="E:\DCOM\CODE\Essentials\inproc\DEBUG\inproc.dll"
   //      "ThreadingModel" = "Both"
   wcscpy(wszKey, TEXT("CLSID\\{DF22A6B2-A58A-11d1-ABCC-00207810D5FE}")
        TEXT("\\InprocServer32"));
   RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
   wcscpy(wszValue, g_wszModuleName);
   RegSetValueEx(hKey, 0, 0, REG_SZ, (BYTE*)wszValue, ByteLen(wszValue));
   wcscpy(wszValue, TEXT("Both"));
   RegSetValueEx(hKey, TEXT("ThreadingModel"), 0, REG_SZ, 
                 (BYTE*)wszValue, ByteLen(wszValue));
   RegCloseKey(hKey);
}

//-------------------------------------------------------------------
// Automatic registration; for in-process server, do:
//    regsvr32.exe -u xxx.dll
//-------------------------------------------------------------------
void UnregisterServerFromSystem()
{
   long lRc = 0 ;

   lRc=RegDeleteKey(HKEY_CLASSES_ROOT, 
       TEXT("CLSID\\{DF22A6B2-A58A-11d1-ABCC-00207810D5FE}") 
     TEXT("\\InprocServer32"));
   DisplayStatus(TEXT("Unregistered CLSID's InprocServer"), lRc);

   lRc=RegDeleteKey(HKEY_CLASSES_ROOT, 
       TEXT("CLSID\\{DF22A6B2-A58A-11d1-ABCC-00207810D5FE}"));
   DisplayStatus(TEXT("Unregistered CLSID"), lRc);
}
 

//*******************************************************************
//*******************************************************************
//***  Implitcit unknown
//*******************************************************************
//*******************************************************************
template<class T> class CImplicitUnknown : public IUnknown {
public:
    // m_pbkptr points to the object implementing the
   // non-delegating IUnknown methods.
   void Bkptr(T *p) { m_pbkptr=p; }

    STDMETHODIMP QueryInterface(REFIID iid, void **ppv)
    { return m_pbkptr->InternalQueryInterface(iid, ppv); }
    STDMETHODIMP_(ULONG) AddRef(void)
    { return m_pbkptr->InternalAddRef(); }
    STDMETHODIMP_(ULONG) Release(void)
    { return m_pbkptr->InternalAddRef(); }
    
private:
    T *m_pbkptr;
};

//*******************************************************************
//*******************************************************************
//***  Class CoOcrEngine - A component object that implements two
//***  interfaces:  IOcr and ISpell
//***  This implementation that supports AGGREGATION.
//***  Containment works with every component object.
//***  Aggregation doesn't work across aparments, including 
//***  processes and machines.  This means that the object
//***  that wants to aggregate this object must run in the same
//***  apartment as this object.  This implies that no marshaling
//***  will be involved, and both the aggregator and the aggregatee
//***  (this object) will run in the same appartment, since we're
//***  in the same process, this also implies the same thread.
//*******************************************************************
//*******************************************************************
class CoOcrEngine : public IOcr, public ISpell {
public:
   //----------------------------------
   // Modified for aggregation support
   //----------------------------------
   CoOcrEngine(IUnknown *pOuterUnk) 
        : m_lRefCount(0), m_pOuterUnk(pOuterUnk), m_InnerUnk()
   { 
      ComponentAddRef(); 

      m_InnerUnk.Bkptr(this);
      if (pOuterUnk==NULL) { 
         // we're not aggregating; therefore, 
         // we've got no outer object
         // the outer object is ourselves
         m_pOuterUnk = &m_InnerUnk;
         DisplayStatus(TEXT("AGGRVersion: not being aggregated"), S_OK);
      } else {
         DisplayStatus(TEXT("AGGRVersion: being aggregated"), S_OK);
      }
   }

   ~CoOcrEngine()
   { ComponentRelease(); }

   //----------------------------------
   // Modified for aggregation support
   //----------------------------------
   static HRESULT CreateObject(LPUNKNOWN pOuterUnk, 
                             REFIID riid, void **ppv);

public: 
   //----------------------------------
   // Modified for aggregation support
   //----------------------------------
   // IUnknown Methods - possibly delegating to an out aggregator
   // these a method for this object's IUnknown's vtbl,
   // but the functionality depends on the m_pOuterUnk pointer.
   STDMETHODIMP QueryInterface(REFIID iid, void **ppv) 
   { return m_pOuterUnk->QueryInterface(iid, ppv); }
   STDMETHODIMP_(ULONG) AddRef(void)
   { return m_pOuterUnk->AddRef(); }
   STDMETHODIMP_(ULONG) Release(void)
   { return m_pOuterUnk->Release(); }

   // IOcr Methods
   STDMETHODIMP OcrImage(long lImageSize, 
                         byte *pbImage,                          
                         wchar_t **pwszOcrText);
   STDMETHODIMP OcrZone(long lImageSize, 
                        byte *pbImage,
                        Zone zone,
                        wchar_t **pwszOcrText);

   // ISpell Methods
   STDMETHODIMP Check(wchar_t *pwszWord,
                      PossibleWords *pWords);

private:
   //----------------------------------
   // Aggregation support
   //----------------------------------
   // non-delegating/inner/implicit unknown 
   // these are non-virtual private functions
   HRESULT InternalQueryInterface(REFIID iid, void **ppv);
   ULONG InternalAddRef(void)
   {
      wchar_t wszMsg[MAX_PATH];
      wsprintf(wszMsg, TEXT("CoOcrEngine::InternalAddRef (%ld)"), m_lRefCount); 
      return InterlockedIncrement(&m_lRefCount);
   }

   ULONG InternalRelease(void)
   {
      wchar_t wszMsg[MAX_PATH];
      wsprintf(wszMsg, TEXT("CoOcrEngine::InternalRelease (%ld)"), m_lRefCount-1); 
      long lCount = InterlockedDecrement(&m_lRefCount);
      if (lCount == 0) { delete this; } 
      return lCount; 
   }

private:
   LONG m_lRefCount;

   //----------------------------------
   // Aggregation support
   //----------------------------------
   IUnknown *m_pOuterUnk;
   friend CImplicitUnknown<CoOcrEngine>;
   CImplicitUnknown<CoOcrEngine> m_InnerUnk;
};

//-------------------------------------------------------------------
// CoOcrEngine::CreateObject - static function to create an
// CoOcrEngine object
//-------------------------------------------------------------------
HRESULT CoOcrEngine::CreateObject(LPUNKNOWN pOuterUnk, 
                                  REFIID riid, 
                                  void** ppv)
{
   // debug message to check this thread id 
   // and the client's thread id, uncomment to see the effect
   // Aggregation work only when the thread ids are equal

⌨️ 快捷键说明

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