home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / dockstat.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  20KB  |  715 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 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. // CDockState
  26.  
  27. AFX_STATIC_DATA const TCHAR _afxVisible[] = _T("Visible");
  28. AFX_STATIC_DATA const TCHAR _afxBarSection[] = _T("%s-Bar%d");
  29. AFX_STATIC_DATA const TCHAR _afxSummarySection[] = _T("%s-Summary");
  30. AFX_STATIC_DATA const TCHAR _afxXPos[] = _T("XPos");
  31. AFX_STATIC_DATA const TCHAR _afxYPos[] = _T("YPos");
  32. AFX_STATIC_DATA const TCHAR _afxMRUWidth[] = _T("MRUWidth");
  33. AFX_STATIC_DATA const TCHAR _afxDocking[] = _T("Docking");
  34. AFX_STATIC_DATA const TCHAR _afxMRUDockID[] = _T("MRUDockID");
  35. AFX_STATIC_DATA const TCHAR _afxMRUDockLeftPos[] = _T("MRUDockLeftPos");
  36. AFX_STATIC_DATA const TCHAR _afxMRUDockRightPos[] = _T("MRUDockRightPos");
  37. AFX_STATIC_DATA const TCHAR _afxMRUDockTopPos[] = _T("MRUDockTopPos");
  38. AFX_STATIC_DATA const TCHAR _afxMRUDockBottomPos[] = _T("MRUDockBottomPos");
  39. AFX_STATIC_DATA const TCHAR _afxMRUFloatStyle[] = _T("MRUFloatStyle");
  40. AFX_STATIC_DATA const TCHAR _afxMRUFloatXPos[] = _T("MRUFloatXPos");
  41. AFX_STATIC_DATA const TCHAR _afxMRUFloatYPos[] = _T("MRUFloatYPos");
  42.  
  43. AFX_STATIC_DATA const TCHAR _afxBarID[] = _T("BarID");
  44. AFX_STATIC_DATA const TCHAR _afxHorz[] = _T("Horz");
  45. AFX_STATIC_DATA const TCHAR _afxFloating[] = _T("Floating");
  46. AFX_STATIC_DATA const TCHAR _afxBars[] = _T("Bars");
  47. AFX_STATIC_DATA const TCHAR _afxScreenCX[] = _T("ScreenCX");
  48. AFX_STATIC_DATA const TCHAR _afxScreenCY[] = _T("ScreenCY");
  49. AFX_STATIC_DATA const TCHAR _afxBar[] = _T("Bar#%d");
  50.  
  51. CControlBarInfo::CControlBarInfo()
  52. {
  53.     m_nBarID = 0;
  54.     m_bDockBar = m_bVisible = m_bFloating = m_bHorz = m_bDocking = FALSE;
  55.     m_pBar = NULL;
  56.     m_pointPos.x = m_pointPos.y = -1;
  57.     m_nMRUWidth = 32767;
  58.  
  59.     m_uMRUDockID = 0;
  60.     m_rectMRUDockPos.SetRectEmpty();
  61.     m_dwMRUFloatStyle = 0;
  62.     m_ptMRUFloatPos = CPoint(0,0);
  63.  
  64.     ASSERT(sizeof(DWORD) == sizeof(void*));
  65. }
  66.  
  67. void CControlBarInfo::Serialize(CArchive& ar, CDockState* pDockState)
  68. {
  69.     ASSERT(pDockState!=NULL);
  70.  
  71.     if (ar.IsStoring())
  72.     {
  73.         ar << (DWORD)m_nBarID;
  74.         ar << (DWORD)m_bVisible;
  75.         ar << (DWORD)m_bFloating;
  76.         ar << (DWORD)m_bHorz;
  77.         ar << m_pointPos;
  78.         if (pDockState->GetVersion() > 1)
  79.         {
  80.             ar << (DWORD)m_nMRUWidth;
  81.             ar << (DWORD)m_bDocking;
  82.             if (m_bDocking)
  83.             {
  84.                 ar << (DWORD)m_uMRUDockID;
  85.                 ar << m_rectMRUDockPos;
  86.                 ar << m_dwMRUFloatStyle;
  87.                 ar << m_ptMRUFloatPos;
  88.             }
  89.         }
  90.  
  91.         ar << (WORD)m_arrBarID.GetSize();
  92.         if (m_arrBarID.GetSize() != 0)
  93.         {
  94. #ifdef _AFX_BYTESWAP
  95.             if (!ar.IsByteSwapping())
  96. #endif
  97.             ar.Write(&m_arrBarID.ElementAt(0),
  98.                 m_arrBarID.GetSize()*sizeof(DWORD));
  99. #ifdef _AFX_BYTESWAP
  100.             else
  101.             {
  102.                 // write each ID individually so that it will be byte-swapped
  103.                 for (int i = 0; i < m_arrBarID.GetSize(); i++)
  104.                     ar << (DWORD)m_arrBarID[i];
  105.             }
  106. #endif
  107.         }
  108.     }
  109.     else
  110.     {
  111.  
  112.         DWORD dw;
  113.         ar >> dw;
  114.         m_nBarID = (int)dw;
  115.         ar >> dw;
  116.         m_bVisible = (BOOL)dw;
  117.         ar >> dw;
  118.         m_bFloating = (BOOL)dw;
  119.         ar >> dw;
  120.         m_bHorz = (BOOL)dw;
  121.         ar >> m_pointPos;
  122.  
  123.         if (pDockState->GetVersion() > 1)
  124.         {
  125.             pDockState->ScalePoint(m_pointPos);
  126.  
  127.             ar >> dw;
  128.             m_nMRUWidth = (int)dw;
  129.             ar >> dw;
  130.             m_bDocking = (BOOL)dw;
  131.             if (m_bDocking)
  132.             {
  133.                 ar >> dw;
  134.                 m_uMRUDockID = (DWORD)dw;
  135.                 ar >> m_rectMRUDockPos;
  136.                 pDockState->ScaleRectPos(m_rectMRUDockPos);
  137.  
  138.                 ar >> m_dwMRUFloatStyle;
  139.                 ar >> m_ptMRUFloatPos;
  140.                 pDockState->ScalePoint(m_ptMRUFloatPos);
  141.             }
  142.         }
  143.  
  144.         WORD w;
  145.         ar >> w;
  146.         m_arrBarID.SetSize(w);
  147.         if (w != 0)
  148.         {
  149.             ar.Read(&m_arrBarID.ElementAt(0),
  150.                 m_arrBarID.GetSize()*sizeof(DWORD));
  151. #ifdef _AFX_BYTESWAP
  152.             if (ar.IsByteSwapping())
  153.             {
  154.                 for (int i = 0; i < m_arrBarID.GetSize(); i++)
  155.                     _AfxByteSwap((DWORD)m_arrBarID[i], (BYTE*)&m_arrBarID[i]);
  156.             }
  157. #endif
  158.         }
  159.     }
  160. }
  161.  
  162. BOOL CControlBarInfo::LoadState(LPCTSTR lpszProfileName, int nIndex, CDockState* pDockState)
  163. {
  164.     ASSERT(pDockState != NULL);
  165.  
  166.     CWinApp* pApp = AfxGetApp();
  167.     TCHAR szSection[256];
  168.     wsprintf(szSection, _afxBarSection, lpszProfileName, nIndex);
  169.  
  170.     m_nBarID = pApp->GetProfileInt(szSection, _afxBarID, 0);
  171.     m_bVisible = (BOOL) pApp->GetProfileInt(szSection, _afxVisible, TRUE);
  172.     m_bHorz = (BOOL) pApp->GetProfileInt(szSection, _afxHorz, TRUE);
  173.     m_bFloating = (BOOL) pApp->GetProfileInt(szSection, _afxFloating, FALSE);
  174.     m_pointPos = CPoint(
  175.         pApp->GetProfileInt(szSection, _afxXPos, -1),
  176.         pApp->GetProfileInt(szSection, _afxYPos, -1));
  177.     pDockState->ScalePoint(m_pointPos);
  178.     m_nMRUWidth = pApp->GetProfileInt(szSection, _afxMRUWidth, 32767);
  179.     m_bDocking = pApp->GetProfileInt(szSection, _afxDocking, 0);
  180.     if (m_bDocking)
  181.     {
  182.         m_uMRUDockID = pApp->GetProfileInt(szSection, _afxMRUDockID, 0);
  183.  
  184.         m_rectMRUDockPos = CRect(
  185.             pApp->GetProfileInt(szSection, _afxMRUDockLeftPos, 0),
  186.             pApp->GetProfileInt(szSection, _afxMRUDockTopPos, 0),
  187.             pApp->GetProfileInt(szSection, _afxMRUDockRightPos, 0),
  188.             pApp->GetProfileInt(szSection, _afxMRUDockBottomPos, 0));
  189.         pDockState->ScaleRectPos(m_rectMRUDockPos);
  190.  
  191.         m_dwMRUFloatStyle = pApp->GetProfileInt(szSection, _afxMRUFloatStyle, 0);
  192.  
  193.         m_ptMRUFloatPos = CPoint(
  194.             pApp->GetProfileInt(szSection, _afxMRUFloatXPos, 0),
  195.             pApp->GetProfileInt(szSection, _afxMRUFloatYPos, 0));
  196.         pDockState->ScalePoint(m_ptMRUFloatPos);
  197.     }
  198.  
  199.     int nBars = pApp->GetProfileInt(szSection, _afxBars, 0);
  200.     for (int i=0; i < nBars; i++)
  201.     {
  202.         TCHAR buf[16];
  203.         wsprintf(buf, _afxBar, i);
  204.         m_arrBarID.Add((void*)pApp->GetProfileInt(szSection, buf, 0));
  205.     }
  206.  
  207.     return m_nBarID != 0;
  208. }
  209.  
  210. BOOL CControlBarInfo::SaveState(LPCTSTR lpszProfileName, int nIndex)
  211. {
  212.     TCHAR szSection[256];
  213.     wsprintf(szSection, _afxBarSection, lpszProfileName, nIndex);
  214.  
  215.     // delete the section
  216.     CWinApp* pApp = AfxGetApp();
  217.     pApp->WriteProfileString(szSection, NULL, NULL);
  218.  
  219.     if (m_bDockBar && m_bVisible && !m_bFloating && m_pointPos.x == -1 &&
  220.         m_pointPos.y == -1 && m_arrBarID.GetSize() <= 1)
  221.     {
  222.         return FALSE;
  223.     }
  224.  
  225.     pApp->WriteProfileInt(szSection, _afxBarID, m_nBarID);
  226.     if (!m_bVisible)
  227.         pApp->WriteProfileInt(szSection, _afxVisible, m_bVisible);
  228.     if (m_bFloating)
  229.     {
  230.         pApp->WriteProfileInt(szSection, _afxHorz, m_bHorz);
  231.         pApp->WriteProfileInt(szSection, _afxFloating, m_bFloating);
  232.     }
  233.     if (m_pointPos.x != -1)
  234.         pApp->WriteProfileInt(szSection, _afxXPos, m_pointPos.x);
  235.     if (m_pointPos.y != -1)
  236.         pApp->WriteProfileInt(szSection, _afxYPos, m_pointPos.y);
  237.     if (m_nMRUWidth != 32767)
  238.         pApp->WriteProfileInt(szSection, _afxMRUWidth, m_nMRUWidth);
  239.     if (m_bDocking)
  240.     {
  241.         pApp->WriteProfileInt(szSection, _afxDocking, m_bDocking);
  242.         pApp->WriteProfileInt(szSection, _afxMRUDockID, m_uMRUDockID);
  243.         pApp->WriteProfileInt(szSection, _afxMRUDockLeftPos, m_rectMRUDockPos.left);
  244.         pApp->WriteProfileInt(szSection, _afxMRUDockTopPos, m_rectMRUDockPos.top);
  245.         pApp->WriteProfileInt(szSection, _afxMRUDockRightPos, m_rectMRUDockPos.right);
  246.         pApp->WriteProfileInt(szSection, _afxMRUDockBottomPos, m_rectMRUDockPos.bottom);
  247.         pApp->WriteProfileInt(szSection, _afxMRUFloatStyle, m_dwMRUFloatStyle);
  248.         pApp->WriteProfileInt(szSection, _afxMRUFloatXPos, m_ptMRUFloatPos.x);
  249.         pApp->WriteProfileInt(szSection, _afxMRUFloatYPos, m_ptMRUFloatPos.y);
  250.     }
  251.  
  252.     if (m_arrBarID.GetSize() > 1) //if ==1 then still empty
  253.     {
  254.         pApp->WriteProfileInt(szSection, _afxBars, m_arrBarID.GetSize());
  255.         for (int i = 0; i < m_arrBarID.GetSize(); i++)
  256.         {
  257.             TCHAR buf[16];
  258.             wsprintf(buf, _afxBar, i);
  259.             pApp->WriteProfileInt(szSection, buf, (int)m_arrBarID[i]);
  260.         }
  261.     }
  262.     return TRUE;
  263. }
  264.  
  265. CDockState::CDockState()
  266. {
  267.     m_dwVersion = 2;
  268.  
  269.     m_bScaling = FALSE;
  270.  
  271.     m_rectDevice.left = 0;
  272.     m_rectDevice.top = 0;
  273.     m_rectDevice.right = GetSystemMetrics(SM_CXSCREEN);
  274.     m_rectDevice.bottom = GetSystemMetrics(SM_CYSCREEN);
  275.  
  276.     m_rectClip = m_rectDevice;
  277.     m_rectClip.right -= GetSystemMetrics(SM_CXICON);
  278.     m_rectClip.bottom -= GetSystemMetrics(SM_CYICON);
  279. }
  280.  
  281. CDockState::~CDockState()
  282. {
  283.     for (int i = 0; i < m_arrBarInfo.GetSize(); i++)
  284.         delete (CControlBarInfo*)m_arrBarInfo[i];
  285. }
  286.  
  287. void CDockState::Serialize(CArchive& ar)
  288. {
  289.     // read/write version info
  290.     if (ar.IsStoring())
  291.     {
  292.         ar << m_dwVersion;
  293.  
  294.         if (m_dwVersion > 1)
  295.         {
  296.             ar << GetScreenSize();
  297.         }
  298.  
  299.         // write array contents
  300.         ar << (WORD)m_arrBarInfo.GetSize();
  301.         for (int i = 0; i < m_arrBarInfo.GetSize(); i++)
  302.             ((CControlBarInfo*)m_arrBarInfo[i])->Serialize(ar, this);
  303.     }
  304.     else
  305.     {
  306.         Clear(); //empty out dockstate
  307.         ar >> m_dwVersion;       // read version marker
  308.         ASSERT(m_dwVersion == 1 || m_dwVersion == 2);
  309.  
  310.         if (m_dwVersion > 1)
  311.         {
  312.             CSize size;
  313.             ar >> size;
  314.             SetScreenSize(size);
  315.         }
  316.  
  317.         // read array contents
  318.         WORD nOldSize;
  319.         ar >> nOldSize;
  320.         m_arrBarInfo.SetSize(nOldSize);
  321.         for (int i = 0; i < m_arrBarInfo.GetSize(); i++)
  322.         {
  323.             m_arrBarInfo[i] = new CControlBarInfo;
  324.             ((CControlBarInfo*)m_arrBarInfo[i])->Serialize(ar, this);
  325.         }
  326.         m_dwVersion = 2;
  327.     }
  328. }
  329.  
  330. void CDockState::LoadState(LPCTSTR lpszProfileName)
  331. {
  332.     CWinApp* pApp = AfxGetApp();
  333.     TCHAR szSection[256];
  334.     wsprintf(szSection, _afxSummarySection, lpszProfileName);
  335.     int nBars = pApp->GetProfileInt(szSection, _afxBars, 0);
  336.  
  337.     CSize size;
  338.     size.cx = pApp->GetProfileInt(szSection, _afxScreenCX, 0);
  339.     size.cy = pApp->GetProfileInt(szSection, _afxScreenCY, 0);
  340.     SetScreenSize(size);
  341.  
  342.     for (int i = 0; i < nBars; i++)
  343.     {
  344.         CControlBarInfo* pInfo = new CControlBarInfo;
  345.         m_arrBarInfo.Add(pInfo);
  346.         pInfo->LoadState(lpszProfileName, i, this);
  347.     }
  348. }
  349.  
  350. void CDockState::SaveState(LPCTSTR lpszProfileName)
  351. {
  352.     int nIndex = 0;
  353.     for (int i = 0;i < m_arrBarInfo.GetSize(); i++)
  354.     {
  355.         CControlBarInfo* pInfo = (CControlBarInfo*)m_arrBarInfo[i];
  356.         ASSERT(pInfo != NULL);
  357.         if (pInfo->SaveState(lpszProfileName, nIndex))
  358.             nIndex++;
  359.     }
  360.     CWinApp* pApp = AfxGetApp();
  361.     TCHAR szSection[256];
  362.     wsprintf(szSection, _afxSummarySection, lpszProfileName);
  363.     pApp->WriteProfileInt(szSection, _afxBars, nIndex);
  364.  
  365.     CSize size = GetScreenSize();
  366.     pApp->WriteProfileInt(szSection, _afxScreenCX, size.cx);
  367.     pApp->WriteProfileInt(szSection, _afxScreenCY, size.cy);
  368. }
  369.  
  370. void CDockState::Clear()
  371. {
  372.     for (int i = 0; i < m_arrBarInfo.GetSize(); i++)
  373.         delete (CControlBarInfo*) m_arrBarInfo[i];
  374.     m_arrBarInfo.RemoveAll();
  375. }
  376.  
  377. DWORD CDockState::GetVersion()
  378. {
  379.     return m_dwVersion;
  380. }
  381.  
  382. void CDockState::ScalePoint(CPoint& pt)
  383. {
  384.     if (m_bScaling)
  385.     {
  386.         CSize sizeDevice = m_rectDevice.Size();
  387.  
  388.         pt.x = MulDiv(pt.x, sizeDevice.cx, m_sizeLogical.cx);
  389.         pt.y = MulDiv(pt.y, sizeDevice.cy, m_sizeLogical.cy);
  390.     }
  391.     if (pt.x > m_rectClip.right)
  392.         pt.x = m_rectClip.right;
  393.     if (pt.y > m_rectClip.bottom)
  394.         pt.y = m_rectClip.bottom;
  395. }
  396.  
  397. void CDockState::ScaleRectPos(CRect& rect)
  398. {
  399.     CPoint pt;
  400.  
  401.     if (m_bScaling)
  402.     {
  403.         pt = rect.TopLeft();
  404.         CSize sizeDevice = m_rectDevice.Size();
  405.  
  406.         pt.x = MulDiv(pt.x, sizeDevice.cx, m_sizeLogical.cx) - rect.left;
  407.         pt.y = MulDiv(pt.y, sizeDevice.cy, m_sizeLogical.cy) - rect.top;
  408.         rect.OffsetRect(pt);
  409.     }
  410.     pt.x = pt.y = 0;
  411.  
  412.     if (rect.left > m_rectClip.right)
  413.         pt.x = m_rectClip.right - rect.left;
  414.     if (rect.top > m_rectClip.bottom)
  415.         pt.y = m_rectClip.bottom - rect.top;
  416.  
  417.     if (!((pt.x == 0) && (pt.y == 0)))
  418.         rect.OffsetRect(pt);
  419. }
  420.  
  421. CSize CDockState::GetScreenSize()
  422. {
  423.     return m_rectDevice.Size();
  424. }
  425.  
  426. void CDockState::SetScreenSize(CSize& size)
  427. {
  428.     m_sizeLogical = size;
  429.     m_bScaling = (size != m_rectDevice.Size());
  430. }
  431.  
  432. void CFrameWnd::LoadBarState(LPCTSTR lpszProfileName)
  433. {
  434.     CDockState state;
  435.     state.LoadState(lpszProfileName);
  436.     SetDockState(state);
  437. }
  438.  
  439. void CFrameWnd::SaveBarState(LPCTSTR lpszProfileName) const
  440. {
  441.     CDockState state;
  442.     GetDockState(state);
  443.     state.SaveState(lpszProfileName);
  444. }
  445.  
  446. void CFrameWnd::SetDockState(const CDockState& state)
  447. {
  448.     // first pass through barinfo's sets the m_pBar member correctly
  449.     // creating floating frames if necessary
  450.     for (int i = 0; i < state.m_arrBarInfo.GetSize(); i++)
  451.     {
  452.         CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
  453.         ASSERT(pInfo != NULL);
  454.         if (pInfo->m_bFloating)
  455.         {
  456.             // need to create floating frame to match
  457.             CMiniDockFrameWnd* pDockFrame = CreateFloatingFrame(
  458.                 pInfo->m_bHorz ? CBRS_ALIGN_TOP : CBRS_ALIGN_LEFT);
  459.             ASSERT(pDockFrame != NULL);
  460.             CRect rect(pInfo->m_pointPos, CSize(10, 10));
  461.             pDockFrame->CalcWindowRect(&rect);
  462.             pDockFrame->SetWindowPos(NULL, rect.left, rect.top, 0, 0,
  463.                 SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  464.             CDockBar* pDockBar =
  465.                 (CDockBar*)pDockFrame->GetDlgItem(AFX_IDW_DOCKBAR_FLOAT);
  466.             ASSERT(pDockBar != NULL);
  467.             ASSERT_KINDOF(CDockBar, pDockBar);
  468.             pInfo->m_pBar = pDockBar;
  469.         }
  470.         else // regular dock bar or toolbar
  471.         {
  472.             pInfo->m_pBar = GetControlBar(pInfo->m_nBarID);
  473.             ASSERT(pInfo->m_pBar != NULL); //toolbar id's probably changed
  474.         }
  475.         pInfo->m_pBar->m_nMRUWidth = pInfo->m_nMRUWidth;
  476.     }
  477.  
  478.     // the second pass will actually dock all of the control bars and
  479.     //  set everything correctly
  480.     for (i = 0; i < state.m_arrBarInfo.GetSize(); i++)
  481.     {
  482.         CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
  483.         ASSERT(pInfo != NULL);
  484.         if (pInfo->m_pBar != NULL)
  485.             pInfo->m_pBar->SetBarInfo(pInfo, this);
  486.     }
  487.  
  488.     // last pass shows all the floating windows that were previously shown
  489.     for (i = 0; i < state.m_arrBarInfo.GetSize(); i++)
  490.     {
  491.         CControlBarInfo* pInfo = (CControlBarInfo*)state.m_arrBarInfo[i];
  492.         ASSERT(pInfo != NULL);
  493.         ASSERT(pInfo->m_pBar != NULL);
  494.         if (pInfo->m_bFloating)
  495.         {
  496.             CFrameWnd* pFrameWnd = pInfo->m_pBar->GetParentFrame();
  497.             CDockBar* pDockBar = (CDockBar*)pInfo->m_pBar;
  498.             ASSERT_KINDOF(CDockBar, pDockBar);
  499.             if (pDockBar->GetDockedVisibleCount() > 0)
  500.             {
  501.                 pFrameWnd->RecalcLayout();
  502.                 pFrameWnd->ShowWindow(SW_SHOWNA);
  503.             }
  504.         }
  505.     }
  506.     DelayRecalcLayout();
  507. }
  508.  
  509. void CFrameWnd::GetDockState(CDockState& state) const
  510. {
  511.     state.Clear(); //make sure dockstate is empty
  512.     // get state info for each bar
  513.     POSITION pos = m_listControlBars.GetHeadPosition();
  514.     while (pos != NULL)
  515.     {
  516.         CControlBar* pBar = (CControlBar*)m_listControlBars.GetNext(pos);
  517.         ASSERT(pBar != NULL);
  518.         CControlBarInfo* pInfo = new CControlBarInfo;
  519.         pBar->GetBarInfo(pInfo);
  520.         state.m_arrBarInfo.Add(pInfo);
  521.     }
  522. }
  523.  
  524. // Note: GetBarInfo and SetBarInfo are not virtual since doing so adds
  525. //  to much code to an application which does not save and load docking
  526. //  state.  For this reason, the CControlBar implementations must
  527. //  delagate to CDockBar as appropriate.
  528.  
  529. void CControlBar::GetBarInfo(CControlBarInfo* pInfo)
  530. {
  531.     ASSERT_VALID(this);
  532.  
  533.     // get state info
  534.     pInfo->m_nBarID = _AfxGetDlgCtrlID(m_hWnd);
  535.     pInfo->m_pBar = this;
  536.     pInfo->m_bVisible = IsVisible(); // handles delayed showing and hiding
  537.     pInfo->m_nMRUWidth = m_nMRUWidth;
  538.  
  539.     if (m_pDockBar != NULL) // don't need position unless docked
  540.     {
  541.         CRect rect;
  542.         GetWindowRect(&rect);
  543.         m_pDockBar->ScreenToClient(&rect);
  544.         pInfo->m_pointPos = rect.TopLeft();
  545.  
  546.         ASSERT(m_pDockContext != NULL);
  547.         pInfo->m_bDocking = TRUE;
  548.         pInfo->m_uMRUDockID = m_pDockContext->m_uMRUDockID;
  549.         pInfo->m_rectMRUDockPos = m_pDockContext->m_rectMRUDockPos;
  550.         pInfo->m_dwMRUFloatStyle = m_pDockContext->m_dwMRUFloatStyle;
  551.         pInfo->m_ptMRUFloatPos = m_pDockContext->m_ptMRUFloatPos;
  552.     }
  553.  
  554.     // save dockbar specific parts
  555.     if (IsDockBar())
  556.         ((CDockBar*)this)->GetBarInfo(pInfo);
  557. }
  558.  
  559. void CControlBar::SetBarInfo(CControlBarInfo* pInfo, CFrameWnd* pFrameWnd)
  560. {
  561.     // dockbars are handled differently
  562.     if (IsDockBar())
  563.     {
  564.         ((CDockBar*)this)->SetBarInfo(pInfo, pFrameWnd);
  565.         return;
  566.     }
  567.  
  568.     // don't set position when not docked
  569.     UINT nFlags = SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER;
  570.     if (m_pDockBar == NULL)
  571.         nFlags |= SWP_NOMOVE;
  572.  
  573.     m_nMRUWidth = pInfo->m_nMRUWidth;
  574.     CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH | LM_COMMIT);
  575.  
  576.     if (pInfo->m_bDocking)
  577.     {
  578.         ASSERT(m_pDockContext != NULL);
  579.         // You need to call EnableDocking before calling LoadBarState
  580.  
  581.         m_pDockContext->m_uMRUDockID = pInfo->m_uMRUDockID;
  582.         m_pDockContext->m_rectMRUDockPos = pInfo->m_rectMRUDockPos;
  583.         m_pDockContext->m_dwMRUFloatStyle = pInfo->m_dwMRUFloatStyle;
  584.         m_pDockContext->m_ptMRUFloatPos = pInfo->m_ptMRUFloatPos;
  585.     }
  586.  
  587.     // move and show/hide the window
  588.     SetWindowPos(NULL, pInfo->m_pointPos.x, pInfo->m_pointPos.y, 0, 0,
  589.         nFlags | (pInfo->m_bVisible ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));
  590. }
  591.  
  592. void CDockBar::GetBarInfo(CControlBarInfo* pInfo)
  593. {
  594.     ASSERT_VALID(this);
  595.  
  596.     pInfo->m_bDockBar = TRUE;
  597.     pInfo->m_bFloating = m_bFloating;
  598.     if (m_bFloating)
  599.     {
  600.         CRect rect;
  601.         GetWindowRect(&rect);
  602.         pInfo->m_pointPos = rect.TopLeft();
  603.     }
  604.     pInfo->m_bHorz = m_dwStyle & CBRS_ORIENT_HORZ ? TRUE : FALSE;
  605.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  606.     {
  607.         CControlBar* pBar = (CControlBar*)m_arrBars[i];
  608.         if (pBar != NULL && HIWORD(pBar) == 0)
  609.         {
  610.             WORD w = LOWORD(((DWORD)pBar));
  611.             void* pRememberedID = (void *)MAKELONG(w, 1);
  612.             pInfo->m_arrBarID.Add(pRememberedID);
  613.         }
  614.         else
  615.         {
  616.             pInfo->m_arrBarID.Add(pBar == NULL ?
  617.                 0 : (void*)_AfxGetDlgCtrlID(pBar->m_hWnd));
  618.         }
  619.     }
  620. }
  621.  
  622. void CDockBar::SetBarInfo(CControlBarInfo* pInfo, CFrameWnd* pFrameWnd)
  623. {
  624.     ASSERT(pFrameWnd != NULL);
  625.     ASSERT_VALID(this);
  626.  
  627.     int nSize = pInfo->m_arrBarID.GetSize();
  628.     // don't insert trailing NULLs
  629.     while (nSize != 0 && (pInfo->m_arrBarID[nSize-1] == NULL ||
  630.         pInfo->m_arrBarID[nSize-1] == (void*)MAKELONG(0, 1)))
  631.     {
  632.         nSize--;
  633.     }
  634.     // start at 1 to avoid inserting leading NULL
  635.     for (int i = 1; i < nSize; i++)
  636.     {
  637.         CControlBar* pBar = NULL;
  638.         if (HIWORD(pInfo->m_arrBarID[i]) == 0)
  639.         {
  640.             pBar = pFrameWnd->GetControlBar((UINT)pInfo->m_arrBarID[i]);
  641.             if (pBar != NULL)
  642.             {
  643.                 if (pBar->GetParent() != this)
  644.                     pBar->SetParent(this);
  645.                 if (pBar->m_pDockBar != NULL)
  646.                     pBar->m_pDockBar->RemoveControlBar(pBar, -1, -1);
  647.                 //remove the ID place holder if it exists in this dockbar
  648.                 RemovePlaceHolder(pBar);
  649.                 pBar->m_pDockBar = this;
  650.  
  651.                 // align correctly and turn on all borders
  652.                 DWORD dwStyle = pBar->GetBarStyle();
  653.                 dwStyle &= ~(CBRS_ALIGN_ANY);
  654.                 dwStyle |= (m_dwStyle & CBRS_ALIGN_ANY);
  655.                 dwStyle |= CBRS_BORDER_ANY;
  656.                 if (m_bFloating)
  657.                     dwStyle |= CBRS_FLOATING;
  658.                 else
  659.                     dwStyle &= ~CBRS_FLOATING;
  660.                 pBar->SetBarStyle(dwStyle);
  661.  
  662.                 // handle special case for floating toolbars
  663.                 if (m_bFloating)
  664.                 {
  665.                     // set CBRS_FLOAT_MULTI style if docking bar has it
  666.                     if (pBar->m_dwDockStyle & CBRS_FLOAT_MULTI)
  667.                         m_dwStyle |= CBRS_FLOAT_MULTI;
  668.  
  669.                     // set owner of parent frame as appropriate
  670.                     CFrameWnd* pDockFrame = pBar->GetParentFrame();
  671.                     ASSERT_VALID(pDockFrame);
  672.                     ASSERT(pDockFrame != pBar->m_pDockSite);
  673.                     if (pDockFrame->m_hWndOwner == NULL)
  674.                         pDockFrame->m_hWndOwner = pBar->m_hWnd;
  675.  
  676.                     if (pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
  677.                         pDockFrame->ModifyStyle(MFS_MOVEFRAME, 0);
  678.                 }
  679.  
  680.                 // set initial text of the dock bar
  681.                 if (i == 1 && !(m_dwStyle & CBRS_FLOAT_MULTI))
  682.                 {
  683.                     CString strTitle;
  684.                     pBar->GetWindowText(strTitle);
  685.                     AfxSetWindowText(m_hWnd, strTitle);
  686.                 }
  687.             }
  688.         }
  689.         else
  690.         {
  691.             WORD w = LOWORD(((DWORD)pInfo->m_arrBarID[i]));
  692.             pBar = (CControlBar*)(MAKELONG(w, 0));
  693.             RemovePlaceHolder(pBar);
  694.         }
  695.         m_arrBars.InsertAt(i, pBar);
  696.     }
  697.     int nArrSize = m_arrBars.GetSize();
  698.     if (nSize < nArrSize && m_arrBars[nSize] != NULL)
  699.     {
  700.         m_arrBars.InsertAt(nSize, (void*)NULL);
  701.         nArrSize++;
  702.     }
  703.     if (m_arrBars[nArrSize-1] != NULL)
  704.         m_arrBars.InsertAt(nArrSize, (void*)NULL);
  705.     ASSERT_VALID(this);
  706. }
  707.  
  708. #ifdef AFX_INIT_SEG
  709. #pragma code_seg(AFX_INIT_SEG)
  710. #endif
  711.  
  712. IMPLEMENT_SERIAL(CDockState, CObject, 0)
  713.  
  714. /////////////////////////////////////////////////////////////////////////////
  715.