// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // // // Declares a convenience coclass implementation that makes it easy to create // initialized object instances. #ifndef CEEE_COMMON_INITIALIZING_COCLASS_H_ #define CEEE_COMMON_INITIALIZING_COCLASS_H_ #include #include using ATL::CComObject; // A convenience mixin coclass, to allow creating and initializing // CComObject-derived object instances, and optionally query them for // a given interface, all in a single CreateInstance invocation. // // Usage: // // class MyObjectImpl: public CComObjectRoot<...>, // public InitializingCoClass, ... { // public: // // This function will be invoked when MyObjectImpl::CreateInstance with N // // arguments of the appropriate type is invoked. // // @note if this function returns error, the object will be destroyed // // @note reference args must be const // HRESULT Initialize(SomeType1 arg1, ..., SomeTypeN argN); // }; // ... // CComPtr foo; // HRESULT hr = MyObjectImp::CreateInstance(arg1, ..., argN, &foo) // // // @param T the CComObjectRootEx derivative class you want to create and // initalize. template class InitializingCoClass { public: typedef CComObject TImpl; // Creates an instance of CComObject and initializes it. // @param new_instance on success returns the new, initialized instance. // @note this method does not return a reference to the new object. static HRESULT CreateInstance(T** new_instance) { TImpl* instance; HRESULT hr = TImpl::CreateInstance(&instance); if (FAILED(hr)) return hr; instance->InternalFinalConstructAddRef(); hr = instance->Initialize(); instance->InternalFinalConstructRelease(); if (FAILED(hr)) { delete instance; instance = NULL; } *new_instance = instance; return hr; } // Creates an instance of CComObject, initializes it and queries it // for interface I. // @param instance on success returns the new, initialized instance. template static HRESULT CreateInitialized(I** instance) { T* new_instance; HRESULT hr = CreateInstance(&new_instance); if (FAILED(hr)) return hr; hr = new_instance->QueryInterface(__uuidof(I), reinterpret_cast(instance)); if (FAILED(hr)) delete new_instance; return hr; } // Creates an instance of CComObject, initializes it and queries it // for an interface. // @param iid the interface to query for. Must be congruent to the type I. // @param instance on success returns the new, initialized instance. template static HRESULT CreateInitializedIID(REFIID iid, I** instance) { T* new_instance; HRESULT hr = CreateInstance(&new_instance); if (FAILED(hr)) return hr; hr = new_instance->QueryInterface(iid, reinterpret_cast(instance)); if (FAILED(hr)) delete new_instance; return hr; } // This file is chock full of repetitions of the same code, and because we // don't yet stock infinite monkeys (nor infinite developers to review their // code) we substitute with the python script initializing_coclass.py // // The functions therein are of this general make: // Create a new, initialized T* instance. Note that zero references will // be held to *new_instance at return. // // template // HRESULT CreateInstance(A1 a1, ..., An an, T **new_instance); // // Create a new, initialized T* instance, and QI it for I // template // HRESULT CreateInstance(A1 a1, ..., An an, I **new_instance); #include "initializing_coclass_gen.inl" // NOLINT }; #ifndef CEEE_COMMON_INITIALIZING_COCLASS_GEN_INL_ #error initializing_coclass_gen.inl wasn't generated correctly. #endif #endif // CEEE_COMMON_INITIALIZING_COCLASS_H_