home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / ctlobj.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-16  |  10.5 KB  |  428 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFXCTL_CORE2_SEG
  14. #pragma code_seg(AFXCTL_CORE2_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. #define new DEBUG_NEW
  23.  
  24. /////////////////////////////////////////////////////////////////////////////
  25. // COleControl::XOleObject
  26.  
  27. STDMETHODIMP_(ULONG) COleControl::XOleObject::AddRef()
  28. {
  29.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  30.     return (ULONG)pThis->ExternalAddRef();
  31. }
  32.  
  33. STDMETHODIMP_(ULONG) COleControl::XOleObject::Release()
  34. {
  35.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  36.     return (ULONG)pThis->ExternalRelease();
  37. }
  38.  
  39. STDMETHODIMP COleControl::XOleObject::QueryInterface(
  40.     REFIID iid, LPVOID* ppvObj)
  41. {
  42.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  43.     return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
  44. }
  45.  
  46. STDMETHODIMP COleControl::XOleObject::SetClientSite(LPOLECLIENTSITE pClientSite)
  47. {
  48.     METHOD_PROLOGUE_EX(COleControl, OleObject)
  49.  
  50.     ASSERT_NULL_OR_POINTER(pClientSite, IOleClientSite);
  51.  
  52.     // maintain reference counts
  53.     if (pClientSite != NULL)
  54.         pClientSite->AddRef();
  55.     RELEASE(pThis->m_pClientSite);
  56.     pThis->m_pClientSite = pClientSite;
  57.  
  58.     // Release existing pointer to ambient property dispinterface.
  59.     pThis->m_ambientDispDriver.ReleaseDispatch();
  60.  
  61.     if (pClientSite != NULL)
  62.     {
  63.         BOOL bValue;
  64.         pThis->m_bAutoClip =
  65.             pThis->GetAmbientProperty(DISPID_AMBIENT_AUTOCLIP, VT_BOOL, &bValue) ? bValue : 0;
  66.         pThis->m_bMsgReflect =
  67.             pThis->GetAmbientProperty(DISPID_AMBIENT_MESSAGEREFLECT, VT_BOOL, &bValue) ? bValue : 0;
  68.         pThis->m_bUIDead = (BYTE)(pThis->AmbientUIDead());
  69.     }
  70.  
  71.     // Release existing pointer to in-place site, if any.
  72.     RELEASE(pThis->m_pInPlaceSite);
  73.  
  74.     // Initialize pointer to control site
  75.     LPVOID pInterface;
  76.     if (pClientSite == NULL ||
  77.         FAILED(pClientSite->QueryInterface(IID_IOleControlSite, &pInterface)))
  78.     {
  79.         pInterface = NULL;
  80.     }
  81.  
  82.     RELEASE(pThis->m_pControlSite);
  83.     pThis->m_pControlSite = (LPOLECONTROLSITE) pInterface;
  84.  
  85.     // Initialize pointer to simple frame site
  86.     if (pClientSite == NULL || !pThis->m_bSimpleFrame ||
  87.         FAILED(pClientSite->QueryInterface(IID_ISimpleFrameSite, &pInterface)))
  88.     {
  89.         pInterface = NULL;
  90.     }
  91.  
  92.     RELEASE(pThis->m_pSimpleFrameSite);
  93.     pThis->m_pSimpleFrameSite = (LPSIMPLEFRAMESITE) pInterface;
  94.  
  95.     // Let the control run its own code here.
  96.     pThis->OnSetClientSite();
  97.  
  98.     // Unless IPersist*::Load or IPersist*::InitNew is called after this,
  99.     // we can't count on ambient properties being available while loading.
  100.     pThis->m_bCountOnAmbients = FALSE;
  101.  
  102.     return S_OK;
  103. }
  104.  
  105. STDMETHODIMP COleControl::XOleObject::GetClientSite(LPOLECLIENTSITE* ppClientSite)
  106. {
  107.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  108.  
  109.     ASSERT_POINTER(ppClientSite, LPOLECLIENTSITE);
  110.  
  111.     LPOLECLIENTSITE pClientSite = pThis->m_pClientSite;
  112.     *ppClientSite = pClientSite;
  113.     if (pClientSite != NULL)
  114.         pClientSite->AddRef();
  115.  
  116.     return (pClientSite != NULL) ? S_OK : E_FAIL;
  117. }
  118.  
  119. STDMETHODIMP COleControl::XOleObject::SetHostNames(LPCOLESTR, LPCOLESTR)
  120. {
  121.     return S_OK;
  122. }
  123.  
  124. STDMETHODIMP COleControl::XOleObject::Close(DWORD dwSaveOption)
  125. {
  126.     METHOD_PROLOGUE_EX(COleControl, OleObject)
  127.     pThis->OnClose(dwSaveOption);
  128.     return S_OK;
  129. }
  130.  
  131. void COleControl::OnClose(DWORD dwSaveOption)
  132. {
  133.     if (m_bInPlaceActive)
  134.         m_xOleInPlaceObject.InPlaceDeactivate();
  135.  
  136.     if (((dwSaveOption == OLECLOSE_SAVEIFDIRTY) || (dwSaveOption == OLECLOSE_PROMPTSAVE)) &&
  137.         m_bModified)
  138.     {
  139.         SendAdvise(OBJECTCODE_SAVEOBJECT);
  140.         SendAdvise(OBJECTCODE_SAVED);
  141.     }
  142. }
  143.  
  144. STDMETHODIMP COleControl::XOleObject::SetMoniker(DWORD, LPMONIKER)
  145. {
  146.     return E_NOTIMPL;
  147. }
  148.  
  149. STDMETHODIMP COleControl::XOleObject::GetMoniker(DWORD, DWORD, LPMONIKER*)
  150. {
  151.     return E_NOTIMPL;
  152. }
  153.  
  154. STDMETHODIMP COleControl::XOleObject::InitFromData(LPDATAOBJECT, BOOL, DWORD)
  155. {
  156.     return E_NOTIMPL;
  157. }
  158.  
  159. STDMETHODIMP COleControl::XOleObject::GetClipboardData(DWORD, LPDATAOBJECT*)
  160. {
  161.     return E_NOTIMPL;
  162. }
  163.  
  164. STDMETHODIMP COleControl::XOleObject::DoVerb(LONG iVerb, LPMSG lpmsg,
  165.     LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent,
  166.     LPCRECT lprcPosRect)
  167. {
  168.     METHOD_PROLOGUE_EX(COleControl, OleObject)
  169.  
  170.     TRY
  171.     {
  172.         if (pThis->OnDoVerb(iVerb, lpmsg, hwndParent, lprcPosRect))
  173.             return S_OK;                 // Custom verb succeeded
  174.     }
  175.     CATCH (CException, e)
  176.     {
  177.         return E_FAIL;     // Custom verb failed
  178.     }
  179.     END_CATCH
  180.  
  181.     // Custom verb not found, invoke standard verb instead.
  182.  
  183.     HRESULT hr;
  184.  
  185.     switch (iVerb)
  186.     {
  187.     case OLEIVERB_HIDE:
  188.         pThis->m_xOleInPlaceObject.UIDeactivate();
  189.         return pThis->OnHide();
  190.  
  191.  
  192.     case OLEIVERB_SHOW:
  193.         return pThis->OnOpen(-1, lpmsg);      // Try in-place first
  194.  
  195.     case OLEIVERB_UIACTIVATE:
  196.     case OLEIVERB_INPLACEACTIVATE:
  197. #ifdef _AFXDLL
  198.         if (pThis->m_bOpen)
  199.             return OLE_E_NOT_INPLACEACTIVE;    // Already open
  200. #endif
  201.  
  202.         // FALL THRU
  203.  
  204.     case OLEIVERB_PRIMARY:
  205.         if (lprcPosRect != NULL)
  206.             CopyRect(&pThis->m_rcPos, lprcPosRect);
  207.         else
  208.             memset(&pThis->m_rcPos, 0, sizeof(pThis->m_rcPos));
  209.         return pThis->OnActivateInPlace((iVerb != OLEIVERB_INPLACEACTIVATE), lpmsg);
  210.  
  211. #ifdef _AFXDLL
  212.     case OLEIVERB_OPEN:
  213.         return pThis->OnOpen(FALSE, lpmsg);     // Don't try in-place
  214. #endif
  215.  
  216.     case OLEIVERB_PROPERTIES:
  217.         return pThis->OnProperties(lpmsg, hwndParent, lprcPosRect) ?
  218.                 S_OK : E_FAIL;
  219.  
  220.     default:
  221.         // negative verbs not understood should return E_NOTIMPL
  222.         if (iVerb < 0)
  223.             return E_NOTIMPL;
  224.  
  225.         // positive verb not processed --
  226.         // according to OLE spec, primary verb should be executed
  227.         // instead.
  228.         if (SUCCEEDED(hr = DoVerb(OLEIVERB_PRIMARY, lpmsg, pActiveSite,
  229.                                 lindex, hwndParent, lprcPosRect)))
  230.             return OLEOBJ_S_INVALIDVERB;
  231.         else
  232.             return hr;
  233.     }
  234. }
  235.  
  236. BOOL COleControl::OnDoVerb(LONG iVerb, LPMSG lpMsg, HWND hWndParent,
  237.     LPCRECT lpRect)
  238. {
  239.     return DoOleVerb(iVerb, lpMsg, hWndParent, lpRect);
  240. }
  241.  
  242. STDMETHODIMP COleControl::XOleObject::EnumVerbs(LPENUMOLEVERB* ppenumOleVerb)
  243. {
  244.     METHOD_PROLOGUE_EX(COleControl, OleObject)
  245.     return pThis->OnEnumVerbs(ppenumOleVerb) ?
  246.         S_OK : OLEOBJ_E_NOVERBS;
  247. }
  248.  
  249. BOOL COleControl::OnEnumVerbs(LPENUMOLEVERB* ppenumOleVerb)
  250. {
  251.     return EnumOleVerbs(ppenumOleVerb);
  252. }
  253.  
  254. STDMETHODIMP COleControl::XOleObject::Update()
  255. {
  256.     return S_OK;
  257. }
  258.  
  259. STDMETHODIMP COleControl::XOleObject::IsUpToDate()
  260. {
  261.     return S_OK;
  262. }
  263.  
  264. STDMETHODIMP COleControl::XOleObject::GetUserClassID(CLSID* pClsid)
  265. {
  266.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  267.     return pThis->GetClassID(pClsid);
  268. }
  269.  
  270. STDMETHODIMP COleControl::XOleObject::GetUserType(DWORD, LPOLESTR* ppszUserType)
  271. {
  272.     METHOD_PROLOGUE_EX(COleControl, OleObject)
  273.     UNUSED(ppszUserType);   // not used in release builds
  274.     ASSERT_POINTER(ppszUserType, LPOLESTR);
  275.     TCHAR szUserType[256];
  276.     pThis->GetUserType(szUserType);
  277.     *ppszUserType = AfxAllocTaskOleString(szUserType);
  278.     return S_OK;
  279. }
  280.  
  281. void COleControl::GetUserType(LPTSTR pszUserType)
  282. {
  283.     ASSERT(pszUserType != NULL);
  284.     pszUserType[0] = '\0';
  285.  
  286.     TRY
  287.     {
  288.         AfxLoadString(GetUserTypeNameID(), pszUserType);
  289.     }
  290.     END_TRY
  291. }
  292.  
  293. STDMETHODIMP COleControl::XOleObject::SetExtent(DWORD dwDrawAspect, LPSIZEL lpsizel)
  294. {
  295.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  296.  
  297.     if (dwDrawAspect & DVASPECT_CONTENT)
  298.         return pThis->OnSetExtent(lpsizel) ? S_OK : E_FAIL;
  299.     else
  300.         return E_NOTIMPL;
  301. }
  302.  
  303. BOOL COleControl::OnSetExtent(LPSIZEL lpSizeL)
  304. {
  305.     if (m_bChangingExtent)  // Prevent infinite recursion!
  306.         return FALSE;
  307.  
  308.     m_bChangingExtent = TRUE;
  309.  
  310.     // Update the control's extent.
  311.     m_cxExtent = lpSizeL->cx;
  312.     m_cyExtent = lpSizeL->cy;
  313.  
  314.     // Mark the control dirty and force a repaint.
  315.     SetModifiedFlag();
  316.     InvalidateControl();
  317.  
  318.     SIZEL szlPixels;
  319.     _AfxXformSizeInHimetricToPixels(NULL, lpSizeL, &szlPixels);
  320.  
  321.     CRect rectNew(m_rcPos);
  322.     rectNew.right = rectNew.left + (int)szlPixels.cx;
  323.     rectNew.bottom = rectNew.top + (int)szlPixels.cy;
  324.  
  325.     if ((m_pInPlaceSite != NULL) && m_bInPlaceActive)
  326.     {
  327.         // If the control is in-place active, tell the container to resize.
  328.         m_pInPlaceSite->OnPosRectChange(&rectNew);
  329.     }
  330. #ifdef _AFXDLL
  331.     else if (m_bOpen)
  332.     {
  333.         // If the control is open, resize it.
  334.         ResizeOpenControl((int)szlPixels.cx, (int)szlPixels.cy);
  335.     }
  336. #endif
  337.     else
  338.     {
  339.         CopyRect(m_rcPos, rectNew);
  340.  
  341.         // Resize off-screen window, if any.
  342.         if (m_hWnd != NULL)
  343.             ::SetWindowPos(m_hWnd, NULL, 0, 0, (int)szlPixels.cx,
  344.                 (int)szlPixels.cy, SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE);
  345.     }
  346.  
  347.     m_bChangingExtent = FALSE;
  348.     return TRUE;
  349. }
  350.  
  351. STDMETHODIMP COleControl::XOleObject::GetExtent(DWORD dwDrawAspect,
  352.     LPSIZEL lpsizel)
  353. {
  354.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  355.  
  356.     if (dwDrawAspect & DVASPECT_CONTENT)
  357.     {
  358.         lpsizel->cx = pThis->m_cxExtent;
  359.         lpsizel->cy = pThis->m_cyExtent;
  360.         return S_OK;
  361.     }
  362.     return E_NOTIMPL;
  363. }
  364.  
  365. STDMETHODIMP COleControl::XOleObject::Advise(LPADVISESINK pAdvSink,
  366.     DWORD* pdwConnection)
  367. {
  368.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  369.  
  370.     // If no advise holder exists, create one.
  371.     // Then delegate this call to the advise holder.
  372.  
  373.     if (pThis->m_pOleAdviseHolder == NULL)
  374.     {
  375.         HRESULT hr;
  376.         if (FAILED(hr = CreateOleAdviseHolder(&pThis->m_pOleAdviseHolder)))
  377.             return hr;
  378.     }
  379.  
  380.     return pThis->m_pOleAdviseHolder->Advise(pAdvSink, pdwConnection);
  381. }
  382.  
  383. STDMETHODIMP COleControl::XOleObject::Unadvise(DWORD dwConnection)
  384. {
  385.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  386.  
  387.     if (pThis->m_pOleAdviseHolder != NULL)
  388.         return pThis->m_pOleAdviseHolder->Unadvise(dwConnection);
  389.  
  390.     return E_FAIL;
  391. }
  392.  
  393. STDMETHODIMP COleControl::XOleObject::EnumAdvise(LPENUMSTATDATA* ppenumAdvise)
  394. {
  395.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  396.  
  397.     if (pThis->m_pOleAdviseHolder != NULL)
  398.         return pThis->m_pOleAdviseHolder->EnumAdvise(ppenumAdvise);
  399.  
  400.     return E_FAIL;
  401. }
  402.  
  403. STDMETHODIMP COleControl::XOleObject::GetMiscStatus(DWORD dwAspect,
  404.     DWORD* pdwStatus)
  405. {
  406.     METHOD_PROLOGUE_EX_(COleControl, OleObject)
  407.     ASSERT_POINTER(pdwStatus, DWORD);
  408.  
  409.     if (dwAspect == DVASPECT_CONTENT)
  410.         *pdwStatus = pThis->GetMiscStatus();
  411.     else
  412.         *pdwStatus = 0;
  413.  
  414.     return S_OK;
  415. }
  416.  
  417. STDMETHODIMP COleControl::XOleObject::SetColorScheme(LPLOGPALETTE)
  418. {
  419.     return E_NOTIMPL;
  420. }
  421.  
  422. /////////////////////////////////////////////////////////////////////////////
  423. // Force any extra compiler-generated code into AFX_INIT_SEG
  424.  
  425. #ifdef AFX_INIT_SEG
  426. #pragma code_seg(AFX_INIT_SEG)
  427. #endif
  428.