PageRenderTime 15ms CodeModel.GetById 1ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2008/CppExeCOMServer/SimpleObject.cpp

#
C++ | 248 lines | 159 code | 42 blank | 47 comment | 25 complexity | 8d3fb9eb9b9ec0f5eabdd37c2f99cf2d MD5 | raw file
  1/****************************** Module Header ******************************\
  2Module Name:  SimpleObject.cpp
  3Project:      CppExeCOMServer
  4Copyright (c) Microsoft Corporation.
  5
  6
  7
  8This source is subject to the Microsoft Public License.
  9See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
 10All other rights reserved.
 11
 12THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 13EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 14WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 15\***************************************************************************/
 16
 17#include "SimpleObject.h"
 18#include "CppExeCOMServer_i.c"  // For component GUIDs
 19
 20
 21SimpleObject::SimpleObject() : m_cRef(1), m_fField(0.0F), m_ptinfo(NULL)
 22{
 23}
 24
 25SimpleObject::~SimpleObject()
 26{
 27}
 28
 29
 30//
 31// IUnknown
 32//
 33
 34// Query to the interface the component supported.
 35IFACEMETHODIMP SimpleObject::QueryInterface(REFIID riid, void **ppv)
 36{
 37    HRESULT hr = S_OK;
 38
 39    if (IsEqualIID(IID_IUnknown, riid))
 40    {
 41        *ppv = static_cast<IUnknown *>(this);
 42    }
 43    else if (IsEqualIID(IID_IDispatch, riid)) // For implementing IDispatch
 44    {
 45        *ppv = static_cast<IDispatch *>(this);
 46    }
 47    else if (IsEqualIID(IID_ISimpleObject, riid))
 48    {
 49        *ppv = static_cast<ISimpleObject *>(this);
 50    }
 51    else
 52    {
 53        hr = E_NOINTERFACE;
 54        *ppv = NULL;
 55    }
 56    
 57    if (*ppv)
 58    {
 59        AddRef();
 60    }
 61
 62    return hr;
 63}
 64
 65// Increase the reference count for an interface on an object.
 66IFACEMETHODIMP_(ULONG) SimpleObject::AddRef()
 67{
 68    return InterlockedIncrement(&m_cRef);
 69}
 70
 71// Decrease the reference count for an interface on an object.
 72IFACEMETHODIMP_(ULONG) SimpleObject::Release()
 73{
 74    ULONG cRef = InterlockedDecrement(&m_cRef);
 75    if (0 == cRef)
 76    {
 77        delete this;
 78    }
 79
 80    return cRef;
 81}
 82
 83
 84//
 85// IDispatch
 86//
 87
 88// This method retrieves the number of type information interfaces that an 
 89// object provides, either 0 or 1. If the object provides type information, 
 90// this *pctinfo is 1; otherwise the *pctinfo is 0.
 91IFACEMETHODIMP SimpleObject::GetTypeInfoCount(UINT *pctinfo)
 92{
 93    if (pctinfo == NULL) 
 94    {
 95        return E_POINTER; 
 96    }
 97    *pctinfo = 1;
 98    return S_OK;
 99}
