home *** CD-ROM | disk | FTP | other *** search
/ ActiveX Programming Unleashed CD / AXU.iso / source / chap18 / doserver / bindipfw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-02  |  6.2 KB  |  216 lines

  1. // bindipfw.cpp : implementation of the Binder-aware DocObject
  2. //    in-place frame window 
  3. //
  4. // This is a part of the Microsoft Foundation Classes C++ library.
  5. // Copyright (C) 1992-1995 Microsoft Corporation
  6. // All rights reserved.
  7. //
  8. // This source code is only intended as a supplement to the
  9. // Microsoft Foundation Classes Reference and related
  10. // electronic documentation provided with the library.
  11. // See these sources for detailed information regarding the
  12. // Microsoft Foundation Classes product.
  13. //
  14.  
  15. #include "stdafx.h"
  16. #include <afxpriv.h>     // for AfxRepositionWindow
  17. #include "bindipfw.h"
  18. #include "binddoc.h"
  19. #include "mfcbind.h"
  20.  
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char BASED_CODE THIS_FILE[] = __FILE__;
  24. #endif
  25.  
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CDocObjectIPFrameWnd
  28.  
  29. IMPLEMENT_DYNCREATE(CDocObjectIPFrameWnd, COleIPFrameWnd)
  30.  
  31. BEGIN_MESSAGE_MAP(CDocObjectIPFrameWnd, COleIPFrameWnd)
  32.     //{{AFX_MSG_MAP(CDocObjectIPFrameWnd)
  33.         // NOTE - the ClassWizard will add and remove mapping macros here.
  34.     //}}AFX_MSG_MAP
  35. END_MESSAGE_MAP()
  36.  
  37. CDocObjectIPFrameWnd::CDocObjectIPFrameWnd()
  38. {
  39.     m_hMenuHelpPopup = NULL;
  40. }
  41.  
  42. CDocObjectIPFrameWnd::~CDocObjectIPFrameWnd()
  43. {
  44. }
  45.  
  46. void CDocObjectIPFrameWnd::OnRequestPositionChange(LPCRECT lpRect)
  47. {
  48.     CDocObjectServerDoc* pDoc = (CDocObjectServerDoc*)GetActiveDocument();
  49.     ASSERT_VALID(pDoc);
  50.     ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CDocObjectServerDoc)));
  51.  
  52.     // DocObjects don't need to generate OnPosRectChange calls, so we 
  53.     // just return if this is a DocObject.
  54.     if (pDoc->IsDocObject())
  55.         return;
  56.  
  57.     // The default behavior is to not affect the extent during the
  58.     //  call to RequestPositionChange.  This results in consistent
  59.     //  scaling behavior.
  60.     pDoc->RequestPositionChange(lpRect);
  61. }
  62.  
  63. void CDocObjectIPFrameWnd::RecalcLayout(BOOL /*bNotify*/)
  64. {
  65.     ASSERT_VALID(this);
  66.  
  67.     CDocObjectServerDoc* pDoc = (CDocObjectServerDoc*)GetActiveDocument();
  68.     if (pDoc)
  69.     {
  70.         ASSERT_VALID(pDoc);
  71.         ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CDocObjectServerDoc)));
  72.     }
  73.  
  74.     // Normal in-place objects put scrollbars on the outside,
  75.     //    DocObjects put them inside
  76.     UINT nAdjustType = (pDoc && pDoc->IsDocObject())
  77.                                 ? CWnd::adjustBorder : CWnd::adjustOutside;
  78.  
  79.     // better have a parent window (only used for inplace)
  80.     CWnd* pParentWnd = GetParent();
  81.     ASSERT_VALID(pParentWnd);
  82.  
  83.     // first call reposition bars with arbitarily large rect just to
  84.     //  see how much space the bars will take up
  85.     CRect rectBig(0, 0, INT_MAX/2, INT_MAX/2);
  86.     CRect rectLeft;
  87.     RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST, reposQuery,
  88.         &rectLeft, &rectBig);
  89.  
  90.     // grow the rect by the size of the control bars
  91.     CRect rect = m_rectPos;
  92.     rect.left -= rectLeft.left;
  93.     rect.top -= rectLeft.top;
  94.     rect.right += INT_MAX/2 - rectLeft.right;
  95.     rect.bottom += INT_MAX/2 - rectLeft.bottom;
  96.  
  97.     // see how much extra space for non-client areas (such as scrollbars)
  98.     //  that the view needs.
  99.     CWnd* pLeftOver = GetDlgItem(AFX_IDW_PANE_FIRST);
  100.     if (pLeftOver != NULL)
  101.     {
  102.         rectBig = m_rectPos;
  103.         pLeftOver->CalcWindowRect(&rectBig, nAdjustType);
  104.         rect.left -= m_rectPos.left - rectBig.left;
  105.         rect.top -= m_rectPos.top - rectBig.top;
  106.         rect.right += rectBig.right - m_rectPos.right;
  107.         rect.bottom += rectBig.bottom - m_rectPos.bottom;
  108.     }
  109.  
  110.     // adjust for non-client area on the frame window
  111.     CalcWindowRect(&rect, nAdjustType);
  112.  
  113.     // the frame window must be clipped to the visible part in the container
  114.     CRect rectVis;
  115.     rectVis.IntersectRect(&rect, &m_rectClip);
  116.  
  117.     // move the window
  118.     AfxRepositionWindow(NULL, m_hWnd, &rectVis);
  119.  
  120.     // now resize the control bars relative to the (now moved) frame
  121.     pParentWnd->ClientToScreen(&rect);
  122.     ScreenToClient(&rect);
  123.     RepositionBars(0, 0xffff, AFX_IDW_PANE_FIRST,
  124.         CWnd::reposDefault, NULL, &rect);
  125. }
  126.  
  127. BOOL CDocObjectIPFrameWnd::BuildSharedMenu()
  128. {
  129.     HMENU hMenu = GetInPlaceMenu();
  130.  
  131.     // create shared menu
  132.     ASSERT(m_hSharedMenu == NULL);
  133.     if ((m_hSharedMenu = ::CreateMenu()) == NULL)
  134.         return FALSE;
  135.  
  136.     // start out by getting menu from container
  137.     memset(&m_menuWidths, 0, sizeof m_menuWidths);
  138.     if (m_lpFrame->InsertMenus(m_hSharedMenu, &m_menuWidths) != NOERROR)
  139.     {
  140.         ::DestroyMenu(m_hSharedMenu);
  141.         m_hSharedMenu = NULL;
  142.         return FALSE;
  143.     }
  144.  
  145.     // container shouldn't touch these
  146.     ASSERT(m_menuWidths.width[1] == 0);
  147.     ASSERT(m_menuWidths.width[3] == 0);
  148.  
  149.     // container shouldn't touch this unless we're working with a DocObject
  150.     CDocObjectServerDoc* pDoc = (CDocObjectServerDoc*)GetActiveDocument();
  151.     ASSERT_VALID(pDoc);
  152.     ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CDocObjectServerDoc)));
  153.     if (!pDoc->IsDocObject())
  154.         ASSERT(m_menuWidths.width[5] == 0);
  155.  
  156.     // only copy the popups if there is a menu loaded
  157.     if (hMenu == NULL)
  158.         return TRUE;
  159.  
  160.     // insert our menu popups amongst the container menus
  161.     m_hMenuHelpPopup = MfcBinderMergeMenus(CMenu::FromHandle(m_hSharedMenu),
  162.                                  CMenu::FromHandle(hMenu), &m_menuWidths.width[0], 1);
  163.  
  164.     // finally create the special OLE menu descriptor
  165.     m_hOleMenu = ::OleCreateMenuDescriptor(m_hSharedMenu, &m_menuWidths);
  166.  
  167.     return m_hOleMenu != NULL;
  168. }
  169.  
  170. void CDocObjectIPFrameWnd::DestroySharedMenu()
  171. {
  172.     if (m_hSharedMenu == NULL)
  173.     {
  174.         ASSERT(m_hOleMenu == NULL);
  175.         ASSERT(m_hMenuHelpPopup == NULL);
  176.         return;
  177.     }
  178.  
  179.     // get in-place menu to be unmerged (must be same as during activation)
  180.     HMENU hMenu = GetInPlaceMenu();
  181.     if (hMenu == NULL)
  182.         return;
  183.  
  184.     // remove our menu popups from the shared menu
  185.     MfcBinderUnmergeMenus(CMenu::FromHandle(m_hSharedMenu), 
  186.                               CMenu::FromHandle(hMenu),
  187.                               CMenu::FromHandle(m_hMenuHelpPopup));
  188.  
  189.     // allow container to remove its items from the menu
  190.     ASSERT(m_lpFrame != NULL);
  191.     VERIFY(m_lpFrame->RemoveMenus(m_hSharedMenu) == NOERROR);
  192.  
  193.     // now destroy the menu
  194.     ::DestroyMenu(m_hSharedMenu);
  195.     m_hSharedMenu = NULL;
  196.     if (m_hOleMenu != NULL)
  197.     {
  198.         VERIFY(::OleDestroyMenuDescriptor(m_hOleMenu) == NOERROR);
  199.         m_hOleMenu = NULL;
  200.     }
  201.     m_hMenuHelpPopup = NULL;
  202. }
  203.  
  204. #ifdef _DEBUG
  205. void CDocObjectIPFrameWnd::AssertValid() const
  206. {
  207.     COleIPFrameWnd::AssertValid();
  208. }
  209.  
  210. void CDocObjectIPFrameWnd::Dump(CDumpContext& dc) const
  211. {
  212.     COleIPFrameWnd::Dump(dc);
  213. }
  214. #endif //_DEBUG
  215.  
  216.