1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
| #include "stdafx.h" //Windows.h, OleAuto.h, ObjBase.h
#include "TLBHeader\iface.h"
#include "DynLib1.h"
class CCOMObj : public IDynLib1
{
private:
LONG count;
ITypeInfo *m_pTypeInfo;
IUnknown *m_pUnknownStdDisp;
public:
CCOMObj() : count(1) {}
~CCOMObj();
HRESULT Init(void);
STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP GetTypeInfoCount(UINT* pCountTypeInfo);
STDMETHODIMP GetTypeInfo(UINT iTypeInfo, LCID lcid, ITypeInfo** ppITypeInfo);
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId);
STDMETHODIMP Invoke(DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo,
UINT* puArgErr);
STDMETHODIMP Fonc(SAFEARRAY** ppArr, int *pRet);
};
//IUnknown implementation
STDMETHODIMP CCOMObj::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown || riid == IID_IDynLib1)
{
IDynLib1 * pRet = this;
pRet->AddRef();
*ppv = pRet;
return S_OK;
}
else if(riid == IID_IDispatch)
{
return m_pUnknownStdDisp->QueryInterface(riid, ppv);
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
}
STDMETHODIMP_(ULONG) CCOMObj::AddRef(void)
{
return InterlockedIncrement(&count);
}
STDMETHODIMP_(ULONG) CCOMObj::Release(void)
{
ULONG ret = InterlockedDecrement(&count);
if(ret == 0)
{
delete this;
}
return ret;
}
//IDispatch implementation
HRESULT CCOMObj::GetTypeInfoCount(UINT* pCountTypeInfo)
{
*pCountTypeInfo = 1;
return S_OK;
}
HRESULT CCOMObj::GetTypeInfo(UINT iTypeInfo, LCID lcid,
ITypeInfo** ppITypeInfo)
{
*ppITypeInfo = NULL;
if(iTypeInfo != 0)
return DISP_E_BADINDEX;
m_pTypeInfo->AddRef();
*ppITypeInfo = m_pTypeInfo;
return S_OK;
}
HRESULT CCOMObj::GetIDsOfNames(REFIID riid,
LPOLESTR* rgszNames, UINT cNames, LCID lcid,
DISPID* rgDispId)
{
if(riid != IID_NULL)
return DISP_E_UNKNOWNINTERFACE;
return DispGetIDsOfNames(m_pTypeInfo, rgszNames, cNames,
rgDispId);
}
HRESULT CCOMObj::Invoke(DISPID dispIdMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr)
{
if(riid != IID_NULL)
return DISP_E_UNKNOWNINTERFACE;
return DispInvoke(this, m_pTypeInfo, dispIdMember, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
}
//IDynLib1 implementation
STDMETHODIMP CCOMObj::Fonc(SAFEARRAY** ppArr, int *pRet)
{
if(ppArr==NULL || pRet==NULL)
return E_POINTER;
SAFEARRAY* pArr = *ppArr;
if(pArr != NULL && SafeArrayGetDim(pArr)==1)
{
LONG ix = 1;
BSTR s = NULL;
HRESULT hr = SafeArrayGetElement(pArr, &ix, &s);
MessageBoxW(NULL, s, L"Test (W)", MB_OK|MB_ICONINFORMATION);
SysFreeString(s);
}
*pRet = 0;
return S_OK;
}
//Creation
HRESULT CCOMObj::Init()
{
ITypeLib* pTypeLib;
HRESULT hr;
hr = LoadTypeLib(L"iface.tlb", &pTypeLib);
if(FAILED(hr))
return hr;//E_FAIL;
hr = pTypeLib->GetTypeInfoOfGuid(IID_IDynLib1, &m_pTypeInfo);
pTypeLib->Release();
if(FAILED(hr))
return hr;
return CreateStdDispatch(this, this, m_pTypeInfo, &m_pUnknownStdDisp);
}
CCOMObj::~CCOMObj()
{
count = 42; //Artificial bump to avoid double-destruction if some destructor plays with references to this class
if(m_pTypeInfo != NULL)
m_pTypeInfo->Release(), m_pTypeInfo=NULL;
if(m_pUnknownStdDisp != NULL)
m_pUnknownStdDisp->Release(), m_pUnknownStdDisp=NULL;
}
EXTERN_C DYNLIB1_API STDMETHODIMP GetCOMObj(IDynLib1 **ppRet)
{
if(ppRet==NULL)
return E_POINTER;
*ppRet = NULL;
CCOMObj *pRet = new CCOMObj();
HRESULT hRet = pRet->Init();
if(SUCCEEDED(hRet))
{
pRet->QueryInterface(__uuidof(*ppRet), (void**)ppRet);
}
pRet->Release();
return hRet;
} |
Partager