home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / activexcontrol / basectl / todosvr / cdocobj.cpp next >
Encoding:
C/C++ Source or Header  |  1997-10-05  |  12.3 KB  |  382 lines

  1. //=--------------------------------------------------------------------------=
  2. // CDocObj.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995 - 1997 Microsoft Corporation.  All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // implementation of CDocumentObject, which provides basic DocObject server
  13. // support. This file contains overrides of basic inplace editing support.
  14. // See iodoc.cpp and iodocvw.cpp for implementations of required interfaces
  15. // for DocObject server support.
  16. // 
  17. #include <IPServer.H>
  18. #include <Globals.H>
  19. #include "CDocObj.H"
  20.  
  21. // for ASSERT and FAIL
  22. //
  23. SZTHISFILE
  24.  
  25. //=--------------------------------------------------------------------------=
  26. // CDocumentObject::CDocumentObject
  27. //=--------------------------------------------------------------------------=
  28. //
  29. // Parameters:
  30. //    IUnknown*        - [in]
  31. //    int              - [in]
  32. //    void*            - [in]
  33. //
  34. // Notes:
  35. //
  36. CDocumentObject::CDocumentObject(IUnknown* pUnkOuter, int iPrimaryDispatch, 
  37.                                  void* pMainInterface)
  38.    : BASECLASS(pUnkOuter, iPrimaryDispatch, pMainInterface)
  39. {
  40.     m_fDocObj   = FALSE;
  41.     m_pDocSite  = NULL;
  42.     m_pViewSite = NULL;
  43. }
  44.  
  45. //=--------------------------------------------------------------------------=
  46. // CDocumentObject::~CDocumentObject
  47. //=--------------------------------------------------------------------------=
  48. //
  49. // Notes:
  50. //
  51. CDocumentObject::~CDocumentObject()
  52. {
  53.     ASSERT(m_pDocSite == NULL, "CDocumentObject::m_pDocSite not properly released");
  54.     ASSERT(m_pViewSite == NULL, "CDocumentObject::m_pViewSite not properly released");
  55. }
  56.  
  57.  
  58. //=--------------------------------------------------------------------------=
  59. // CDocumentObject::InternalQueryInterface
  60. //=--------------------------------------------------------------------------=
  61. // qi for things only we support.
  62. //
  63. // Parameters:
  64. // Parameters:
  65. //    REFIID       - [in]  interface they want
  66. //    void**       - [out] where they want to put the resulting object ptr.
  67. //
  68. // Output:
  69. //    HRESULT      - S_OK, E_NOINTERFACE
  70. //
  71. // Notes:
  72. //
  73. HRESULT CDocumentObject::InternalQueryInterface(REFIID riid, void** ppvObjOut)
  74. {
  75.     // Check for interfaces we implement
  76.     if (DO_GUIDS_MATCH(riid, IID_IOleDocument)) 
  77.         *ppvObjOut = (void *)(IOleDocument*)this; 
  78.     else if (DO_GUIDS_MATCH(riid, IID_IOleDocumentView))
  79.         *ppvObjOut = (void *)(IOleDocumentView*)this; 
  80.     else
  81.         // delegate to super-class for automation interfaces, etc ...
  82.         //
  83.         return BASECLASS::InternalQueryInterface(riid, ppvObjOut);
  84.  
  85.     // we like the interface, so addref and return
  86.     //
  87.     ((IUnknown *)(*ppvObjOut))->AddRef();
  88.     return S_OK;
  89. }
  90.  
  91. //=--------------------------------------------------------------------------=
  92. // CDocumentObject::SetClientSite
  93. //=--------------------------------------------------------------------------=
  94. // determines whether object can and should activate as a DocObject
  95. //
  96. // Parameters:
  97. //    IOleClientSite*        - [in] pointer to client site.
  98. //
  99. // Output:
  100. //    HRESULT                - S_OK
  101. //
  102. // Notes:
  103. //
  104. HRESULT CDocumentObject::SetClientSite(IOleClientSite* pClientSite)
  105. {
  106.     TRACE("\nCDocumentObject::SetClientSite");
  107.  
  108.     // perform regular SetClientSite processing
  109.     HRESULT hr = BASECLASS::SetClientSite(pClientSite);
  110.     if (FAILED(hr))
  111.         return hr;
  112.  
  113.     // If we have a document site pointer, 
  114.     //    release it and set docobj flag FALSE
  115.     RELEASE_OBJECT(m_pDocSite);
  116.     m_fDocObj = FALSE;
  117.  
  118.     // If we got a client site,
  119.     if (pClientSite != NULL)
  120.     {
  121.         // If the client site supports IID_IOleDocumentSite,
  122.         //    save the document site pointer
  123.         //    and set docobj flag TRUE
  124.         hr = pClientSite->QueryInterface(IID_IOleDocumentSite, 
  125.                                          (void**)&m_pDocSite);
  126.         if (SUCCEEDED(hr))
  127.             m_fDocObj = TRUE;
  128.     }
  129.     return S_OK;
  130. }
  131.  
  132. //=--------------------------------------------------------------------------=
  133. // CDocumentObject::DoVerb    [IOleObject]
  134. //=--------------------------------------------------------------------------=
  135. // Requests an object to perform an action in response to an end-user's
  136. // action.
  137. //
  138. // Parameters:
  139. //    LONG             - [in]  verb to be performed
  140. //    LPMSG            - [in]  event that invoked the verb
  141. //    IOleClientSite * - [in]  the controls active client site
  142. //    LONG             - [in]  reserved
  143. //    HWND             - [in]  handle of window containing the object.
  144. //    LPCRECT          - [in]  pointer to objects's display rectangle
  145. //
  146. // Output:
  147. //    HRESULT          - S_OK, OLE_E_NOTINPLACEACTIVE, OLE_E_CANT_BINDTOSOURCE,
  148. //                       DV_E_LINK, OLEOBJ_S_CANNOT_DOVERB_NOW, OLEOBJ_S_INVALIDHWND,
  149. //                       OLEOBJ_E_NOVERBS, OLEOBJ_S_INVALIDVERB, MK_E_CONNECT,
  150. //                       OLE_CLASSDIFF, E_NOTIMPL
  151. //
  152. // Notes:
  153. //
  154. STDMETHODIMP CDocumentObject::DoVerb
  155. (
  156.     LONG            lVerb,
  157.     LPMSG           pMsg,
  158.     IOleClientSite *pActiveSite,
  159.     LONG            lIndex,
  160.     HWND            hwndParent,
  161.     LPCRECT         prcPosRect
  162. )
  163. {
  164.     TRACE("\nCDocumentObject::DoVerb");
  165.  
  166.     // if we're acting as a docobj
  167.     if (m_fDocObj)
  168.     {
  169.         switch (lVerb)
  170.         {
  171.         // call IOleDocumentSite::ActivateMe for Show, Open, InPlaceActivate and UIActivate Verbs
  172.         case OLEIVERB_SHOW:
  173.         case OLEIVERB_UIACTIVATE:
  174.         case OLEIVERB_OPEN:
  175.         case OLEIVERB_INPLACEACTIVATE:
  176.             return m_pDocSite->ActivateMe(NULL);
  177.  
  178.         // return E_INVALIDARG for Hide Verb
  179.         case OLEIVERB_HIDE:
  180.             return E_INVALIDARG;
  181.  
  182.         // otherwise, just do normal processing
  183.         default:
  184.             break;
  185.         }
  186.     }
  187.     
  188.     // if we're not acting as a docobj, just do normal processing    
  189.     return BASECLASS::DoVerb(lVerb, pMsg, pActiveSite, lIndex,
  190.                              hwndParent, prcPosRect);
  191.  
  192. }
  193.  
  194. //=--------------------------------------------------------------------------=
  195. // CDocumentObject::SetExtent    [IOleObject]
  196. //=--------------------------------------------------------------------------=
  197. // Informs the control of how much display space its container has assigned it.
  198. //
  199. // Parameters:
  200. //    DWORD            - [in] which form or 'aspect'  is to be displayed.
  201. //    SIZEL *          - [in] size limit for the control.
  202. //
  203. // Output:
  204. //    HRESULT          - S_OK, E_FAIL, OLE_E_NOTRUNNING
  205. //
  206. // Notes:
  207. //
  208. STDMETHODIMP CDocumentObject::SetExtent(DWORD dwDrawAspect, SIZEL *psizel)
  209. {
  210.     TRACE("\nCDocumentObject::SetExtent");
  211.  
  212.     // ignore SetExtent calls if we are a docobj
  213.     if (m_fDocObj)
  214.         return S_OK;
  215.  
  216.     // otherwise do normal processing
  217.     return BASECLASS::SetExtent(dwDrawAspect, psizel);
  218. }
  219.  
  220. //=--------------------------------------------------------------------------=
  221. // CDocumentObject::Unadvise    [IOleObject]
  222. //=--------------------------------------------------------------------------=
  223. // Deletes a previously established advisory connection.
  224. //
  225. // Parameters:
  226. //    DWORD         - [in] connection cookie
  227. //
  228. // Output:
  229. //    HRESULT       - S_OK, E_FAIL, OLE_E_NOCONNECTION
  230. //
  231. // Notes:
  232. //      This override is included to work around a problem observed 
  233. //      interacting with Office Binder. When activated as a docobj, 
  234. //      IOleObject::Advise is not getting called. However, when deactivated, 
  235. //      IOleObject::Unadvise *is* called. Since no advise holder was ever 
  236. //      created, the base class method asserts.
  237. // 
  238. //      All this function does is prevent the assert from getting hit.
  239. //
  240. STDMETHODIMP CDocumentObject::Unadvise(DWORD dwConnection)
  241. {
  242.     if (!dwConnection) {
  243.         TRACE("\nSomebody called Unadvise on IOleObject without calling Advise!");
  244.         return OLE_E_NOCONNECTION;
  245.     }
  246.  
  247.     return BASECLASS::Unadvise(dwConnection);
  248. }
  249.  
  250.  
  251. //=--------------------------------------------------------------------------=
  252. // CDocumentObject::ActivateAsDocObject
  253. //=--------------------------------------------------------------------------=
  254. // activates a document object, and depending on the verb, optionally 
  255. // ui activates it as well.
  256. //
  257. // Parameters:
  258. //    LONG         - [in] the verb that caused us to activate
  259. //
  260. // Output:
  261. //    HRESULT      - S_OK, E_UNEXPECTED
  262. //
  263. // Notes:
  264. //      This implementation is based on COleControl::InPlaceActivate.
  265. //      COleControl::InPlaceActivate is called when a CDocumentObject
  266. //      is being used as a control or normal embedding, not this function.
  267. //
  268. HRESULT CDocumentObject::ActivateAsDocObject(LONG lVerb)
  269. {
  270.     TRACE("\nEntering CDocumentObject::ActivateAsDocObject");
  271.  
  272.     HRESULT hr = S_OK;
  273.  
  274.     // if our view site has not been set, report an error
  275.     if (!m_pViewSite)
  276.     {
  277.         hr = E_UNEXPECTED;
  278.         goto LeaveMethod;
  279.     }
  280.  
  281.     // if we don't have a client site, then there's not much to do.
  282.     //
  283.     if (!m_pClientSite)
  284.         goto LeaveMethod;
  285.  
  286.  
  287.     // get an InPlaceSite pointer
  288.     //
  289.     if (!m_pInPlaceSite) {
  290.         hr = m_pClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&m_pInPlaceSite);
  291.         if (FAILED(hr))
  292.             goto LeaveMethod;
  293.     }
  294.  
  295.     // if we're not already active, go and do it.
  296.     //
  297.     if (!m_fInPlaceActive) {
  298.         OLEINPLACEFRAMEINFO InPlaceFrameInfo;
  299.         RECT rcPos, rcClip;
  300.  
  301.         // ask for permission and notify the container we're going active.
  302.         //
  303.         hr = m_pInPlaceSite->CanInPlaceActivate();
  304.         if (hr != S_OK) 
  305.         {
  306.             if (FAILED(hr))
  307.                 hr = E_FAIL;
  308.             goto LeaveMethod;
  309.         }
  310.  
  311.         hr = m_pInPlaceSite->OnInPlaceActivate();
  312.         if (FAILED(hr))
  313.             goto LeaveMethod;
  314.  
  315.         m_fInPlaceActive = TRUE;
  316.         InPlaceFrameInfo.cb = sizeof(OLEINPLACEFRAMEINFO);
  317.  
  318.         // get our parent window
  319.         //
  320.         hr = m_pInPlaceSite->GetWindow(&m_hwndParent);
  321.         if (!FAILED(hr))
  322.             // get our display and clipping rectangles
  323.             //
  324.             hr = m_pInPlaceSite->GetWindowContext(&m_pInPlaceFrame, &m_pInPlaceUIWindow,
  325.                                                   &rcPos, &rcClip, &InPlaceFrameInfo);
  326.         if (FAILED(hr)) {
  327.             InPlaceDeactivate();
  328.             goto LeaveMethod;
  329.         }
  330.  
  331.         // make sure we'll display ourselves in the correct location with the correct size
  332.         //    SetObjectRects expects object extent to be set, but
  333.       //    DocObjects ignore SetExtent. Set m_Size to the size 
  334.       //    specified for the view.
  335.       m_Size.cx = rcPos.right - rcPos.left;
  336.       m_Size.cy = rcPos.bottom - rcPos.top;
  337.         SetObjectRects(&rcPos, &rcClip);
  338.  
  339.         // create the window, and display it. 
  340.         //
  341.         CreateInPlaceWindow(rcPos.left, rcPos.top, TRUE);
  342.     }
  343.  
  344.     if (!m_fInPlaceVisible)
  345.         SetInPlaceVisible(TRUE);
  346.  
  347.     // if we weren't asked to UIActivate, then we're done.
  348.     //
  349.     if (lVerb != OLEIVERB_PRIMARY && lVerb != OLEIVERB_UIACTIVATE)
  350.         goto LeaveMethod;
  351.  
  352.     // if we're not already UI active, do sow now.
  353.     //
  354.     if (!m_fUIActive) {
  355.         m_fUIActive = TRUE;
  356.  
  357.         // inform the container of our intent
  358.         //
  359.         m_pInPlaceSite->OnUIActivate();
  360.  
  361.         // take the focus  [which is what UI Activation is all about !]
  362.         //
  363.         SetFocus(TRUE);
  364.  
  365.         // set up the active object [us] with the container.
  366.         //
  367.         m_pInPlaceFrame->SetActiveObject((IOleInPlaceActiveObject *)this, NULL);
  368.         if (m_pInPlaceUIWindow)
  369.             m_pInPlaceUIWindow->SetActiveObject((IOleInPlaceActiveObject *)this, NULL);
  370.  
  371.         // we have to explicitly say we don't wany any border space.
  372.         //
  373.         m_pInPlaceFrame->SetBorderSpace(NULL);
  374.         if (m_pInPlaceUIWindow)
  375.             m_pInPlaceUIWindow->SetBorderSpace(NULL);
  376.     }
  377.  
  378. LeaveMethod:
  379.     TRACE("\nLeaving CDocumentObject::ActivateAsDocObject");
  380.     return hr;
  381. }
  382.