EXTCTL.CPP
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:8k
源码类别:

Windows编程

开发平台:

Visual C++

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