📄 aggregate.cpp
字号:
//*******************************************************************
//*******************************************************************
//*** REUSE in COM - Aggregation Demo
//*** This COM server will make use of the inner object via
//*** 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" // the reused intefaces
#include "..\idl\aggregate.h" // the interface we're implementing
//-------------------------------------------------------------------
// global event telling use wen to shutdown our application
//-------------------------------------------------------------------
HANDLE g_hExitEvent;
//-------------------------------------------------------------------
// Component Level Reference count for the lifetime managment of
// the whole component.
// These specific implementations are used for out-of-process servers
// There's a pair of functions like these that are used for
// in-process servers.
//-------------------------------------------------------------------
inline ULONG ComponentAddRef()
{
ULONG ul = CoAddRefServerProcess();
wprintf(TEXT("ComponentAddRef(%ld)\n"), ul);
return ul ;
}
inline ULONG ComponentRelease()
{
ULONG ul = CoReleaseServerProcess();
// wait 3 second to test for REGCLS_MULTIPLEUSE
// Sleep(3000);
wprintf(TEXT("ComponentRelease(%ld)\n"), ul);
if (ul==0) {
SetEvent(g_hExitEvent);
}
return ul ;
}
//*******************************************************************
//*******************************************************************
//*** 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 out-of-process server support the
// -regserver option
//-------------------------------------------------------------------
void RegisterComponent()
{
wchar_t wszKey[MAX_PATH];
wchar_t wszValue[MAX_PATH];
HKEY hKey = 0;
// HKEY_CLASSES_ROOT\CLSID\{A0F3554A-C5C1-11d1-9150-006008052F2D}
// @="Thesaurus"
wcscpy(wszKey, TEXT("CLSID\\{A0F3554A-C5C1-11d1-9150-006008052F2D}"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
wcscpy(wszValue, TEXT("Thesaurus"));
RegSetValueEx(hKey, 0, 0, REG_SZ, (BYTE*)wszValue, ByteLen(wszValue));
// "AppID"="{63B53C11-C46B-11d1-83B4-006008CDD9AE}"
wcscpy(wszValue, TEXT("{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
RegSetValueEx(hKey, TEXT("AppID"), 0, REG_SZ,
(BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
// HKEY_CLASSES_ROOT\CLSID\{A0F3554A-C5C1-11d1-9150-006008052F2D}\LocalServer32
// @="...path...\aggregate.exe"
wcscpy(wszKey, TEXT("CLSID\\{A0F3554A-C5C1-11d1-9150-006008052F2D}\\")
TEXT("LocalServer32"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
GetModuleFileName(0, wszValue, MAX_PATH);
RegSetValueEx(hKey, 0, 0, REG_SZ, (BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
// HKEY_CLASSES_ROOT\AppID\aggregate.exe
// "AppID"="{63B53C11-C46B-11d1-83B4-006008CDD9AE}"
wcscpy(wszKey, TEXT("AppID\\aggregate.exe"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
wcscpy(wszValue, TEXT("{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
RegSetValueEx(hKey, TEXT("AppID"), 0, REG_SZ,
(BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
// HKEY_CLASSES_ROOT\AppID\{63B53C11-C46B-11d1-83B4-006008CDD9AE}
// @="Thesaurus"
wcscpy(wszKey, TEXT("AppID\\{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
RegCreateKey(HKEY_CLASSES_ROOT, wszKey, &hKey);
wcscpy(wszValue, TEXT("Thesaurus"));
RegSetValueEx(hKey, 0, 0, REG_SZ,
(BYTE*)wszValue, ByteLen(wszValue));
RegCloseKey(hKey);
}
//-------------------------------------------------------------------
// Automatic unregistration; for out-of-process server support the
// -unregserver option
//-------------------------------------------------------------------
void UnregisterComponent()
{
long lRc = 0 ;
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("CLSID\\")
TEXT("{A0F3554A-C5C1-11d1-9150-006008052F2D}\\")
TEXT("LocalServer32"));
DisplayStatus(TEXT("Unregistered LocalServer32"), lRc);
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("CLSID\\")
TEXT("{A0F3554A-C5C1-11d1-9150-006008052F2D}"));
DisplayStatus(TEXT("Unregistered CLSID"), lRc);
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("AppID\\")
TEXT("{63B53C11-C46B-11d1-83B4-006008CDD9AE}"));
DisplayStatus(TEXT("Unregistered AppID"), lRc);
lRc = RegDeleteKey(HKEY_CLASSES_ROOT, TEXT("AppID\\aggregate.exe"));
DisplayStatus(TEXT("Unregistered aggregate.exe"), lRc);
}
//*******************************************************************
//*******************************************************************
//*** AGGREGATION...
//*** Class CoThesaurus - A component object that implements just
//*** one interface: IThesaurus.
//*** We are using aggregation to reuse the functionality of ISpell
//*** and IOcr that's been implemented by the inner object.
//*** If we happen to detect request for IOcr or ISpell, we
//*** will forward these calls to the inner object, thus reusing
//*** already implemented functionality.
//*******************************************************************
//*******************************************************************
class CoThesaurus : public IThesaurus {
public:
// constructors/destructors
// Code to support aggregation
CoThesaurus() : m_lRefCount(0), m_pUnkAggregate(0)
{
ComponentAddRef();
// creating the inner, reused object
CreateInnerObject();
}
// Code to support aggregation
~CoThesaurus()
{
if (m_pUnkAggregate) { m_pUnkAggregate->Release(); }
ComponentRelease();
}
// The factory will call this method to actually
// create this object
static HRESULT CreateObject(LPUNKNOWN pUnkOuter, REFIID riid,
void** ppv);
public:
// IUnknown Methods
STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
STDMETHODIMP_(ULONG) AddRef(void)
{ return InterlockedIncrement(&m_lRefCount); }
STDMETHODIMP_(ULONG) Release(void)
{
long lCount = InterlockedDecrement(&m_lRefCount);
if (lCount == 0) { delete this; }
return lCount;
}
// IThesaurus
STDMETHODIMP LookUp()
{ wprintf(TEXT("Lookup success...\n")); return S_OK; }
private:
// function to create the inner object for reuse
void CreateInnerObject();
private:
LONG m_lRefCount;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -