home *** CD-ROM | disk | FTP | other *** search
/ Prima Shareware 3 / DuCom_Prima-Shareware-3_cd1.bin / PROGRAMO / C / MRCE / SOURCE.ZIP / FRAMEWND.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-20  |  28.3 KB  |  868 lines

  1. // MRCEXT: Micro Focus Extension DLL for MFC 2.1+
  2. // Copyright (C)1994-5    Micro Focus Inc, 2465 East Bayshore Rd, Palo Alto, CA 94303.
  3. // 
  4. //  This program is free software; you can redistribute it and/or modify
  5. //  it under the terms of the GNU General Public License as published by
  6. //  the Free Software Foundation. In addition, you may also charge for any
  7. //  application    using MRCEXT, and are under no obligation to supply source
  8. //  code. You must accredit Micro Focus Inc in the "About Box", or banner
  9. //  of your application. 
  10. //
  11. //  This program is distributed in the hope that it will be useful,
  12. //  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. //  GNU General Public License for more details.
  15. //
  16. //  You should also have received a copy of the GNU General Public License with this
  17. //  software, also indicating additional rights you have when using MRCEXT.  
  18. //
  19. //
  20. // FRAMEWND.CPP
  21. // $Date:   04 Dec 1995 15:24:28  $
  22. // $Revision:   1.0  $
  23. // $Author:   MRC  $
  24. // framewnd.cpp : implementation file
  25. //
  26.  
  27. #include "mrcstafx.h"
  28. #include "mrcpriv.h"
  29.  
  30. extern MRC_AUX_DATA afxData;
  31.  
  32. #ifdef _DEBUG
  33. #undef THIS_FILE
  34. static char BASED_CODE THIS_FILE[] = __FILE__;
  35. #endif
  36.  
  37. // dwDockBarMap - table mapping standard ID's to styles
  38. // Exists in MFC30.DLL, but not exported, so have to code it here
  39. const DWORD CFrameWnd::dwDockBarMap[4][2] =
  40. {
  41.         { AFX_IDW_DOCKBAR_TOP,      CBRS_TOP    },
  42.         { AFX_IDW_DOCKBAR_BOTTOM,   CBRS_BOTTOM },
  43.         { AFX_IDW_DOCKBAR_LEFT,     CBRS_LEFT   },
  44.         { AFX_IDW_DOCKBAR_RIGHT,    CBRS_RIGHT  },
  45. };
  46.  
  47.  
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CMRCFrameWndSizeDock
  50.  
  51. IMPLEMENT_DYNCREATE(CMRCFrameWndSizeDock, CFrameWnd)
  52.  
  53. CMRCFrameWndSizeDock::CMRCFrameWndSizeDock()
  54. {
  55. }
  56.  
  57. CMRCFrameWndSizeDock::~CMRCFrameWndSizeDock()
  58. {
  59.     CMRCSizeControlBar::TidyUp();        // tidy up any outstanding control bars...
  60. #ifdef _DEBUG
  61.     CObArray arrWnd;
  62.     GetFloatingBars(arrWnd);  // debug code to see what's still around !
  63. #endif
  64. }
  65.  
  66.  
  67. BEGIN_MESSAGE_MAP(CMRCFrameWndSizeDock, CFrameWnd)
  68.         //{{AFX_MSG_MAP(CMRCFrameWndSizeDock)
  69.     ON_WM_SYSCOLORCHANGE()
  70.     //}}AFX_MSG_MAP
  71. END_MESSAGE_MAP()
  72.  
  73.  
  74. /////////////////////////////////////////////////////////////////////////////
  75. // CMRCFrameWndSizeDock message handlers
  76.  
  77. // dock bars will be created in the order specified by dwDockBarMap
  78. // this also controls which gets priority during layout
  79. // this order can be changed by calling EnableDocking repetitively
  80. // with the exact order of priority
  81. //------------------------------------------------------------------------------
  82. void CMRCFrameWndSizeDock::EnableDocking(DWORD dwDockStyle)
  83. // This is over-ridden primarily because we need to insert our own CDockBar class
  84. // to handle the recalc layout, and this is the place they are created.
  85. //------------------------------------------------------------------------------
  86. {
  87.     // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  88.     ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
  89.  
  90.     m_pFloatingFrameClass = RUNTIME_CLASS(CSizableMiniDockFrameWnd); // protected member
  91.     for (int i = 0; i < 4; i++)
  92.     {
  93.         if (dwDockBarMap[i][1] & dwDockStyle & CBRS_ALIGN_ANY)          // protected
  94.         {
  95.             CDockBar* pDock = (CDockBar*)GetControlBar(dwDockBarMap[i][0]);
  96.             if (pDock == NULL)
  97.                 {
  98.                     pDock = new CSizeDockBar;
  99.                     if (!pDock->Create(this,
  100.                                        WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE |
  101.                                               dwDockBarMap[i][1], dwDockBarMap[i][0]))
  102.                     {
  103.                         AfxThrowResourceException();
  104.                     }
  105.                 }
  106.         }
  107.     }
  108. }
  109.  
  110.  
  111. //-----------------------------------------------------------------------------
  112. void CMRCFrameWndSizeDock::TileDockedBars(DWORD dwDockStyle)
  113. // Tiles the bars docked in the specified orientation
  114. //-----------------------------------------------------------------------------
  115. {
  116.     for (int i = 0; i < 4; i++)
  117.     {
  118.         if (dwDockBarMap[i][1] & dwDockStyle & CBRS_ALIGN_ANY)  //protected
  119.         {
  120.             CSizeDockBar* pDock = (CSizeDockBar*)GetControlBar(dwDockBarMap[i][0]);
  121.             // ASSERT(pDock == NULL || pDock->IsKindOf(RUNTIME_CLASS(CSizeDockBar)));
  122.             if (pDock != NULL && (pDock->m_dwStyle & dwDockStyle))
  123.             {
  124.                 pDock->TileDockedBars();
  125.             }
  126.         }
  127.        }
  128. }
  129.  
  130.  
  131.  
  132. //-----------------------------------------------------------------------------
  133. void CMRCFrameWndSizeDock::ArrangeFloatingBars(DWORD dwOrient)
  134. //-----------------------------------------------------------------------------
  135. {
  136.     CObArray arrWnd;
  137.     GetFloatingBars(arrWnd);
  138.     ArrangeWindows(arrWnd, dwOrient);
  139. }
  140.  
  141.  
  142. //-----------------------------------------------------------------------------
  143. void CMRCMDIFrameWndSizeDock::ArrangeFloatingBars(DWORD dwOrient)
  144. //-----------------------------------------------------------------------------
  145. {
  146.     CObArray arrWnd;
  147.     GetFloatingBars(arrWnd);
  148.     ASSERT (this->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)));
  149.      ASSERT(m_hWndMDIClient != NULL);
  150.     // Use the MDI Client window - not the normal client area
  151.     CWnd * pMDIClientWnd = CWnd::FromHandle(m_hWndMDIClient);
  152.     ArrangeWindowsInWindow (pMDIClientWnd, arrWnd, dwOrient);
  153.  
  154.     // clear all the MOVED flags for sizeable windows...
  155.     for (int i = arrWnd.GetUpperBound(); i >= 0; i--)
  156.     {
  157.         CSizableMiniDockFrameWnd * pFloatFrame = (CSizableMiniDockFrameWnd *) arrWnd[i]; 
  158.         
  159.         ASSERT(pFloatFrame->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd)));
  160.         pFloatFrame->ModifyStyle(CBRS_MOVED_BY_USER, 0);
  161.         /*
  162.         if (pFloatFrame->IsKindOf(RUNTIME_CLASS(CSizableMiniDockFrameWnd)))
  163.         {        
  164.             CMRCSizeControlBar* pBar = ((CSizeDockBar *)(&(pFloatFrame->m_wndDockBar)))->GetFirstControlBar();
  165.             if (pBar != NULL)
  166.                 pBar->ModifyStyle(CBRS_MOVED_BY_USER, 0);
  167.         }  */
  168.     }
  169. }
  170.  
  171.  
  172. //-----------------------------------------------------------------------------
  173. void CMRCMDIFrameWndSizeDock::ArrangeWindows(CObArray & arrWnd, DWORD dwOrient)
  174. //-----------------------------------------------------------------------------
  175. {
  176.     ASSERT (this->IsKindOf(RUNTIME_CLASS(CMDIFrameWnd)));
  177.      ASSERT(m_hWndMDIClient != NULL);
  178.     // Use the MDI Client window - not the normal client area
  179.     CWnd * pMDIClientWnd = CWnd::FromHandle(m_hWndMDIClient);
  180.     ArrangeWindowsInWindow (pMDIClientWnd, arrWnd, dwOrient);
  181. }
  182.  
  183.  
  184.  
  185. //-----------------------------------------------------------------------------
  186. void CMRCFrameWndSizeDock::ArrangeWindows(CObArray & arrWnd, DWORD dwOrient)
  187. //-----------------------------------------------------------------------------
  188. {
  189.     ArrangeWindowsInWindow (this, arrWnd, dwOrient);
  190. }
  191.  
  192.  
  193. //-----------------------------------------------------------------
  194. void CMRCFrameWndSizeDock::GetFloatingBars(CObArray & arrWnd)
  195. // Appends the floating bars, visible bars to an array
  196. //-----------------------------------------------------------------
  197. {
  198.     CPtrList & listControlBars = m_listControlBars;
  199.     
  200.     POSITION pos = listControlBars.GetHeadPosition();
  201.     while (pos != NULL)
  202.     {
  203.         CControlBar* pBar = (CControlBar*)listControlBars.GetNext(pos);
  204.         ASSERT(pBar != NULL);
  205.         if (!pBar->IsDockBar() && pBar->IsFloating() && pBar->IsVisible())     // not a dockbar and floating....
  206.         {
  207.             ASSERT(pBar->m_pDockBar != NULL);
  208.             CWnd * pFloatFrame = ((CWnd *)pBar->m_pDockBar)->GetParent(); 
  209.             ASSERT(pBar != NULL);
  210.             arrWnd.Add(pFloatFrame);
  211.         }
  212.     }
  213. }
  214.  
  215.  
  216. //------------------------------------------------------------------------
  217. void CMRCFrameWndSizeDock::DestroyDynamicBars()
  218. // Destroys the dynamic bars in an application
  219. //------------------------------------------------------------------------
  220. {
  221.     CPtrList & listControlBars = m_listControlBars;
  222.     
  223.     CObArray arrBars;
  224.     CMRCSizeControlBar* pBar;
  225.     
  226.     // pass through the list and build an array of bars to destroy
  227.     POSITION pos = listControlBars.GetHeadPosition();
  228.     while (pos != NULL)
  229.     {
  230.         pBar = (CMRCSizeControlBar *) listControlBars.GetNext(pos);
  231.         ASSERT(pBar != NULL);
  232.         if (pBar->IsKindOf(RUNTIME_CLASS(CMRCSizeControlBar)) &&
  233.                 (pBar->m_Style & SZBARF_AUTOTIDY) != 0)
  234.             arrBars.Add(pBar);
  235.     }
  236.  
  237.     // now destroy these bars...
  238.     for (int i = arrBars.GetUpperBound(); i >= 0; i--)
  239.     {
  240.         pBar = (CMRCSizeControlBar *) arrBars[i];
  241.         pBar->DestroyWindow();
  242.     }
  243. }
  244.  
  245.  
  246. struct BarSizeSaveInfo 
  247. {
  248.     CSize   FloatSize;         // floating size
  249.     CSize    HorzDockSize;      // size when docked horizontally
  250.     CSize   VertDockSize;      // size when docked vertically
  251. };
  252.  
  253.  
  254.  
  255. //------------------------------------------------------------------------
  256. void CMRCFrameWndSizeDock::SaveSizeBarState(LPCTSTR pszProfileName)
  257. //------------------------------------------------------------------------
  258. {
  259.     DestroyDynamicBars();            // remove bars allocated dynamically
  260.                                     // - we reload these at present
  261.     
  262.     CFrameWnd::SaveBarState(pszProfileName);    // save the raw states
  263.     SaveBarSizes(pszProfileName, TRUE);            // save additional info
  264.     AfxGetApp()->WriteProfileInt(pszProfileName, REG_VERSION, REG_VERSION_NO);
  265. }
  266.  
  267.  
  268.  
  269. //------------------------------------------------------------------------
  270. void CMRCFrameWndSizeDock::LoadSizeBarState(LPCTSTR pszProfileName)
  271. //------------------------------------------------------------------------
  272. {
  273.     // check the registry version. If it doesn't match, do nothing...
  274.     // this prevents us trying to load registry info from a previous version, that
  275.     // is unlikely to make sense to the code below.
  276.     if (AfxGetApp()->GetProfileInt(pszProfileName, REG_VERSION, 0) != REG_VERSION_NO)
  277.         return;
  278.     CFrameWnd::LoadBarState(pszProfileName);
  279.     SaveBarSizes(pszProfileName, FALSE);        // load the sizes back
  280. }
  281.  
  282.  
  283. //------------------------------------------------------------------------
  284. void CMRCFrameWndSizeDock::SaveBarSizes(LPCTSTR pszSection, BOOL bSave)
  285. // Saves all the sizeable bars info
  286. // uses the "ID" of the bar as a key. The bar will already exist on a 
  287. // load, so this seems safe enough
  288. //------------------------------------------------------------------------
  289. {
  290.     struct BarSizeSaveInfo BSI;
  291.     CMRCSizeControlBar* pBar;
  292.     char szBarId[20] = "BarSize_";
  293.     
  294.     POSITION pos = m_listControlBars.GetHeadPosition();
  295.     while (pos != NULL)
  296.     {
  297.         pBar = (CMRCSizeControlBar *) m_listControlBars.GetNext(pos);
  298.         ASSERT(pBar != NULL);
  299.         if (pBar->IsKindOf(RUNTIME_CLASS(CMRCSizeControlBar)))
  300.         {
  301.             UINT nID = pBar->GetDlgCtrlID();
  302.             _itoa(nID, szBarId + 8, 10);
  303.  
  304.             if (bSave)
  305.             {
  306.                 BSI.VertDockSize     = pBar->m_VertDockSize;
  307.                 BSI.HorzDockSize    = pBar->m_HorzDockSize;
  308.                 BSI.FloatSize         = pBar->m_FloatSize;
  309.                 MRCWriteProfileBinary (pszSection, szBarId, &BSI, sizeof BSI);
  310.             }
  311.             else
  312.             {
  313.                 if (MRCGetProfileBinary (pszSection, szBarId, &BSI, sizeof BSI))
  314.                 {
  315.                     pBar->m_VertDockSize    = BSI.VertDockSize;
  316.                     pBar->m_HorzDockSize    = BSI.HorzDockSize;
  317.                     pBar->m_FloatSize         = BSI.FloatSize;
  318.                     
  319.                     // Now have to set the actual window size. The reason for this is
  320.                     // that the Adjustment algorithm looks at actual window rect sizes, so
  321.                     // it doesn't have to worry about borders etc.
  322.                     CSize NewSize = pBar->CalcFixedLayout(FALSE, (pBar->m_dwStyle & CBRS_ORIENT_HORZ));
  323.                     pBar->SetWindowPos(0, 0, 0, NewSize.cx, NewSize.cy, 
  324.                                 SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER | SWP_NOMOVE);
  325.                     if (pBar->IsFloating())
  326.                     {
  327.                         CFrameWnd * pFrame = pBar->GetParentFrame();
  328.                         if (pFrame != NULL)
  329.                             pFrame->RecalcLayout();
  330.                     }
  331.                 }
  332.             }
  333.  
  334. #ifdef _VERBOSE_TRACE
  335.             CString strTitle;
  336.             pBar->GetWindowText(strTitle);
  337.             TRACE("%s '%s' ID=%d Float(%d,%d) Horz(%d,%d) Vert(%d,%d)\n",
  338.                     LPCTSTR(pBar->GetRuntimeClass()->m_lpszClassName),
  339.                     LPCTSTR(strTitle), nID,
  340.                     pBar->m_FloatSize.cx, pBar->m_FloatSize.cy,
  341.                     pBar->m_HorzDockSize.cx,  pBar->m_HorzDockSize.cy,
  342.                     pBar->m_VertDockSize.cx,  pBar->m_VertDockSize.cy);
  343. #endif
  344.         }
  345.     }
  346.  
  347. }
  348.  
  349.  
  350.  
  351.  
  352.  
  353. //-----------------------------------------------------------------
  354. // private class - don't want this exported !
  355. //-----------------------------------------------------------------
  356. class CWndSpaceElt : public CObject
  357. {
  358. public:
  359.     WORD ht;
  360.     WORD wd;
  361. };
  362.  
  363.  
  364.  
  365.  
  366. //-----------------------------------------------------------------
  367. // helper function to find list position
  368. void PositionInSpcList(CWnd *pWnd, CObList & SpcList, DWORD dwOrient,
  369.                                 CWnd * pParentWnd, CSize & ParentSize, HDWP hDwp)    
  370. //-----------------------------------------------------------------
  371. {
  372.  
  373.     CRect WndRect;
  374.     pWnd->GetWindowRect(&WndRect);        // external dimensions of the window
  375.     CSize WndSize;
  376.     WndSize = WndRect.Size();            // size of rectangle
  377.        POSITION pos;
  378.  
  379. #ifdef _DEBUG
  380.     //TRACE("Inserting Window: cx = %d, cy = %d\n", WndSize.cx, WndSize.cy);
  381.     pos = SpcList.GetHeadPosition();
  382.     while (pos != NULL)
  383.     {
  384.         CWndSpaceElt * pSpcElt = (CWndSpaceElt *)SpcList.GetNext(pos);
  385.         ASSERT(pSpcElt != NULL);
  386.  
  387.         //TRACE("ht= %d w=%d\n", pSpcElt->ht, pSpcElt->wd);
  388.     }
  389. #endif
  390.  
  391.     int nHt = WndSize.cy;            // height of window....
  392.     int nWd = WndSize.cx;            // width of window (used below)
  393.     int nHtLeft;
  394.  
  395.     int nCurY = 0;                    // current Y position of scan
  396.     int nMinX = 0xffff;                // minimum X position found so far;
  397.     int nMinY;                        // again should be ok...
  398.     
  399.     POSITION MinListPos = NULL;        // position in the list with this minimum X;
  400.     
  401.     pos = SpcList.GetHeadPosition();
  402.     while (pos != NULL)
  403.     {
  404.         POSITION posCurrent = pos;
  405.         CWndSpaceElt * pSpcElt = (CWndSpaceElt *)SpcList.GetNext(pos);
  406.         ASSERT(pSpcElt != NULL);
  407.         
  408.         // if we inserted in this position, what would the width be ? 
  409.         // Set nHtLeft, ThisPosX accordingly....
  410.         nHtLeft = nHt;
  411.         int nThisX = 0;
  412.         CWndSpaceElt * pLoopSpcElt = pSpcElt;
  413.         POSITION posLoop = pos;
  414.         while (TRUE) 
  415.         {
  416.             nThisX = max (nThisX, pLoopSpcElt->wd);
  417.             if (nThisX > nMinX)
  418.                 break;        // give up if we're already beyond the current minimum
  419.             nHtLeft -= pSpcElt->ht;
  420.             if (nHtLeft <= 0)
  421.             {
  422.                 if (nThisX < nMinX)
  423.                 {
  424.                     nMinX = nThisX;
  425.                     MinListPos = posCurrent;    // acutually the position after the current index in the list
  426.                     nMinY = nCurY;
  427.                 }
  428.                 break;
  429.             }
  430.             if (posLoop == NULL)
  431.                 break;            // end of the list            
  432.             pLoopSpcElt = (CWndSpaceElt *) SpcList.GetNext(posLoop);
  433.         }
  434.         
  435.            nCurY += pSpcElt->ht;    // update current Y position.
  436.        }
  437.     
  438.     
  439.     if (MinListPos == NULL) // window wouldn't fit anywhere in the window cleanly, 
  440.         return;                // ignore this for now
  441.  
  442.     ASSERT(MinListPos != NULL && nMinX < 0xffff);
  443.     
  444.     // work out the new position for the window
  445.     // Might want to delay window positioning in future
  446.     CPoint WndPt;
  447.     WndPt.x = ((dwOrient & CBRS_ARRANGE_LEFT) ?  nMinX : ParentSize.cx - nMinX - WndSize.cx);
  448.     WndPt.y = ((dwOrient & CBRS_ARRANGE_TOP)  ?  nMinY : ParentSize.cy - nMinY - WndSize.cy);
  449.   
  450.     // if not child of requested window, convert co-ords to Screen
  451.     if ((pWnd->GetStyle() & WS_POPUP) || pWnd->GetParent() != pParentWnd)
  452.         pParentWnd->ClientToScreen(&WndPt);
  453.  
  454.  
  455.     CRect rcWnd;
  456.     pWnd->GetWindowRect(rcWnd);
  457.     // attempt to optimize by only moving windows that have changed position...
  458.     if (rcWnd.TopLeft() != WndPt || rcWnd.Size() != WndSize)
  459.     {
  460.         if (hDwp == NULL)
  461.               pWnd->SetWindowPos(NULL, WndPt.x, WndPt.y, WndSize.cx, WndSize.cy,
  462.                                 SWP_NOSIZE | SWP_NOZORDER);
  463.         else
  464.             ::DeferWindowPos(hDwp, pWnd->m_hWnd, NULL, WndPt.x,  WndPt.y, WndSize.cx, WndSize.cy,
  465.                                 SWP_NOSIZE | SWP_NOZORDER);
  466.     }
  467.     
  468.     // now update the SpcList.
  469.     nHtLeft = nHt;
  470.     pos = MinListPos;
  471.     CWndSpaceElt * pSpcElt = (CWndSpaceElt *)SpcList.GetAt(pos);
  472.     while (pos != NULL)
  473.     {
  474.         nHtLeft -= pSpcElt->ht;
  475.         if (nHtLeft < 0)    
  476.             break;
  477.         
  478.         CWndSpaceElt * pOldElt = pSpcElt;
  479.         POSITION OldPos = pos;
  480.         pSpcElt = (CWndSpaceElt *) SpcList.GetNext(pos);
  481.         
  482.         SpcList.RemoveAt(OldPos);                // move that element
  483.         delete pOldElt;
  484.     }
  485.  
  486.     // should now be looking at the element we need to shrink...
  487.     // NB: If pos = NULL then we removed to the end of the list...
  488.     pSpcElt->ht = - nHtLeft;        // adjust height of element that left.
  489.  
  490.     pSpcElt = new CWndSpaceElt;
  491.     pSpcElt->wd = nMinX + nWd;
  492.     pSpcElt->ht = nHt;
  493.     if (pos == NULL)
  494.         SpcList.AddTail(pSpcElt);
  495.     else
  496.         SpcList.InsertBefore(pos, pSpcElt);
  497. }
  498.  
  499.  
  500.  
  501. //--------------------------------------------------------------------------------
  502. void ArrangeWindowsInWindow (CWnd * pParentWnd, CObArray & arrWnd, DWORD dwOrient)
  503. // Arranges the windows within the rectangle of another window.
  504. //--------------------------------------------------------------------------------
  505. {
  506.     CRect ClientRect;
  507.     pParentWnd->GetClientRect(&ClientRect);
  508.     
  509.     CSize ParentSize = ClientRect.Size();
  510.     CObList SpcList;
  511.     
  512.     // add initial Arrange rectangle to the list;    
  513.     CWndSpaceElt * pSpcElt = new CWndSpaceElt;
  514.     pSpcElt->wd = 0;
  515.     pSpcElt->ht = ClientRect.Height();
  516.     SpcList.AddTail(pSpcElt); 
  517.  
  518.     HDWP hDWP = BeginDeferWindowPos(arrWnd.GetSize());       // defer window moves to save on refresh
  519.  
  520.     // iterate thru all the windows in the list looking for a position to put it
  521.     for (int nWndNo = 0; nWndNo < arrWnd.GetSize(); nWndNo++)
  522.     {
  523.         CWnd * pWnd = (CWnd *)arrWnd[nWndNo];
  524.         ASSERT(pWnd != NULL);            // pretty obvious....
  525.         PositionInSpcList(pWnd, SpcList, dwOrient, pParentWnd, ParentSize, hDWP);
  526.     } 
  527.  
  528.     if (hDWP != NULL)
  529.         ::EndDeferWindowPos(hDWP);        // move the windows
  530.  
  531.     // Remove elements from the SpcList;
  532.     while (!SpcList.IsEmpty())
  533.     {
  534.         CWndSpaceElt * pElt = (CWndSpaceElt *) SpcList.GetTail();
  535.         delete pElt;
  536.         SpcList.RemoveTail();
  537.     }
  538. }
  539.  
  540.  
  541.  
  542.  
  543. ////////////////////////////////////////////////////////////////////////////////
  544. // Diagnostics
  545. #ifdef _DEBUG
  546. void CMRCFrameWndSizeDock::AssertValid() const
  547. {
  548.         CFrameWnd::AssertValid();
  549. }
  550.  
  551.  
  552. void CMRCFrameWndSizeDock::Dump(CDumpContext& dc) const
  553. {
  554.         CFrameWnd::Dump(dc);
  555.         dc << "\nCMRCFrameWndSizeDock - dockbars";
  556.         // for (int i = 0; i < 4; i++)
  557.         // {
  558.         // GetControlBar is not a const function, so we can;t use it here ... bugger..
  559.         //      // CSizeDockBar* pDock = (CSizeDockBar*)GetControlBar(dwDockBarMap[i][0]);      //protected
  560.         //      if (pDock != NULL)
  561.     //          {
  562.         //              pDock->Dump(dc);
  563.         //      }
  564.         // }
  565. }
  566. #endif
  567.  
  568.  
  569.  
  570.  
  571. ////////////////////////////////////////////////////////////////////////////////
  572. ////////////////////////////////////////////////////////////////////////////////
  573. // CMRCMDIFrameWndSizeDock frame
  574. ////////////////////////////////////////////////////////////////////////////////
  575. ////////////////////////////////////////////////////////////////////////////////
  576.  
  577. IMPLEMENT_DYNCREATE(CMRCMDIFrameWndSizeDock, CMDIFrameWnd)
  578.  
  579. CMRCMDIFrameWndSizeDock::CMRCMDIFrameWndSizeDock()
  580. {
  581. }
  582.  
  583. CMRCMDIFrameWndSizeDock::~CMRCMDIFrameWndSizeDock()
  584. {
  585.     CMRCSizeControlBar::TidyUp();        // tidy up any outstanding control bars...
  586. #ifdef _DEBUG
  587.     CObArray arrWnd;
  588.     GetFloatingBars(arrWnd);  // debug code to see what's still around !
  589. #endif
  590. }
  591.  
  592.  
  593.  
  594.  
  595. BEGIN_MESSAGE_MAP(CMRCMDIFrameWndSizeDock, CMDIFrameWnd)
  596.         //{{AFX_MSG_MAP(CMRCMDIFrameWndSizeDock)
  597.     ON_WM_SYSCOLORCHANGE()
  598.     //}}AFX_MSG_MAP
  599. END_MESSAGE_MAP()
  600.  
  601.  
  602.  
  603. void CMRCMDIFrameWndSizeDock::FloatControlBarInMDIChild(CControlBar* pBar, CPoint point, DWORD dwStyle)
  604. // float a control bar in an MDI Child window
  605. {
  606.     ASSERT(pBar != NULL);
  607.  
  608.     // point is in screen co-ords - map to client
  609.     ScreenToClient(&point);
  610.     point.x = max (point.x, 0);        // clip to (0,0) - prevents floating beyond top left of window
  611.     point.y = max (point.y, 0);
  612.  
  613.  
  614.     // If the bar is already floating in an MDI child, then just move it
  615.     // MFC has a similar optimization for CMiniDockFrameWnd 
  616.     if (pBar->m_pDockSite != NULL && pBar->m_pDockBar != NULL)
  617.     {
  618.         CDockBar* pDockBar = pBar->m_pDockBar;
  619.         ASSERT(pDockBar->IsKindOf(RUNTIME_CLASS(CDockBar)));
  620.         CFrameWnd* pDockFrame = (CFrameWnd*)pDockBar->GetParent();
  621.         ASSERT(pDockFrame != NULL);
  622.         ASSERT(pDockFrame->IsKindOf(RUNTIME_CLASS(CFrameWnd)));
  623.         if (pDockFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFloatWnd)))
  624.         {
  625.              // already a floating as an MDI child, so just move it.
  626.             if (pDockBar->m_bFloating && pDockBar->GetDockedCount() == 1 &&
  627.                 (dwStyle & pDockBar->m_dwStyle & CBRS_ALIGN_ANY) != 0)
  628.              {
  629.                 pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0,
  630.                             SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  631.                 return;
  632.             }
  633.         }
  634.     }
  635.  
  636.     // Create a CMRCMDIFloatWnd, and dock the bar into it.
  637.     CMRCMDIFloatWnd * pDockFrame = (CMRCMDIFloatWnd *)(RUNTIME_CLASS(CMRCMDIFloatWnd))->CreateObject();
  638.     ASSERT(pDockFrame != NULL);
  639.     if (!pDockFrame->Create(this, dwStyle))
  640.         AfxThrowResourceException();
  641.     
  642.     pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0,
  643.         SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  644.     
  645.     if (pDockFrame->m_hWndOwner == NULL)
  646.         pDockFrame->m_hWndOwner = pBar->m_hWnd;
  647.  
  648.     // Gets the dockbar created by the CMRCMDIFloatWnd
  649.     CDockBar* pDockBar = (CDockBar*)pDockFrame->GetDlgItem(AFX_IDW_DOCKBAR_FLOAT);
  650.     ASSERT(pDockBar != NULL);
  651.     ASSERT(pDockBar->IsKindOf(RUNTIME_CLASS(CDockBar)));
  652.  
  653.     ASSERT(pBar->m_pDockSite == this);
  654.     // if this assertion occurred it is because the parent of pBar was not
  655.     //  initially this CFrameWnd when pBar's OnCreate was called
  656.     // (this control bar should have been created with a different
  657.     //  parent initially)
  658.  
  659.     pDockBar->DockControlBar(pBar);
  660.     pDockFrame->RecalcLayout();
  661.     pDockFrame->ShowWindow(SW_SHOWNA);
  662.     pDockFrame->UpdateWindow(); 
  663. }    
  664.  
  665.  
  666. //--------------------------------------------------------------------------------------------
  667. void CMRCMDIFrameWndSizeDock::UnFloatInMDIChild(CControlBar* pBar, CPoint point, DWORD dwStyle)
  668. // removes the control bar from an MDI floating window, and then floats the bar
  669. //--------------------------------------------------------------------------------------------
  670. {
  671.     ASSERT(pBar != NULL);
  672.     ASSERT(pBar->IsFloating());
  673.     CMRCMDIFloatWnd * pFloatFrame = (CMRCMDIFloatWnd *)pBar->GetParentFrame();
  674.     ASSERT(pFloatFrame->IsKindOf(RUNTIME_CLASS(CMRCMDIFloatWnd)));
  675.  
  676.     // This is basically the code from MFC's CFrameWnd::FloatControlBar(), with the
  677.     // test to avoid destroying/creating the floating frame window removed. 
  678.     // Tried explicitly removing the control bar, but this doesn't work as it destroys the
  679.     // CMDIFloatWnd, which in turn kills the child control bar. So need to create the floating
  680.     // frame first, and then dock into this.  
  681.     CMiniDockFrameWnd* pDockFrame = CreateFloatingFrame(dwStyle);
  682.     ASSERT(pDockFrame != NULL);
  683.     pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0,
  684.         SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  685.     if (pDockFrame->m_hWndOwner == NULL)
  686.         pDockFrame->m_hWndOwner = pBar->m_hWnd;
  687.  
  688.     CDockBar* pDockBar = (CDockBar*)pDockFrame->GetDlgItem(AFX_IDW_DOCKBAR_FLOAT);
  689.     ASSERT(pDockBar != NULL);
  690.     ASSERT(pDockBar->IsKindOf(RUNTIME_CLASS(CDockBar)));
  691.  
  692.     ASSERT(pBar->m_pDockSite == this);
  693.     // if this assertion occurred it is because the parent of pBar was not
  694.     //  initially this CFrameWnd when pBar's OnCreate was called
  695.     // (this control bar should have been created with a different
  696.     //  parent initially)
  697.  
  698.     pDockBar->DockControlBar(pBar);
  699.     pDockFrame->RecalcLayout();
  700.     pDockFrame->ShowWindow(SW_SHOWNA);
  701.     pDockFrame->UpdateWindow();
  702. }
  703.  
  704.  
  705. #ifdef _DEBUG
  706. void CMRCMDIFrameWndSizeDock::AssertValid() const
  707. {
  708.         CMDIFrameWnd::AssertValid();
  709. }
  710.  
  711.  
  712. void CMRCMDIFrameWndSizeDock::Dump(CDumpContext& dc) const
  713. {
  714.         CMDIFrameWnd::Dump(dc);
  715.         dc << "\nCMRCMDIFrameWndSizeDock - dockbars";
  716. }
  717. #endif
  718.  
  719.  
  720.  
  721. ////////////////////////////////////////////////////////////////////////////////
  722. ////////////////////////////////////////////////////////////////////////////////
  723. // CMRCMDIFrameWndSizeDock frame
  724. ////////////////////////////////////////////////////////////////////////////////
  725. ////////////////////////////////////////////////////////////////////////////////
  726.  
  727. IMPLEMENT_DYNCREATE(CMRCMDIChildWndSizeDock, CMDIChildWnd)
  728.  
  729. CMRCMDIChildWndSizeDock::CMRCMDIChildWndSizeDock()
  730. {
  731. }
  732.  
  733. CMRCMDIChildWndSizeDock::~CMRCMDIChildWndSizeDock()
  734. {
  735. //    CMRCSizeControlBar::TidyUp();        // tidy up any outstanding control bars...// ??
  736. }
  737.  
  738.  
  739. BEGIN_MESSAGE_MAP(CMRCMDIChildWndSizeDock, CMDIChildWnd)
  740.         //{{AFX_MSG_MAP(CMRCMDIChildWndSizeDock)
  741.                 // NOTE - the ClassWizard will add and remove mapping macros here.
  742.         //}}AFX_MSG_MAP
  743. END_MESSAGE_MAP()
  744.  
  745.  
  746.  
  747. //-------------------------------------------------------------------------
  748. BOOL MRCWriteProfileBinary(LPCTSTR lpszSection, LPCTSTR lpszEntry, 
  749.                                         LPVOID pData, DWORD nBufferSize)
  750. // Write a binary value into the registry. If the pointer to the buffer
  751. // is NULL then the current value is deleted. This can be generally used
  752. // for removing any value not just binary ones
  753. //-------------------------------------------------------------------------
  754. {
  755.     CWinApp * pApp = AfxGetApp();
  756.     ASSERT(pApp != NULL);
  757.     ASSERT(lpszSection != NULL);
  758.     ASSERT(lpszEntry != NULL);
  759.     ASSERT(pApp->m_pszRegistryKey != NULL); // We must be using the registry not 
  760.                                       // INI files for binary to be supported
  761.     LONG lRes;
  762.     
  763.     HKEY hSecKey = pApp->GetSectionKey(lpszSection);
  764.     if (hSecKey == NULL)
  765.         return FALSE;
  766.     if (pData == NULL)
  767.     {
  768.         lRes = ::RegDeleteValue(hSecKey, (LPTSTR)lpszEntry);
  769.     }
  770.     else
  771.     {
  772.         lRes = RegSetValueEx(hSecKey, lpszEntry, NULL, REG_BINARY,
  773.                                 (LPBYTE)pData, nBufferSize);
  774.     }
  775.     RegCloseKey(hSecKey);
  776.     return (lRes == ERROR_SUCCESS) ? TRUE : FALSE;
  777. }
  778.  
  779.  
  780. //-------------------------------------------------------------------------
  781. BOOL MRCGetProfileBinary(LPCTSTR lpszSection, LPCTSTR lpszEntry,
  782.                     LPVOID pData, DWORD nBufferSize)
  783. // Read the registry for a binary value. 
  784. // Various assertions fail if the size of the value does not match that
  785. // which is asked for. We can assume that the registry data should always
  786. // match the current software. Any conversion required between versions
  787. // should have taken place when initializing the app 
  788. //-------------------------------------------------------------------------
  789. {
  790.     CWinApp * pApp = AfxGetApp();
  791.     ASSERT(lpszSection != NULL);
  792.     ASSERT(lpszEntry != NULL);
  793.     ASSERT(pApp->m_pszRegistryKey != NULL); // We must be using the registry not INI files 
  794.                                      //for binary to be supported
  795.  
  796.     HKEY hSecKey = pApp->GetSectionKey(lpszSection);
  797.     if (hSecKey == NULL)
  798.         return FALSE;
  799.     DWORD dwType;
  800.     DWORD dwCount = nBufferSize;
  801.     LONG lRes = RegQueryValueEx(hSecKey, (LPTSTR)lpszEntry, NULL, &dwType,
  802.                     (LPBYTE)pData, &dwCount);
  803.     RegCloseKey(hSecKey);
  804.     ASSERT(lRes != ERROR_MORE_DATA); // Is Data in the registry larger than the buffer?
  805.                                       // We should have converted registry data on start up.
  806.     if (lRes == ERROR_SUCCESS)
  807.     {
  808.         ASSERT(dwType == REG_BINARY);
  809.         ASSERT(dwCount = nBufferSize); // The data should be the expected size
  810.         return TRUE;
  811.     }
  812.     return FALSE;
  813. }
  814.  
  815.  
  816.  
  817. //-----------------------------------------------------------------------------------------
  818. LPVOID MRCGetProfileBinary(LPCTSTR lpszSection, LPCTSTR lpszEntry, int * pBytesRead)
  819. // similar to function above, but allocates a block of data to read into and returns
  820. // a pointer to it. User must delete this area when no longer required
  821. //-----------------------------------------------------------------------------------------
  822. {
  823.     CWinApp * pApp = AfxGetApp();
  824.     ASSERT(lpszSection != NULL);
  825.     ASSERT(lpszEntry != NULL);
  826.     ASSERT(pApp->m_pszRegistryKey != NULL); // We must be using the registry not INI files 
  827.  
  828.  
  829.     HKEY hSecKey = pApp->GetSectionKey(lpszSection);
  830.     if (hSecKey == NULL)
  831.         return NULL;
  832.     
  833.     LPBYTE lpValue = NULL;
  834.     DWORD dwType, dwCount;
  835.     LONG lRes = RegQueryValueEx(hSecKey, (LPTSTR)lpszEntry, NULL, &dwType, NULL, &dwCount);
  836.     if (lRes == ERROR_SUCCESS)
  837.     {
  838.         lpValue = new BYTE[dwCount];
  839.         ASSERT(dwType == REG_BINARY);
  840.         lRes = RegQueryValueEx(hSecKey, (LPTSTR)lpszEntry, NULL, &dwType, lpValue, &dwCount);
  841.         if (lRes != ERROR_SUCCESS)
  842.         {
  843.             delete lpValue;            // error reading - deallocate the memory
  844.                lpValue = NULL;
  845.            }
  846.     }
  847.     RegCloseKey(hSecKey);
  848.  
  849.     if (pBytesRead != NULL)               // return length if we want this
  850.         *pBytesRead = dwCount;
  851.  
  852.     return lpValue;
  853. }
  854.  
  855.  
  856. void CMRCMDIFrameWndSizeDock::OnSysColorChange() 
  857. {
  858.     afxData.UpdateSysColors();
  859.     CMDIFrameWnd::OnSysColorChange();
  860. }
  861.  
  862.  
  863. void CMRCFrameWndSizeDock::OnSysColorChange() 
  864. {
  865.     afxData.UpdateSysColors();        
  866.     CFrameWnd::OnSysColorChange();
  867. }
  868.