100
101// This method retrieves the type information for an object.
102IFACEMETHODIMP SimpleObject::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
103{
104    HRESULT hr = S_OK;
105    *pptinfo = NULL;
106
107    if (itinfo != 0)
108    {
109        return ResultFromScode(DISP_E_BADINDEX);
110    }
111
112    if (m_ptinfo == NULL)
113    {
114        // Load the type info.
115        hr = LoadTypeInfo(&m_ptinfo, LIBID_CppExeCOMServerLib, IID_ISimpleObject, 0);
116    }
117
118    if (SUCCEEDED(hr))
119    {
120        // AddRef and return pointer to cached typeinfo.
121        m_ptinfo->AddRef();
122        *pptinfo = m_ptinfo;
123    }
124
125    return hr;
126}
127
128// Helper function to load the type info.
129HRESULT SimpleObject::LoadTypeInfo(ITypeInfo **pptinfo, 
130                                   const CLSID& libid, 
131                                   const CLSID& iid, 
132                                   LCID lcid)
133{
134    HRESULT hr;
135    LPTYPELIB ptlib = NULL;
136    LPTYPEINFO ptinfo = NULL;
137
138    *pptinfo = NULL;
139
140    // Load the type library.
141    hr = LoadRegTypeLib(libid, 1, 0, lcid, &ptlib);
142    if (SUCCEEDED(hr))
143    {
144        // Get type information for interface of the object.
145        hr = ptlib->GetTypeInfoOfGuid(iid, &ptinfo);
146        if (SUCCEEDED(hr))
147        {
148            *pptinfo = ptinfo;
149        }
150
151        ptlib->Release();
152    }
153
154    return hr;
155}
156
157// Maps a single member and an optional set of argument names to a 
158// corresponding set of integer DISPIDs, which can be used on subsequent 
159// calls to IDispatch::Invoke. The dispatch function DispGetIDsOfNames 
160// provides a standard implementation of GetIDsOfNames.
161IFACEMETHODIMP SimpleObject::GetIDsOfNames(REFIID riid, 
162                                           LPOLESTR *rgszNames, 
163                                           UINT cNames, 
164                                           LCID lcid, 
165                                           DISPID* rgdispid)
166{
167    HRESULT hr = S_OK;
168
169    if (m_ptinfo == NULL)
170    {
171        // Load the type info.
172        hr = LoadTypeInfo(&m_ptinfo, LIBID_CppExeCOMServerLib, IID_ISimpleObject, 0);
173    }
174
175    if (SUCCEEDED(hr))
176    {
177        hr = DispGetIDsOfNames(m_ptinfo, rgszNames, cNames, rgdispid);
178    }
179
180    return hr;
181}
182
183// Provides access to properties and methods exposed by an object. The 
184// dispatch function DispInvoke Function provides a standard implementation 
185// of IDispatch::Invoke.
186IFACEMETHODIMP SimpleObject::Invoke(DISPID dispidMember, 
187                                    REFIID riid,
188                                    LCID lcid,
189                                    WORD wFlags,
190                                    DISPPARAMS *pdispParams,
191                                    VARIANT *pvarResult,
192                                    EXCEPINFO *pExcepInfo, 
193                                    UINT *puArgErr)
194{
195    HRESULT hr = S_OK;
196
197    if (m_ptinfo == NULL)
198    {
199        // Load the type info.
200        hr = LoadTypeInfo(&m_ptinfo, LIBID_CppExeCOMServerLib, IID_ISimpleObject, 0);
201    }
202
203    if (SUCCEEDED(hr))
204    {
205        hr = DispInvoke(this, m_ptinfo, dispidMember, wFlags, pdispParams, 
206            pvarResult, pExcepInfo, puArgErr); 
207    }
208
209    return hr;
210}
211
212
213//
214// ISimpleObject
215//
216
217IFACEMETHODIMP SimpleObject::get_FloatProperty(FLOAT *pVal)
218{
219    *pVal = m_fField;
220    return S_OK;
221}
222
223IFACEMETHODIMP SimpleObject::put_FloatProperty(FLOAT newVal)
224{
225    m_fField = newVal;
226    return S_OK;
227}
228
229IFACEMETHODIMP SimpleObject::HelloWorld(BSTR *pRet)
230{
231    // Allocate memory for the string.
232    *pRet = ::SysAllocString(L"HelloWorld");
233    if (pRet == NULL)
234    {
235        return E_OUTOFMEMORY;
236    }
237
238    // The client is now responsible for freeing the BSTR.
239    return S_OK;
240}
241
242IFACEMETHODIMP SimpleObject::GetProcessThreadID(LONG *pdwProcessId, LONG *pdwThreadId)
243{
244    *pdwProcessId = GetCurrentProcessId();
245    *pdwThreadId = GetCurrentThreadId();
246
247    return S_OK;
248}