home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / BARDOCK.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-30  |  24.8 KB  |  957 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 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 AFX_CORE3_SEG
  14. #pragma code_seg(AFX_CORE3_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. // CDockBar
  26.  
  27. BEGIN_MESSAGE_MAP(CDockBar, CControlBar)
  28.     //{{AFX_MSG_MAP(CDockBar)
  29.     ON_WM_NCCALCSIZE()
  30.     ON_WM_NCPAINT()
  31.     ON_WM_WINDOWPOSCHANGING()
  32.     ON_WM_PAINT()
  33.     ON_MESSAGE(WM_SIZEPARENT, OnSizeParent)
  34.     //}}AFX_MSG_MAP
  35. END_MESSAGE_MAP()
  36.  
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CDockBar construction
  39.  
  40. CDockBar::CDockBar(BOOL bFloating)
  41. {
  42.     m_bFloating = bFloating;
  43.     m_bAutoDelete = TRUE;
  44.     m_arrBars.Add(NULL);
  45.     m_bLayoutQuery = FALSE;
  46.     m_rectLayout.SetRectEmpty();
  47.  
  48.     // assume no margins
  49.     m_cxLeftBorder = m_cxRightBorder = m_cyBottomBorder = m_cyTopBorder = 0;
  50. }
  51.  
  52. CDockBar::~CDockBar()
  53. {
  54.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  55.     {
  56.         CControlBar* pBar = GetDockedControlBar(i);
  57.         if (pBar != NULL && pBar->m_pDockBar == this)
  58.             pBar->m_pDockBar = NULL;
  59.     }
  60. }
  61.  
  62. BOOL CDockBar::Create(CWnd* pParentWnd, DWORD dwStyle, UINT nID)
  63. {
  64.     ASSERT(pParentWnd != NULL);
  65.     ASSERT_KINDOF(CFrameWnd, pParentWnd);
  66.  
  67.     // save the style
  68.     m_dwStyle = (UINT)dwStyle;
  69.  
  70.     if (!AfxDeferRegisterClass(AFX_WNDCONTROLBAR_REG))
  71.         return FALSE;
  72.  
  73.     // create the HWND
  74.     CRect rect;
  75.     rect.SetRectEmpty();
  76.     if (!CWnd::Create(_afxWndControlBar, NULL, dwStyle, rect, pParentWnd, nID))
  77.         return FALSE;
  78.  
  79.     // Note: Parent must resize itself for control bar to be resized
  80.  
  81.     return TRUE;
  82. }
  83.  
  84. #ifdef _MAC
  85. BOOL CDockBar::PreCreateWindow(CREATESTRUCT& cs)
  86. {
  87.     cs.dwExStyle |= WS_EX_INVISIBLE;
  88.     return CControlBar::PreCreateWindow(cs);
  89. }
  90. #endif
  91.  
  92. BOOL CDockBar::IsDockBar() const
  93. {
  94.     return TRUE;
  95. }
  96.  
  97. int CDockBar::GetDockedCount() const
  98. {
  99.     int nCount = 0;
  100.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  101.     {
  102.         if (GetDockedControlBar(i) != NULL)
  103.             nCount++;
  104.     }
  105.     return nCount;
  106. }
  107.  
  108. int CDockBar::GetDockedVisibleCount() const
  109. {
  110.     int nCount = 0;
  111.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  112.     {
  113.         CControlBar* pBar = STATIC_DOWNCAST(CControlBar, (CObject*)GetDockedControlBar(i));
  114.         if (pBar != NULL && pBar->IsVisible())
  115.             nCount++;
  116.     }
  117.     return nCount;
  118. }
  119.  
  120. /////////////////////////////////////////////////////////////////////////////
  121. // CDockBar operations
  122.  
  123. void CDockBar::DockControlBar(CControlBar* pBar, LPCRECT lpRect)
  124. {
  125.     ASSERT_VALID(this);
  126.     ASSERT_VALID(pBar);
  127.     ASSERT_KINDOF(CControlBar, pBar);
  128.  
  129.     CRect rectBar;
  130.     pBar->GetWindowRect(&rectBar);
  131.     if (pBar->m_pDockBar == this && (lpRect == NULL || rectBar == *lpRect))
  132.     {
  133.         // already docked and no change in position
  134.         return;
  135.     }
  136.  
  137.     // set CBRS_FLOAT_MULTI style if docking bar has it
  138.     if (m_bFloating && (pBar->m_dwDockStyle & CBRS_FLOAT_MULTI))
  139.         m_dwStyle |= CBRS_FLOAT_MULTI;
  140.  
  141.     m_dwStyle &= ~(CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  142.     m_dwStyle |= pBar->m_dwStyle & (CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  143.  
  144.     if (!(m_dwStyle & CBRS_FLOAT_MULTI))
  145.     {
  146.         TCHAR szTitle[_MAX_PATH];
  147.         pBar->GetWindowText(szTitle, _countof(szTitle));
  148.         AfxSetWindowText(m_hWnd, szTitle);
  149.     }
  150.  
  151.     // align correctly and turn on all borders
  152.     DWORD dwStyle = pBar->GetBarStyle();
  153.     dwStyle &= ~(CBRS_ALIGN_ANY);
  154.     dwStyle |=  (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
  155.  
  156.     if (m_bFloating)
  157.         dwStyle |= CBRS_FLOATING;
  158.     else
  159.         dwStyle &= ~CBRS_FLOATING;
  160.  
  161.     pBar->SetBarStyle(dwStyle);
  162.  
  163.     // hide first if changing to a new docking site to avoid flashing
  164.     BOOL bShow = FALSE;
  165.     if (pBar->m_pDockBar != this && pBar->IsWindowVisible())
  166.     {
  167.         pBar->SetWindowPos(NULL, 0, 0, 0, 0,
  168.             SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_HIDEWINDOW);
  169.         bShow = TRUE;
  170.     }
  171.  
  172.     int nPos = -1;
  173.     if (lpRect != NULL)
  174.     {
  175.         // insert into appropriate row
  176.         CRect rect(lpRect);
  177.         ScreenToClient(&rect);
  178.         CPoint ptMid(rect.left + rect.Width()/2, rect.top + rect.Height()/2);
  179.         nPos = Insert(pBar, rect, ptMid);
  180.  
  181.         // position at requested position
  182.         pBar->SetWindowPos(NULL, rect.left, rect.top, rect.Width(),
  183.             rect.Height(), SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  184.     }
  185.     else
  186.     {
  187.         // always add on current row, then create new one
  188.         m_arrBars.Add(pBar);
  189.         m_arrBars.Add(NULL);
  190.  
  191.         // align off the edge initially
  192.         pBar->SetWindowPos(NULL, -afxData.cxBorder2, -afxData.cyBorder2, 0, 0,
  193.             SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  194.     }
  195.  
  196.     // attach it to the docking site
  197.     if (pBar->GetParent() != this)
  198.         pBar->SetParent(this);
  199.     if (pBar->m_pDockBar == this)
  200.         pBar->m_pDockBar->RemoveControlBar(pBar, nPos);
  201.     else if (pBar->m_pDockBar != NULL)
  202.         pBar->m_pDockBar->RemoveControlBar(pBar, -1, m_bFloating && !pBar->m_pDockBar->m_bFloating);
  203.     pBar->m_pDockBar = this;
  204.  
  205.     if (bShow)
  206.     {
  207.         ASSERT(!pBar->IsWindowVisible());
  208.         pBar->SetWindowPos(NULL, 0, 0, 0, 0,
  209.             SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_SHOWWINDOW);
  210.     }
  211.  
  212.     // remove any place holder for pBar in this dockbar
  213.     RemovePlaceHolder(pBar);
  214.  
  215.     // get parent frame for recalc layout
  216.     CFrameWnd* pFrameWnd = GetDockingFrame();
  217.     pFrameWnd->DelayRecalcLayout();
  218. }
  219.  
  220. void CDockBar::ReDockControlBar(CControlBar* pBar, LPCRECT lpRect)
  221. {
  222.     ASSERT_VALID(this);
  223.     ASSERT_VALID(pBar);
  224.     ASSERT_KINDOF(CControlBar, pBar);
  225.     ASSERT(pBar->m_pDockBar != this); // can't redock here if alredy docked here
  226.  
  227.     CRect rectBar;
  228.     pBar->GetWindowRect(&rectBar);
  229.     if (pBar->m_pDockBar == this && (lpRect == NULL || rectBar == *lpRect))
  230.     {
  231.         // already docked and no change in position
  232.         return;
  233.     }
  234.  
  235.     // set CBRS_FLOAT_MULTI style if docking bar has it
  236.     if (m_bFloating && (pBar->m_dwDockStyle & CBRS_FLOAT_MULTI))
  237.         m_dwStyle |= CBRS_FLOAT_MULTI;
  238.  
  239.     m_dwStyle &= ~(CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  240.     m_dwStyle |= pBar->m_dwStyle & (CBRS_SIZE_FIXED | CBRS_SIZE_DYNAMIC);
  241.  
  242.     if (!(m_dwStyle & CBRS_FLOAT_MULTI))
  243.     {
  244.         TCHAR szTitle[_MAX_PATH];
  245.         pBar->GetWindowText(szTitle, _countof(szTitle));
  246.         AfxSetWindowText(m_hWnd, szTitle);
  247.     }
  248.  
  249.     // align correctly and turn on all borders
  250.     DWORD dwStyle = pBar->GetBarStyle();
  251.     dwStyle &= ~(CBRS_ALIGN_ANY);
  252.     dwStyle |=  (m_dwStyle & CBRS_ALIGN_ANY) | CBRS_BORDER_ANY;
  253.  
  254.     if (m_bFloating)
  255.         dwStyle |= CBRS_FLOATING;
  256.     else
  257.         dwStyle &= ~CBRS_FLOATING;
  258.  
  259.     pBar->SetBarStyle(dwStyle);
  260.  
  261.     int nPos = FindBar((CControlBar*)_AfxGetDlgCtrlID(pBar->m_hWnd));
  262.     if (nPos > 0)
  263.         m_arrBars[nPos] = pBar;
  264.  
  265.     if (lpRect != NULL)
  266.     {
  267.         CRect rect(lpRect);
  268.         ScreenToClient(&rect);
  269.  
  270.         if (nPos < 1)
  271.         {
  272.             CPoint ptMid(rect.left + rect.Width()/2, rect.top + rect.Height()/2);
  273.             nPos = Insert(pBar, rect, ptMid);
  274.         }
  275.  
  276.         // position at requested position
  277.         pBar->SetWindowPos(NULL, rect.left, rect.top, rect.Width(),
  278.             rect.Height(), SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  279.     }
  280.     else
  281.     {
  282.         if (nPos < 1)
  283.         {
  284.             // always add on current row, then create new one
  285.             m_arrBars.Add(pBar);
  286.             m_arrBars.Add(NULL);
  287.         }
  288.  
  289.         // align off the edge initially
  290.         pBar->SetWindowPos(NULL, -afxData.cxBorder2, -afxData.cyBorder2, 0, 0,
  291.             SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCOPYBITS);
  292.     }
  293.  
  294.     // attach it to the docking site
  295.     if (pBar->GetParent() != this)
  296.         pBar->SetParent(this);
  297.     if (pBar->m_pDockBar != NULL)
  298.         pBar->m_pDockBar->RemoveControlBar(pBar);
  299.     pBar->m_pDockBar = this;
  300.  
  301.     // get parent frame for recalc layout
  302.     CFrameWnd* pFrameWnd = GetDockingFrame();
  303.     pFrameWnd->DelayRecalcLayout();
  304. }
  305.  
  306. void CDockBar::RemovePlaceHolder(CControlBar* pBar)
  307. {
  308.     // remove remembered docking position
  309.     int nOldPos = FindBar((CControlBar*)_AfxGetDlgCtrlID(pBar->m_hWnd));
  310.     if (nOldPos > 0)
  311.     {
  312.         m_arrBars.RemoveAt(nOldPos);
  313.  
  314.         // remove section indicator (NULL) if nothing else in section
  315.         if (m_arrBars[nOldPos-1] == NULL && m_arrBars[nOldPos] == NULL)
  316.             m_arrBars.RemoveAt(nOldPos);
  317.     }
  318. }
  319.  
  320. BOOL CDockBar::RemoveControlBar(CControlBar* pBar, int nPosExclude, BOOL bAddPlaceHolder)
  321. {
  322.     ASSERT_VALID(this);
  323.     ASSERT(pBar != NULL);
  324.     int nPos = FindBar(pBar, nPosExclude);
  325.     ASSERT(nPos > 0);
  326.  
  327.     if (bAddPlaceHolder)
  328.     {
  329.         m_arrBars[nPos] = (void*)_AfxGetDlgCtrlID(pBar->m_hWnd);
  330.  
  331.         // check for already existing place holder
  332.         int nPosOld = FindBar((CControlBar*)m_arrBars[nPos], nPos);
  333.         if (nPosOld > 0)
  334.         {
  335.             m_arrBars.RemoveAt(nPos);
  336.  
  337.             // remove section indicator (NULL) if nothing else in section
  338.             if (m_arrBars[nPos-1] == NULL && m_arrBars[nPos] == NULL)
  339.                 m_arrBars.RemoveAt(nPos);
  340.         }
  341.     }
  342.     else
  343.     {
  344.         m_arrBars.RemoveAt(nPos);
  345.         if (m_arrBars[nPos-1] == NULL && m_arrBars[nPos] == NULL)
  346.             m_arrBars.RemoveAt(nPos);
  347.  
  348.         // Remove any pre-existing place holders.
  349.         RemovePlaceHolder(pBar);
  350.     }
  351.  
  352.     // don't do anything more in the shutdown case!
  353.     if (pBar->m_pDockContext == NULL)
  354.         return FALSE;
  355.  
  356.     // get parent frame for recalc layout/frame destroy
  357.     CFrameWnd* pFrameWnd = GetDockingFrame();
  358.     if (m_bFloating && GetDockedVisibleCount() == 0)
  359.     {
  360.         if (GetDockedCount() == 0)
  361.         {
  362.             pFrameWnd->DestroyWindow();
  363.             return TRUE; // Self-Destruct
  364.         }
  365.         else
  366.             pFrameWnd->ShowWindow(SW_HIDE);
  367.     }
  368.     else
  369.         pFrameWnd->DelayRecalcLayout();
  370.  
  371.     return FALSE;
  372. }
  373.  
  374. /////////////////////////////////////////////////////////////////////////////
  375. // CDockBar layout
  376.  
  377. CSize CDockBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  378. {
  379.     ASSERT_VALID(this);
  380.  
  381.     CSize sizeFixed = CControlBar::CalcFixedLayout(bStretch, bHorz);
  382.  
  383.     // get max size
  384.     CSize sizeMax;
  385.     if (!m_rectLayout.IsRectEmpty())
  386.         sizeMax = m_rectLayout.Size();
  387.     else
  388.     {
  389.         CRect rectFrame;
  390.         CFrameWnd* pFrame = GetParentFrame();
  391.         pFrame->GetClientRect(&rectFrame);
  392.         sizeMax = rectFrame.Size();
  393.     }
  394.  
  395.     // prepare for layout
  396.     AFX_SIZEPARENTPARAMS layout;
  397.     layout.hDWP = m_bLayoutQuery ?
  398.         NULL : ::BeginDeferWindowPos(m_arrBars.GetSize());
  399.     CPoint pt(-afxData.cxBorder2, -afxData.cyBorder2);
  400.     int nWidth = 0;
  401.  
  402.     BOOL bWrapped = FALSE;
  403.  
  404.     // layout all the control bars
  405.     for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  406.     {
  407.         CControlBar* pBar = GetDockedControlBar(nPos);
  408.         void* pVoid = m_arrBars[nPos];
  409.  
  410.         if (pBar != NULL)
  411.         {
  412.             if (pBar->IsVisible())
  413.             {
  414.                 // get ideal rect for bar
  415.                 DWORD dwMode = 0;
  416.                 if ((pBar->m_dwStyle & CBRS_SIZE_DYNAMIC) &&
  417.                     (pBar->m_dwStyle & CBRS_FLOATING))
  418.                     dwMode |= LM_HORZ | LM_MRUWIDTH;
  419.                 else if (pBar->m_dwStyle & CBRS_ORIENT_HORZ)
  420.                     dwMode |= LM_HORZ | LM_HORZDOCK;
  421.                 else
  422.                     dwMode |=  LM_VERTDOCK;
  423.  
  424.                 CSize sizeBar = pBar->CalcDynamicLayout(-1, dwMode);
  425.  
  426.                 CRect rect(pt, sizeBar);
  427.  
  428.                 // get current rect for bar
  429.                 CRect rectBar;
  430.                 pBar->GetWindowRect(&rectBar);
  431.                 ScreenToClient(&rectBar);
  432.  
  433.                 if (bHorz)
  434.                 {
  435.                     // Offset Calculated Rect out to Actual
  436.                     if (rectBar.left > rect.left && !m_bFloating)
  437.                         rect.OffsetRect(rectBar.left - rect.left, 0);
  438.  
  439.                     // If ControlBar goes off the right, then right justify
  440.                     if (rect.right > sizeMax.cx && !m_bFloating)
  441.                     {
  442.                         int x = rect.Width() - afxData.cxBorder2;
  443.                         x = max(sizeMax.cx - x, pt.x);
  444.                         rect.OffsetRect(x - rect.left, 0);
  445.                     }
  446.  
  447.                     // If ControlBar has been wrapped, then left justify
  448.                     if (bWrapped)
  449.                     {
  450.                         bWrapped = FALSE;
  451.                         rect.OffsetRect(-(rect.left + afxData.cxBorder2), 0);
  452.                     }
  453.                     // If ControlBar is completely invisible, then wrap it
  454.                     else if ((rect.left >= (sizeMax.cx - afxData.cxBorder2)) &&
  455.                         (nPos > 0) && (m_arrBars[nPos - 1] != NULL))
  456.                     {
  457.                         m_arrBars.InsertAt(nPos, (CObject*)NULL);
  458.                         pBar = NULL; pVoid = NULL;
  459.                         bWrapped = TRUE;
  460.                     }
  461.                     if (!bWrapped)
  462.                     {
  463.                         if (rect != rectBar)
  464.                         {
  465.                             if (!m_bLayoutQuery &&
  466.                                 !(pBar->m_dwStyle & CBRS_FLOATING))
  467.                             {
  468.                                 pBar->m_pDockContext->m_rectMRUDockPos = rect;
  469.                             }
  470.                             AfxRepositionWindow(&layout, pBar->m_hWnd, &rect);
  471.                         }
  472.                         pt.x = rect.left + sizeBar.cx - afxData.cxBorder2;
  473.                         nWidth = max(nWidth, sizeBar.cy);
  474.                     }
  475.                 }
  476.                 else
  477.                 {
  478.                     // Offset Calculated Rect out to Actual
  479.                     if (rectBar.top > rect.top && !m_bFloating)
  480.                         rect.OffsetRect(0, rectBar.top - rect.top);
  481.  
  482.                     // If ControlBar goes off the bottom, then bottom justify
  483.                     if (rect.bottom > sizeMax.cy && !m_bFloating)
  484.                     {
  485.                         int y = rect.Height() - afxData.cyBorder2;
  486.                         y = max(sizeMax.cy - y, pt.y);
  487.                         rect.OffsetRect(0, y - rect.top);
  488.                     }
  489.  
  490.                     // If ControlBar has been wrapped, then top justify
  491.                     if (bWrapped)
  492.                     {
  493.                         bWrapped = FALSE;
  494.                         rect.OffsetRect(0, -(rect.top + afxData.cyBorder2));
  495.                     }
  496.                     // If ControlBar is completely invisible, then wrap it
  497.                     else if ((rect.top >= (sizeMax.cy - afxData.cyBorder2)) &&
  498.                         (nPos > 0) && (m_arrBars[nPos - 1] != NULL))
  499.                     {
  500.                         m_arrBars.InsertAt(nPos, (CObject*)NULL);
  501.                         pBar = NULL; pVoid = NULL;
  502.                         bWrapped = TRUE;
  503.                     }
  504.                     if (!bWrapped)
  505.                     {
  506.                         if (rect != rectBar)
  507.                         {
  508.                             if (!m_bLayoutQuery &&
  509.                                 !(pBar->m_dwStyle & CBRS_FLOATING))
  510.                             {
  511.                                 pBar->m_pDockContext->m_rectMRUDockPos = rect;
  512.                             }
  513.                             AfxRepositionWindow(&layout, pBar->m_hWnd, &rect);
  514.                         }
  515.                         pt.y = rect.top + sizeBar.cy - afxData.cyBorder2;
  516.                         nWidth = max(nWidth, sizeBar.cx);
  517.                     }
  518.                 }
  519.             }
  520.             if (!bWrapped)
  521.             {
  522.                 // handle any delay/show hide for the bar
  523.                 pBar->RecalcDelayShow(&layout);
  524.             }
  525.         }
  526.         if (pBar == NULL && pVoid == NULL && nWidth != 0)
  527.         {
  528.             // end of row because pBar == NULL
  529.             if (bHorz)
  530.             {
  531.                 pt.y += nWidth - afxData.cyBorder2;
  532.                 sizeFixed.cx = max(sizeFixed.cx, pt.x);
  533.                 sizeFixed.cy = max(sizeFixed.cy, pt.y);
  534.                 pt.x = -afxData.cxBorder2;
  535.             }
  536.             else
  537.             {
  538.                 pt.x += nWidth - afxData.cxBorder2;
  539.                 sizeFixed.cx = max(sizeFixed.cx, pt.x);
  540.                 sizeFixed.cy = max(sizeFixed.cy, pt.y);
  541.                 pt.y = -afxData.cyBorder2;
  542.             }
  543.             nWidth = 0;
  544.         }
  545.     }
  546.     if (!m_bLayoutQuery)
  547.     {
  548.         // move and resize all the windows at once!
  549.         if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
  550.             TRACE0("Warning: DeferWindowPos failed - low system resources.\n");
  551.     }
  552.  
  553.     // adjust size for borders on the dock bar itself
  554.     CRect rect;
  555.     rect.SetRectEmpty();
  556.     CalcInsideRect(rect, bHorz);
  557.  
  558.     if ((!bStretch || !bHorz) && sizeFixed.cx != 0)
  559.         sizeFixed.cx += -rect.right + rect.left;
  560.     if ((!bStretch || bHorz) && sizeFixed.cy != 0)
  561.         sizeFixed.cy += -rect.bottom + rect.top;
  562.  
  563.     return sizeFixed;
  564. }
  565.  
  566. LRESULT CDockBar::OnSizeParent(WPARAM wParam, LPARAM lParam)
  567. {
  568.     AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
  569.  
  570.     // set m_bLayoutQuery to TRUE if lpLayout->hDWP == NULL
  571.     BOOL bLayoutQuery = m_bLayoutQuery;
  572.     CRect rectLayout = m_rectLayout;
  573.     m_bLayoutQuery = (lpLayout->hDWP == NULL);
  574.     m_rectLayout = lpLayout->rect;
  575.     LRESULT lResult = CControlBar::OnSizeParent(wParam, lParam);
  576.     // restore m_bLayoutQuery
  577.     m_bLayoutQuery = bLayoutQuery;
  578.     m_rectLayout = rectLayout;
  579.  
  580.     return lResult;
  581. }
  582.  
  583. /////////////////////////////////////////////////////////////////////////////
  584. // CDockBar message handlers
  585.  
  586. void CDockBar::OnNcCalcSize(BOOL /*bCalcValidRects*/, NCCALCSIZE_PARAMS* lpncsp)
  587. {
  588.     // calculate border space (will add to top/bottom, subtract from right/bottom)
  589.     CRect rect;
  590.     rect.SetRectEmpty();
  591.     CalcInsideRect(rect, m_dwStyle & CBRS_ORIENT_HORZ);
  592.  
  593.     // adjust non-client area for border space
  594.     lpncsp->rgrc[0].left += rect.left;
  595.     lpncsp->rgrc[0].top += rect.top;
  596.     lpncsp->rgrc[0].right += rect.right;
  597.     lpncsp->rgrc[0].bottom += rect.bottom;
  598. }
  599.  
  600. void CDockBar::OnNcPaint()
  601. {
  602.     EraseNonClient();
  603. }
  604.  
  605. void CDockBar::DoPaint(CDC*)
  606. {
  607.     // border painting is done in non-client area
  608. }
  609.  
  610. void CDockBar::OnPaint()
  611. {
  612.     // background is already filled in grey
  613.     CPaintDC dc(this);
  614.     if (IsVisible() && GetDockedVisibleCount() != 0)
  615.         DoPaint(&dc);       // delegate to paint helper
  616. }
  617.  
  618. #ifdef _MAC
  619. BOOL CDockBar::CheckMonochrome(void)
  620. {
  621.     BOOL bMono = CControlBar::CheckMonochrome();
  622.  
  623.     if (!bMono)
  624.     {
  625.         DWORD dw3D;
  626.  
  627.         SystemParametersInfo(SPI_GET3D, 0, (void*) &dw3D, FALSE);
  628.         bMono = (dw3D & F3D_NO3D) || !(dw3D & F3D_3DTOOLBAR);
  629.     }
  630.  
  631.     return bMono;
  632. }
  633. #endif
  634.  
  635. void CDockBar::OnWindowPosChanging(LPWINDOWPOS lpWndPos)
  636. {
  637.     // not necessary to invalidate the borders
  638.     DWORD dwStyle = m_dwStyle;
  639.     m_dwStyle &= ~(CBRS_BORDER_ANY);
  640.     CControlBar::OnWindowPosChanging(lpWndPos);
  641.     m_dwStyle = dwStyle;
  642. }
  643.  
  644. /////////////////////////////////////////////////////////////////////////////
  645. // CDockBar utility/implementation
  646.  
  647. int CDockBar::FindBar(CControlBar* pBar, int nPosExclude)
  648. {
  649.     for (int nPos = 0; nPos< m_arrBars.GetSize(); nPos++)
  650.     {
  651.         if (nPos != nPosExclude && m_arrBars[nPos] == pBar)
  652.             return nPos;
  653.     }
  654.     return -1;
  655. }
  656.  
  657. void CDockBar::ShowAll(BOOL bShow)
  658. {
  659.     for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  660.     {
  661.         CControlBar* pBar = GetDockedControlBar(nPos);
  662.         if (pBar != NULL)
  663.         {
  664.             CFrameWnd* pFrameWnd = pBar->GetDockingFrame();
  665.             pFrameWnd->ShowControlBar(pBar, bShow, TRUE);
  666.         }
  667.     }
  668. }
  669.  
  670. CControlBar* CDockBar::GetDockedControlBar(int nPos) const
  671. {
  672.     CControlBar* pResult = (CControlBar*)m_arrBars[nPos];
  673.     if (HIWORD(pResult) == 0)
  674.         return NULL;
  675.     return pResult;
  676. }
  677.  
  678. int CDockBar::Insert(CControlBar* pBarIns, CRect rect, CPoint ptMid)
  679. {
  680.     ASSERT_VALID(this);
  681.     ASSERT(pBarIns != NULL);
  682.  
  683.     int nPos = 0;
  684.     int nPosInsAfter = 0;
  685.     int nWidth = 0;
  686.     int nTotalWidth = 0;
  687.     BOOL bHorz = m_dwStyle & CBRS_ORIENT_HORZ ? TRUE : FALSE;
  688.  
  689.     for (nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  690.     {
  691.         CControlBar* pBar = GetDockedControlBar(nPos);
  692.         if (pBar != NULL && pBar->IsVisible())
  693.         {
  694.             CRect rectBar;
  695.             pBar->GetWindowRect(&rectBar);
  696.             ScreenToClient(&rectBar);
  697.             nWidth = max(nWidth,
  698.                 bHorz ? rectBar.Size().cy : rectBar.Size().cx - 1);
  699.             if (bHorz ? rect.left > rectBar.left : rect.top > rectBar.top)
  700.                 nPosInsAfter = nPos;
  701.         }
  702.         else // end of row because pBar == NULL
  703.         {
  704.             nTotalWidth += nWidth - afxData.cyBorder2;
  705.             nWidth = 0;
  706.             if ((bHorz ? ptMid.y : ptMid.x) < nTotalWidth)
  707.             {
  708.                 if (nPos == 0) // first section
  709.                     m_arrBars.InsertAt(nPosInsAfter+1, (CObject*)NULL);
  710.                 m_arrBars.InsertAt(nPosInsAfter+1, pBarIns);
  711.                 return nPosInsAfter+1;
  712.             }
  713.             nPosInsAfter = nPos;
  714.         }
  715.     }
  716.  
  717.     // create a new row
  718.     m_arrBars.InsertAt(nPosInsAfter+1, (CObject*)NULL);
  719.     m_arrBars.InsertAt(nPosInsAfter+1, pBarIns);
  720.  
  721.     return nPosInsAfter+1;
  722. }
  723.  
  724. void CDockBar::OnUpdateCmdUI(CFrameWnd* /*pTarget*/, BOOL /*bDisableIfNoHndler*/)
  725. {
  726. }
  727.  
  728. #ifdef _DEBUG
  729. void CDockBar::AssertValid() const
  730. {
  731.     CControlBar::AssertValid();
  732.     ASSERT(m_arrBars.GetSize() != 0);
  733.     ASSERT(m_arrBars[0] == NULL);
  734.     ASSERT(m_arrBars[m_arrBars.GetUpperBound()] == NULL);
  735. }
  736.  
  737. void CDockBar::Dump(CDumpContext& dc) const
  738. {
  739.     CControlBar::Dump(dc);
  740.  
  741.     dc << "m_arrBars " << m_arrBars;
  742.     dc << "\nm_bFloating " << m_bFloating;
  743.  
  744.     dc << "\n";
  745. }
  746. #endif
  747.  
  748. /////////////////////////////////////////////////////////////////////////////
  749. // CControlBar docking helpers
  750.  
  751. void CControlBar::EnableDocking(DWORD dwDockStyle)
  752. {
  753.     // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  754.     ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
  755.     // CBRS_SIZE_DYNAMIC toolbar cannot have the CBRS_FLOAT_MULTI style
  756.     ASSERT(((dwDockStyle & CBRS_FLOAT_MULTI) == 0) || ((m_dwStyle & CBRS_SIZE_DYNAMIC) == 0));
  757.  
  758.     m_dwDockStyle = dwDockStyle;
  759.     if (m_pDockContext == NULL)
  760.         m_pDockContext = new CDockContext(this);
  761.  
  762.     // permanently wire the bar's owner to its current parent
  763.     if (m_hWndOwner == NULL)
  764.         m_hWndOwner = ::GetParent(m_hWnd);
  765. }
  766.  
  767. /////////////////////////////////////////////////////////////////////////////
  768. // CMiniDockFrameWnd
  769.  
  770. BEGIN_MESSAGE_MAP(CMiniDockFrameWnd, CMiniFrameWnd)
  771.     //{{AFX_MSG_MAP(CMiniDockFrameWnd)
  772.     ON_WM_CLOSE()
  773.     ON_WM_NCLBUTTONDOWN()
  774.     ON_WM_NCLBUTTONDBLCLK()
  775.     //}}AFX_MSG_MAP
  776. #ifdef _MAC
  777.     ON_WM_ERASEBKGND()
  778. #endif
  779.     ON_WM_MOUSEACTIVATE()
  780. END_MESSAGE_MAP()
  781.  
  782. int CMiniDockFrameWnd::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
  783. {
  784.     if (nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST) // resizing
  785.         return MA_NOACTIVATE;
  786.     return CMiniFrameWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
  787. }
  788.  
  789. CMiniDockFrameWnd::CMiniDockFrameWnd() : m_wndDockBar(TRUE)
  790. {
  791.     m_wndDockBar.m_bAutoDelete = FALSE;
  792. }
  793.  
  794. BOOL CMiniDockFrameWnd::Create(CWnd* pParent, DWORD dwBarStyle)
  795. {
  796.     // set m_bInRecalcLayout to avoid flashing during creation
  797.     // RecalcLayout will be called once something is docked
  798.     m_bInRecalcLayout = TRUE;
  799.  
  800.     DWORD dwStyle = WS_POPUP|WS_CAPTION|WS_SYSMENU|MFS_MOVEFRAME|
  801.         MFS_4THICKFRAME|MFS_SYNCACTIVE|MFS_BLOCKSYSMENU|
  802.         FWS_SNAPTOBARS;
  803.  
  804.     if (dwBarStyle & CBRS_SIZE_DYNAMIC)
  805.         dwStyle &= ~MFS_MOVEFRAME;
  806.  
  807.     DWORD dwExStyle = 0;
  808. #ifdef _MAC
  809.     if (dwBarStyle & CBRS_SIZE_DYNAMIC)
  810.         dwExStyle |= WS_EX_FORCESIZEBOX;
  811.     else
  812.         dwStyle &= ~(MFS_MOVEFRAME|MFS_4THICKFRAME);
  813. #endif
  814.  
  815.     if (!CMiniFrameWnd::CreateEx(dwExStyle,
  816.         NULL, &afxChNil, dwStyle, rectDefault, pParent))
  817.     {
  818.         m_bInRecalcLayout = FALSE;
  819.         return FALSE;
  820.     }
  821.     dwStyle = dwBarStyle & (CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT) ?
  822.         CBRS_ALIGN_LEFT : CBRS_ALIGN_TOP;
  823.     dwStyle |= dwBarStyle & CBRS_FLOAT_MULTI;
  824.     CMenu* pSysMenu = GetSystemMenu(FALSE);
  825.     pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
  826.     CString strHide;
  827.     if (strHide.LoadString(AFX_IDS_HIDE))
  828.     {
  829.         pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
  830.         pSysMenu->AppendMenu(MF_STRING|MF_ENABLED, SC_CLOSE, strHide);
  831.     }
  832.  
  833.     // must initially create with parent frame as parent
  834.     if (!m_wndDockBar.Create(pParent, WS_CHILD | WS_VISIBLE | dwStyle,
  835.         AFX_IDW_DOCKBAR_FLOAT))
  836.     {
  837.         m_bInRecalcLayout = FALSE;
  838.         return FALSE;
  839.     }
  840.  
  841.     // set parent to CMiniDockFrameWnd
  842.     m_wndDockBar.SetParent(this);
  843.     m_bInRecalcLayout = FALSE;
  844.  
  845.     return TRUE;
  846. }
  847.  
  848. void CMiniDockFrameWnd::RecalcLayout(BOOL bNotify)
  849. {
  850.     if (!m_bInRecalcLayout)
  851.     {
  852.         CMiniFrameWnd::RecalcLayout(bNotify);
  853.  
  854.         // syncronize window text of frame window with dockbar itself
  855.         TCHAR szTitle[_MAX_PATH];
  856.         m_wndDockBar.GetWindowText(szTitle, _countof(szTitle));
  857.         AfxSetWindowText(m_hWnd, szTitle);
  858.     }
  859. }
  860.  
  861. void CMiniDockFrameWnd::OnClose()
  862. {
  863.     m_wndDockBar.ShowAll(FALSE);
  864. }
  865.  
  866. void CMiniDockFrameWnd::OnNcLButtonDown(UINT nHitTest, CPoint point)
  867. {
  868.     if (nHitTest == HTCAPTION)
  869.     {
  870.         // special activation for floating toolbars
  871.         ActivateTopParent();
  872.  
  873.         // initiate toolbar drag for non-CBRS_FLOAT_MULTI toolbars
  874.         if ((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0)
  875.         {
  876.             int nPos = 1;
  877.             CControlBar* pBar = NULL;
  878.             while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
  879.                 pBar = m_wndDockBar.GetDockedControlBar(nPos++);
  880.  
  881.             ASSERT(pBar != NULL);
  882.             ASSERT_KINDOF(CControlBar, pBar);
  883.             ASSERT(pBar->m_pDockContext != NULL);
  884.             pBar->m_pDockContext->StartDrag(point);
  885.             return;
  886.         }
  887.     }
  888.     else if (nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST)
  889.     {
  890.         // special activation for floating toolbars
  891.         ActivateTopParent();
  892.  
  893.         int nPos = 1;
  894.         CControlBar* pBar = NULL;
  895.         while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
  896.             pBar = m_wndDockBar.GetDockedControlBar(nPos++);
  897.  
  898.         ASSERT(pBar != NULL);
  899.         ASSERT_KINDOF(CControlBar, pBar);
  900.         ASSERT(pBar->m_pDockContext != NULL);
  901.  
  902.         // CBRS_SIZE_DYNAMIC toolbars cannot have the CBRS_FLOAT_MULTI style
  903.         ASSERT((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0);
  904.         pBar->m_pDockContext->StartResize(nHitTest, point);
  905.         return;
  906.     }
  907.     CMiniFrameWnd::OnNcLButtonDown(nHitTest, point);
  908. }
  909.  
  910. void CMiniDockFrameWnd::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
  911. {
  912.     // Note: This option is disabled for the Mac version because
  913.     //  it does not work well with the WindowShade control panel.
  914. #ifndef _MAC
  915.     if (nHitTest == HTCAPTION)
  916.     {
  917.         // special activation for floating toolbars
  918.         ActivateTopParent();
  919.  
  920.         // initiate toolbar toggle for non-CBRS_FLOAT_MULTI toolbars
  921.         if ((m_wndDockBar.m_dwStyle & CBRS_FLOAT_MULTI) == 0)
  922.         {
  923.             int nPos = 1;
  924.             CControlBar* pBar = NULL;
  925.             while(pBar == NULL && nPos < m_wndDockBar.m_arrBars.GetSize())
  926.                 pBar = m_wndDockBar.GetDockedControlBar(nPos++);
  927.  
  928.             ASSERT(pBar != NULL);
  929.             ASSERT_KINDOF(CControlBar, pBar);
  930.             ASSERT(pBar->m_pDockContext != NULL);
  931.             pBar->m_pDockContext->ToggleDocking();
  932.             return;
  933.         }
  934.     }
  935. #endif
  936.     CMiniFrameWnd::OnNcLButtonDblClk(nHitTest, point);
  937. }
  938.  
  939. #ifdef _MAC
  940. BOOL CMiniDockFrameWnd::OnEraseBkgnd(CDC* pDC)
  941. {
  942.     CRect rect;
  943.     GetClientRect(rect);
  944.     pDC->FillSolidRect(rect, m_wndDockBar.m_bMonochrome ? 0xFFFFFF : ::GetSysColor(COLOR_3DLIGHT));
  945.     return TRUE;
  946. }
  947. #endif
  948.  
  949. #ifdef AFX_INIT_SEG
  950. #pragma code_seg(AFX_INIT_SEG)
  951. #endif
  952.  
  953. IMPLEMENT_DYNAMIC(CDockBar, CControlBar)
  954. IMPLEMENT_DYNCREATE(CMiniDockFrameWnd, CMiniFrameWnd)
  955.  
  956. /////////////////////////////////////////////////////////////////////////////
  957.