home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / ole / tstcon / extctl.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-03  |  8.2 KB  |  393 lines

  1. #include "StdAfx.H"
  2. #include "TestCon.H"
  3.  
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9.  
  10. // {FFC3C462-18DE-11d1-8E2F-00C04FB68D60}
  11. const GUID LIBID_TCPROPSLib =
  12. { 0xffc3c462, 0x18de, 0x11d1, { 0x8e, 0x2f, 0x0, 0xc0, 0x4f, 0xb6, 0x8d, 0x60 } };
  13.  
  14. CExtendedControl::CExtendedControl() :
  15.    m_nRefCount( 0 ),
  16.    m_pControl( NULL ),
  17.    m_tVisible( TRUE )
  18. {
  19. }
  20.  
  21. CExtendedControl::~CExtendedControl()
  22. {
  23.    if( m_pInnerDispatch != NULL )
  24.    {
  25.       AddRef();  // Undo the artificial Release
  26.       m_pInnerDispatch.Release();
  27.    }
  28.  
  29.    if( m_pControl != NULL )
  30.    {
  31.       m_pControl->Release();
  32.       m_pControl = NULL;
  33.    }
  34. }
  35.  
  36. HRESULT CExtendedControl::Init( REFCLSID clsidControl,
  37.    CTestContainer98Item* pItem )
  38. {
  39.    USES_CONVERSION;
  40.    HRESULT hResult;
  41.    ITypeLibPtr pTypeLib;
  42.    LPOLESTR pszModuleO;
  43.    TCHAR szModule[MAX_PATH];
  44.    CString strTLBPath;
  45.    ULONG nOldRefCount;
  46.  
  47.    ASSERT( m_pItem != NULL );
  48.    ASSERT( m_pControl == NULL );
  49.  
  50.    m_nRefCount++;  // Protect ourselves while we create the aggregate
  51.  
  52.    hResult = CoCreateInstance( clsidControl, (IUnknown*)this,
  53.       CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER, IID_IUnknown,
  54.      (void**)&m_pControl );
  55.    if( FAILED( hResult ) )
  56.    {
  57.       return( hResult );
  58.    }
  59.  
  60.    nOldRefCount = m_nRefCount;  // Remember our refcount before we QI the
  61.    // aggregate
  62.    m_pInnerDispatch = m_pControl;
  63.    if( m_pInnerDispatch == NULL )
  64.    {
  65.       return( E_NOINTERFACE );
  66.    }
  67.    if( m_nRefCount == nOldRefCount )
  68.    {
  69.       // The control didn't delegate its AddRef to us.  This probably means
  70.       // that the control doesn't support aggregation, but didn't return
  71.       // CLASS_E_NOAGGREGATION when we passed a non-null punkOuter to
  72.       // CoCreateInstance().
  73.       TCTrace( TRACELEVEL_NORMAL, "Control Bug: Aggregated control didn't delegate AddRef to extended control.  Trying without aggregation...\n" );
  74.       m_pInnerDispatch.Release();
  75.       m_nRefCount--;
  76.  
  77.       return( CLASS_E_NOAGGREGATION );
  78.    }
  79.    Release();  // Artificially release because we QI'd the aggregate.
  80.  
  81.    GetModuleFileName( NULL, szModule, MAX_PATH );
  82.    strTLBPath = szModule;
  83.    strTLBPath += _T( "\\2" );  // Load the second TLB from the executable
  84.  
  85.    pszModuleO = T2OLE( strTLBPath );
  86.    hResult = LoadTypeLib( pszModuleO, &pTypeLib );
  87.    if( FAILED( hResult ) )
  88.    {
  89.       TCTrace( TRACELEVEL_NORMAL,
  90.          "Failed to load typelib for extended control\n" );
  91.       return( hResult );
  92.    }
  93.  
  94.    hResult = pTypeLib->GetTypeInfoOfGuid( __uuidof( ITCExtendedControl ),
  95.       &m_pTypeInfo );
  96.    if( FAILED( hResult ) )
  97.    {
  98.       return( hResult );
  99.    }
  100.  
  101.    m_nRefCount--;  // Undo the extra refcount we added to protect ourself
  102.  
  103.    m_pItem = pItem;
  104.    m_pView = m_pItem->GetDocument()->GetView();
  105.  
  106.    return( S_OK );
  107. }
  108.  
  109. HRESULT CExtendedControl::CreateInstance( REFCLSID clsidControl,
  110.    CTestContainer98Item* pItem, IUnknown* pOuterUnknown, REFIID iid,
  111.    void** ppInterface )
  112. {
  113.    CExtendedControl* pObject;
  114.    HRESULT hResult;
  115.  
  116.    (void)pOuterUnknown;
  117.  
  118.    ASSERT( pOuterUnknown == NULL );
  119.    ASSERT( ppInterface != NULL );
  120.    *ppInterface = NULL;
  121.  
  122.    pObject = new CExtendedControl;
  123.    if( pObject == NULL )
  124.    {
  125.       return( E_OUTOFMEMORY );
  126.    }
  127.  
  128.    hResult = pObject->Init( clsidControl, pItem );
  129.    if( FAILED( hResult ) )
  130.    {
  131.       delete pObject;
  132.       return( hResult );
  133.    }
  134.  
  135.    hResult = pObject->QueryInterface( iid, ppInterface );
  136.    if( FAILED( hResult ) )
  137.    {
  138.       delete pObject;
  139.       return( hResult );
  140.    }
  141.  
  142.    return( S_OK );
  143. }
  144.  
  145. STDMETHODIMP_( ULONG ) CExtendedControl::AddRef()
  146. {
  147.    m_nRefCount++;
  148.  
  149.    return( m_nRefCount );
  150. }
  151.  
  152. STDMETHODIMP_( ULONG ) CExtendedControl::Release()
  153. {
  154.    m_nRefCount--;
  155.    if( m_nRefCount == 0 )
  156.    {
  157.       m_nRefCount++;
  158.       delete this;
  159.       return( 0 );
  160.    }
  161.  
  162.    return( m_nRefCount );
  163. }
  164.  
  165. STDMETHODIMP CExtendedControl::QueryInterface( REFIID iid, void** ppInterface )
  166. {
  167.    HRESULT hResult;
  168.  
  169.    ASSERT( ppInterface != NULL );
  170.    *ppInterface = NULL;
  171.  
  172.    if( iid == IID_IDispatch )
  173.    {
  174.       *ppInterface = (IDispatch*)this;
  175.       AddRef();
  176.    }
  177.    else if( iid == __uuidof( ITCExtendedControl ) )
  178.    {
  179.       *ppInterface = (ITCExtendedControl*)this;
  180.       AddRef();
  181.    }
  182.    else
  183.    {
  184.       ASSERT( m_pControl != NULL );
  185.       hResult = m_pControl->QueryInterface( iid, ppInterface );
  186.       if( FAILED( hResult ) )
  187.       {
  188.          return( hResult );
  189.       }
  190.    }
  191.  
  192.    return( S_OK );
  193. }
  194.  
  195. STDMETHODIMP CExtendedControl::GetIDsOfNames( REFIID iid, LPOLESTR* ppszNames,
  196.    UINT nNames, LCID lcid, DISPID* pDispIDs )
  197. {
  198.    HRESULT hResult;
  199.  
  200.    hResult = m_pTypeInfo->GetIDsOfNames( ppszNames, nNames, pDispIDs );
  201.    if( FAILED( hResult ) )
  202.    {
  203.       hResult = m_pInnerDispatch->GetIDsOfNames( iid, ppszNames, nNames, lcid,
  204.          pDispIDs );
  205.    }
  206.  
  207.    return( hResult );
  208. }
  209.  
  210. STDMETHODIMP CExtendedControl::GetTypeInfo( UINT iTypeInfo, LCID lcid,
  211.    ITypeInfo** ppTypeInfo )
  212. {
  213.    return( m_pInnerDispatch->GetTypeInfo( iTypeInfo, lcid, ppTypeInfo ) );
  214. }
  215.  
  216. STDMETHODIMP CExtendedControl::GetTypeInfoCount( UINT* pnInfoCount )
  217. {
  218.    return( m_pInnerDispatch->GetTypeInfoCount( pnInfoCount ) );
  219. }
  220.  
  221. HRESULT CExtendedControl::InternalInvoke( DISPID dispidMember, REFIID iid,
  222.    LCID lcid, WORD wFlags, DISPPARAMS* pdpParams, VARIANT* pvarResult,
  223.    EXCEPINFO* pExceptionInfo, UINT* piArgError )
  224. {
  225.    (void)iid;
  226.    (void)lcid;
  227.  
  228.    return( m_pTypeInfo->Invoke( this, dispidMember, wFlags, pdpParams,
  229.       pvarResult, pExceptionInfo, piArgError ) );
  230. }
  231.  
  232. STDMETHODIMP CExtendedControl::Invoke( DISPID dispidMember, REFIID iid,
  233.    LCID lcid, WORD wFlags, DISPPARAMS* pdpParams, VARIANT* pvarResult,
  234.    EXCEPINFO* pExceptionInfo, UINT* piArgError )
  235. {
  236.    HRESULT hResult;
  237.  
  238.    if( pdpParams == NULL )
  239.    {
  240.       return( E_INVALIDARG );
  241.    }
  242.  
  243.    hResult = DISP_E_MEMBERNOTFOUND;
  244.    if( iid == IID_NULL )
  245.    {
  246.       hResult = InternalInvoke( dispidMember, iid, lcid, wFlags, pdpParams,
  247.          pvarResult, pExceptionInfo, piArgError );
  248.    }
  249.    if( hResult == DISP_E_MEMBERNOTFOUND )
  250.    {
  251.       hResult = m_pInnerDispatch->Invoke( dispidMember, iid, lcid, wFlags,
  252.          pdpParams, pvarResult, pExceptionInfo, piArgError );
  253.    }
  254.  
  255.    return( hResult );
  256. }
  257.  
  258. STDMETHODIMP CExtendedControl::get_Name( BSTR* pbstrName )
  259. {
  260.    ASSERT( pbstrName != NULL );
  261.  
  262.    *pbstrName = m_bstrName.copy();
  263.    if( *pbstrName == NULL )
  264.    {
  265.       return( E_OUTOFMEMORY );
  266.    }
  267.  
  268.    return( S_OK );
  269. }
  270.  
  271. STDMETHODIMP CExtendedControl::put_Name( BSTR bstrName )
  272. {
  273.    m_bstrName = bstrName;
  274.  
  275.    return( S_OK );
  276. }
  277.  
  278. STDMETHODIMP CExtendedControl::get_PositionX( long* px )
  279. {
  280.    if( px == NULL )
  281.    {
  282.       return( E_POINTER );
  283.    }
  284.  
  285.    *px = m_ptPosition.x;
  286.  
  287.    return( S_OK );
  288. }
  289.  
  290. STDMETHODIMP CExtendedControl::put_PositionX( long x )
  291. {
  292.    m_ptPosition.x = x;
  293.  
  294.    return( S_OK );
  295. }
  296.  
  297. STDMETHODIMP CExtendedControl::get_PositionY( long* py )
  298. {
  299.    if( py == NULL )
  300.    {
  301.       return( E_POINTER );
  302.    }
  303.  
  304.    *py = m_ptPosition.y;
  305.  
  306.    return( S_OK );
  307. }
  308.  
  309. STDMETHODIMP CExtendedControl::put_PositionY( long y )
  310. {
  311.    m_ptPosition.y = y;
  312.  
  313.    return( S_OK );
  314. }
  315.  
  316. STDMETHODIMP CExtendedControl::get_SizeX( long* px )
  317. {
  318.    if( px == NULL )
  319.    {
  320.       return( E_POINTER );
  321.    }
  322.  
  323.    *px = m_size.cx;
  324.  
  325.    return( S_OK );
  326. }
  327.  
  328. STDMETHODIMP CExtendedControl::put_SizeX( long x )
  329. {
  330.    m_size.cx = x;
  331.  
  332.    return( S_OK );
  333. }
  334.  
  335. STDMETHODIMP CExtendedControl::get_SizeY( long* py )
  336. {
  337.    if( py == NULL )
  338.    {
  339.       return( E_POINTER );
  340.    }
  341.  
  342.    *py = m_size.cy;
  343.  
  344.    return( S_OK );
  345. }
  346.  
  347. STDMETHODIMP CExtendedControl::put_SizeY( long y )
  348. {
  349.    m_size.cy = y;
  350.  
  351.    return( S_OK );
  352. }
  353.  
  354. STDMETHODIMP CExtendedControl::raw_Activate()
  355. {
  356.    if( !m_pItem->IsInPlaceActive() )
  357.    {
  358.       m_pItem->Activate( OLEIVERB_SHOW, m_pView );
  359.    }
  360.  
  361.    return( S_OK );
  362. }
  363.  
  364. STDMETHODIMP CExtendedControl::raw_Deactivate()
  365. {
  366.    if( m_pItem->IsInPlaceActive() )
  367.    {
  368.       m_pItem->Deactivate();
  369.    }
  370.  
  371.    return( S_OK );
  372. }
  373.  
  374. STDMETHODIMP CExtendedControl::raw_UIActivate()
  375. {
  376.    if( !m_pItem->IsUIActive() )
  377.    {
  378.       m_pItem->DoVerb( OLEIVERB_UIACTIVATE, m_pView );
  379.    }
  380.  
  381.    return( S_OK );
  382. }
  383.  
  384. STDMETHODIMP CExtendedControl::raw_UIDeactivate()
  385. {
  386.    if( m_pItem->IsUIActive() )
  387.    {
  388.       m_pItem->DeactivateUI();
  389.    }
  390.  
  391.    return( S_OK );
  392. }
  393.