Microsoft KB Archive/173823: Difference between revisions

From BetaArchive Wiki
m (Text replacement - ">" to ">")
m (Text replacement - "&" to "&")
 
(One intermediate revision by the same user not shown)
Line 115: Line 115:
<pre class="codesample">  class ATL_NO_VTABLE COutObj :
<pre class="codesample">  class ATL_NO_VTABLE COutObj :
         public CComObjectRootEx<CComSingleThreadModel>,
         public CComObjectRootEx<CComSingleThreadModel>,
         public CComCoClass<COutObj, &amp;CLSID_OutObj>,
         public CComCoClass<COutObj, &CLSID_OutObj>,
         public IDispatchImpl<IOutObj, &amp;IID_IOutObj, &amp;LIBID_OUTEROBJLib>
         public IDispatchImpl<IOutObj, &IID_IOutObj, &LIBID_OUTEROBJLib>
   {
   {
   public:
   public:
Line 138: Line 138:
         CLSID  clsidInner;
         CLSID  clsidInner;


         hr = CLSIDFromProgID(L&quot;InnObj.InnObj.1&quot;, &amp;clsidInner);
         hr = CLSIDFromProgID(L"InnObj.InnObj.1", &clsidInner);
         if (hr == S_OK)
         if (hr == S_OK)
             hr = CoCreateInstance(clsidInner, GetControllingUnknown(),
             hr = CoCreateInstance(clsidInner, GetControllingUnknown(),
                                   CLSCTX_INPROC_SERVER, IID_IUnknown,
                                   CLSCTX_INPROC_SERVER, IID_IUnknown,
                                   (void**)&amp;m_pInnerUnk);
                                   (void**)&m_pInnerUnk);
         return hr;
         return hr;
       } // End of step 4
       } // End of step 4
Line 160: Line 160:
         return  CInnObj::_CreatorClass::CreateInstance(
         return  CInnObj::_CreatorClass::CreateInstance(
             GetControllingUnknown(), IID_IUnknown,
             GetControllingUnknown(), IID_IUnknown,
             (void**)&amp;m_pInnerUnk);
             (void**)&m_pInnerUnk);


       }
       }

Latest revision as of 11:30, 21 July 2020

Knowledge Base


Article ID: 173823

Article Last Modified on 6/29/2004



APPLIES TO

  • Microsoft ActiveX Template Library 3.0, when used with:
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++ 6.0 Standard Edition
    • Microsoft Visual C++ .NET 2002 Standard Edition
    • Microsoft Visual C++ .NET 2003 Standard Edition
  • Microsoft ActiveX Template Library 2.1, when used with:
    • Microsoft Visual C++ 5.0 Enterprise Edition
    • Microsoft Visual C++ 6.0 Enterprise Edition
    • Microsoft Visual C++ 5.0 Professional Edition
    • Microsoft Visual C++ 6.0 Professional Edition
    • Microsoft Visual C++ 6.0 Standard Edition
    • Microsoft Visual C++ .NET 2002 Standard Edition
    • Microsoft Visual C++ .NET 2003 Standard Edition



This article was previously published under Q173823

Note Microsoft Visual C++ .NET (2002) supports both the managed code model that is provided by the Microsoft .NET Framework and the unmanaged native Microsoft Windows code model. The information in this article applies only to unmanaged Visual C++ code.

SUMMARY

The following steps demonstrate how to aggregate a COM object in an ATL project:

  1. Add an IUnknown pointer to your class object and initialize it to NULL in the constructor.
  2. Add the DECLARE_PROTECT_FINAL_CONSTRUCT macro to protect your object from being deleted if (during FinalConstruct) the internal aggregated object increments the reference count then decrements the count to 0.


NOTE: If you are using Visual C++.NET the Wizard adds this for you.

  1. Use the IUnknown pointer you defined as the second parameter to the COM_INTERFACE_ENTRY_AGGREGATE macros. The first parameter is the IID of the interface of the inner object that you want to expose.
  2. Override FinalConstruct() to create the aggregate.
  3. Override FinalRelease() to release the IUnknown pointer.


MORE INFORMATION

If you use and release an interface from the aggregate during FinalConstruct, you should add the DECLARE_PROTECT_FINAL_CONSTRUCT macro to the definition of your class object.

Here is a sample with all four of the steps done in the class definition. This is a simple object, COutObj, which aggregates another simple object, CInnObj.

Sample Code

   class ATL_NO_VTABLE COutObj :
         public CComObjectRootEx<CComSingleThreadModel>,
         public CComCoClass<COutObj, &CLSID_OutObj>,
         public IDispatchImpl<IOutObj, &IID_IOutObj, &LIBID_OUTEROBJLib>
   {
   public:
      COutObj() : m_pInnerUnk(NULL) // Step 1
      {
      }
      DECLARE_GET_CONTROLLING_UNKNOWN()
      DECLARE_REGISTRY_RESOURCEID(IDR_OUTOBJ)
      DECLARE_PROTECT_FINAL_CONSTRUCT() // Step 2

      BEGIN_COM_MAP(COutObj)
         COM_INTERFACE_ENTRY(IOutObj)
         COM_INTERFACE_ENTRY(IDispatch)
         COM_INTERFACE_ENTRY_AGGREGATE(IID_IInnObj, m_pInnerUnk) // Step 3
      END_COM_MAP()

      // Start of step 4
      HRESULT FinalConstruct()
      {
         HRESULT hr;
         CLSID   clsidInner;

         hr = CLSIDFromProgID(L"InnObj.InnObj.1", &clsidInner);
         if (hr == S_OK)
            hr = CoCreateInstance(clsidInner, GetControllingUnknown(),
                                  CLSCTX_INPROC_SERVER, IID_IUnknown,
                                  (void**)&m_pInnerUnk);
         return hr;
      } // End of step 4

      void FinalRelease(){m_pInnerUnk->Release();} // Step 5

      // IOutObj
   public:
      STDMETHOD(Test)();
   private:
      LPUNKNOWN m_pInnerUnk; // Step 1
   };
                

If the inner object is in the same ATL server, then you can use the following code to create the inner object without CoCreateInstance:

   HRESULT FinalConstruct()
      {
         return  CInnObj::_CreatorClass::CreateInstance(
             GetControllingUnknown(), IID_IUnknown,
             (void**)&m_pInnerUnk);

      }
                

REFERENCES

Visual C++ Books Online: Visual C++ Books; C/C++ Language and C++ Library; Active Template Library; Articles; Introduction to COM and ATL; Introduction to COM; Aggregation

Visual C++ Books Online: Visual C++ Books; C/C++ Language and C++ Library; Active Template Library; Articles; Fundamentals of ATL COM Objects; Creating an Aggregate



Additional query words: derive override kbATL210 kbATL300 kbctrl kbserver

Keywords: kbhowto kbarchitecture KB173823