home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / winfrm2.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  8KB  |  263 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_CORE4_SEG
  14. #pragma code_seg(AFX_CORE4_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. // dwDockBarMap
  25. const DWORD CFrameWnd::dwDockBarMap[4][2] =
  26. {
  27.     { AFX_IDW_DOCKBAR_TOP,      CBRS_TOP    },
  28.     { AFX_IDW_DOCKBAR_BOTTOM,   CBRS_BOTTOM },
  29.     { AFX_IDW_DOCKBAR_LEFT,     CBRS_LEFT   },
  30.     { AFX_IDW_DOCKBAR_RIGHT,    CBRS_RIGHT  },
  31. };
  32.  
  33. /////////////////////////////////////////////////////////////////////////////
  34. // Dockable control bar helpers
  35.  
  36. CMiniDockFrameWnd* CFrameWnd::CreateFloatingFrame(DWORD dwStyle)
  37. {
  38.     CMiniDockFrameWnd* pFrame = NULL;
  39.     ASSERT(m_pFloatingFrameClass != NULL);
  40.     pFrame = (CMiniDockFrameWnd*)m_pFloatingFrameClass->CreateObject();
  41.     if (pFrame == NULL)
  42.         AfxThrowMemoryException();
  43.     ASSERT_KINDOF(CMiniDockFrameWnd, pFrame);
  44.     if (!pFrame->Create(this, dwStyle))
  45.         AfxThrowResourceException();
  46.     return pFrame;
  47. }
  48.  
  49. // dock bars will be created in the order specified by dwDockBarMap
  50. // this also controls which gets priority during layout
  51. // this order can be changed by calling EnableDocking repetitively
  52. // with the exact order of priority
  53. void CFrameWnd::EnableDocking(DWORD dwDockStyle)
  54. {
  55.     // must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
  56.     ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
  57.  
  58.     m_pFloatingFrameClass = RUNTIME_CLASS(CMiniDockFrameWnd);
  59.     for (int i = 0; i < 4; i++)
  60.     {
  61.         if (dwDockBarMap[i][1] & dwDockStyle & CBRS_ALIGN_ANY)
  62.         {
  63.             CDockBar* pDock = (CDockBar*)GetControlBar(dwDockBarMap[i][0]);
  64.             if (pDock == NULL)
  65.             {
  66.                 pDock = new CDockBar;
  67.                 if (!pDock->Create(this,
  68.                     WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CHILD|WS_VISIBLE |
  69.                         dwDockBarMap[i][1], dwDockBarMap[i][0]))
  70.                 {
  71.                     AfxThrowResourceException();
  72.                 }
  73.             }
  74.         }
  75.     }
  76. }
  77.  
  78. void CFrameWnd::DockControlBar(CControlBar* pBar, UINT nDockBarID, LPCRECT lpRect)
  79. {
  80.     CDockBar* pDockBar = (nDockBarID == 0) ? NULL :
  81.         (CDockBar*)GetControlBar(nDockBarID);
  82.     DockControlBar(pBar, pDockBar, lpRect);
  83. }
  84.  
  85. void CFrameWnd::DockControlBar(CControlBar* pBar, CDockBar* pDockBar, LPCRECT lpRect)
  86. {
  87.     ASSERT(pBar != NULL);
  88.     // make sure CControlBar::EnableDocking has been called
  89.     ASSERT(pBar->m_pDockContext != NULL);
  90.  
  91.     if (pDockBar == NULL)
  92.     {
  93.         for (int i = 0; i < 4; i++)
  94.         {
  95.             if ((dwDockBarMap[i][1] & CBRS_ALIGN_ANY) ==
  96.                 (pBar->m_dwStyle & CBRS_ALIGN_ANY))
  97.             {
  98.                 pDockBar = (CDockBar*)GetControlBar(dwDockBarMap[i][0]);
  99.                 ASSERT(pDockBar != NULL);
  100.                 // assert fails when initial CBRS_ of bar does not
  101.                 // match available docking sites, as set by EnableDocking()
  102.                 break;
  103.             }
  104.         }
  105.     }
  106.     ASSERT(pDockBar != NULL);
  107.     ASSERT(m_listControlBars.Find(pBar) != NULL);
  108.     ASSERT(pBar->m_pDockSite == this);
  109.     // if this assertion occurred it is because the parent of pBar was not initially
  110.     // this CFrameWnd when pBar's OnCreate was called
  111.     // i.e. this control bar should have been created with a different parent initially
  112.  
  113.     pDockBar->DockControlBar(pBar, lpRect);
  114. }
  115.  
  116. void CFrameWnd::ReDockControlBar(CControlBar* pBar, CDockBar* pDockBar, LPCRECT lpRect)
  117. {
  118.     ASSERT(pBar != NULL);
  119.     // make sure CControlBar::EnableDocking has been called
  120.     ASSERT(pBar->m_pDockContext != NULL);
  121.  
  122.     if (pDockBar == NULL)
  123.     {
  124.         // Search for the place holder.
  125.  
  126.         // In case we don't find a place holder, find a bar with the correct alignment
  127.         // and keep it in pPossibleBar.
  128.         CDockBar* pPossibleBar = NULL;
  129.         for (int i = 0; i < 4; i++)
  130.         {
  131.             CDockBar* pTempBar = (CDockBar*)GetControlBar(dwDockBarMap[i][0]);
  132.             if (pTempBar != NULL)
  133.             {
  134.                 // Is this the same bar we docked with before?
  135.                 if (pTempBar->FindBar((CControlBar*)_AfxGetDlgCtrlID(pBar->m_hWnd)) > 0)
  136.                 {
  137.                     pDockBar = pTempBar;
  138.                     break;
  139.                 }
  140.             }
  141.  
  142.             if ((dwDockBarMap[i][1] & CBRS_ALIGN_ANY) ==
  143.                 (pBar->m_dwStyle & CBRS_ALIGN_ANY))
  144.             {
  145.                 pPossibleBar = (CDockBar*)GetControlBar(dwDockBarMap[i][0]);
  146.                 ASSERT(pPossibleBar != NULL);
  147.                 // assert fails when initial CBRS_ of bar does not
  148.                 // match available docking sites, as set by EnableDocking()
  149.             }
  150.         }
  151.  
  152.         // Did we find the place holder?
  153.         if (pDockBar == NULL)
  154.             pDockBar = pPossibleBar;
  155.     }
  156.     ASSERT(pDockBar != NULL);
  157.     ASSERT(m_listControlBars.Find(pBar) != NULL);
  158.     ASSERT(pBar->m_pDockSite == this);
  159.     // if this assertion occurred it is because the parent of pBar was not initially
  160.     // this CFrameWnd when pBar's OnCreate was called
  161.     // i.e. this control bar should have been created with a different parent initially
  162.  
  163.     pDockBar->ReDockControlBar(pBar, lpRect);
  164. }
  165.  
  166. void CFrameWnd::FloatControlBar(CControlBar* pBar, CPoint point, DWORD dwStyle)
  167. {
  168.     ASSERT(pBar != NULL);
  169.  
  170.     // if the bar is already floating and the dock bar only contains this
  171.     // bar and same orientation then move the window rather than recreating
  172.     // the frame
  173.     if (pBar->m_pDockSite != NULL && pBar->m_pDockBar != NULL)
  174.     {
  175.         CDockBar* pDockBar = pBar->m_pDockBar;
  176.         ASSERT_KINDOF(CDockBar, pDockBar);
  177.         if (pDockBar->m_bFloating && pDockBar->GetDockedCount() == 1 &&
  178.             (dwStyle & pDockBar->m_dwStyle & CBRS_ALIGN_ANY) != 0)
  179.         {
  180.             CMiniDockFrameWnd* pDockFrame =
  181.                 (CMiniDockFrameWnd*)pDockBar->GetParent();
  182.             ASSERT(pDockFrame != NULL);
  183.             ASSERT_KINDOF(CMiniDockFrameWnd, pDockFrame);
  184.             pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0,
  185.                 SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  186.             pDockFrame->RecalcLayout(TRUE);
  187.             pDockFrame->UpdateWindow();
  188.             return;
  189.         }
  190.     }
  191.  
  192.     if (pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
  193.     {
  194.         dwStyle |= CBRS_SIZE_DYNAMIC;
  195.         if (dwStyle & CBRS_ORIENT_VERT)
  196.         {
  197.             dwStyle &= ~CBRS_ALIGN_ANY;
  198.             dwStyle |= CBRS_ALIGN_TOP;
  199.         }
  200.     }
  201.  
  202.     CMiniDockFrameWnd* pDockFrame = CreateFloatingFrame(dwStyle);
  203.     ASSERT(pDockFrame != NULL);
  204.     pDockFrame->SetWindowPos(NULL, point.x, point.y, 0, 0,
  205.         SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
  206.     if (pDockFrame->m_hWndOwner == NULL)
  207.         pDockFrame->m_hWndOwner = pBar->m_hWnd;
  208.  
  209.     CDockBar* pDockBar = (CDockBar*)pDockFrame->GetDlgItem(AFX_IDW_DOCKBAR_FLOAT);
  210.     ASSERT(pDockBar != NULL);
  211.     ASSERT_KINDOF(CDockBar, pDockBar);
  212.  
  213.     ASSERT(pBar->m_pDockSite == this);
  214.     // if this assertion occurred it is because the parent of pBar was not
  215.     //  initially this CFrameWnd when pBar's OnCreate was called
  216.     // (this control bar should have been created with a different
  217.     //  parent initially)
  218.  
  219.     pDockBar->DockControlBar(pBar);
  220.     pDockFrame->RecalcLayout(TRUE);
  221.     if (GetWindowLong(pBar->m_hWnd, GWL_STYLE) & WS_VISIBLE)
  222.     {
  223.         pDockFrame->ShowWindow(SW_SHOWNA);
  224.         pDockFrame->UpdateWindow();
  225.     }
  226. }
  227.  
  228. DWORD CFrameWnd::CanDock(CRect rect, DWORD dwDockStyle, CDockBar** ppDockBar)
  229. {
  230.     // dwDockStyle -- allowable styles of bar
  231.     // don't allow to dock to floating unless multi is specified
  232.     dwDockStyle &= CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI;
  233.  
  234.     if (ppDockBar != NULL)
  235.         *ppDockBar = NULL;
  236.     POSITION pos = m_listControlBars.GetHeadPosition();
  237.     while (pos != NULL)
  238.     {
  239.         CDockBar* pDockBar = (CDockBar*)m_listControlBars.GetNext(pos);
  240.         if (pDockBar->IsDockBar() && pDockBar->IsWindowVisible() &&
  241.             (pDockBar->m_dwStyle & dwDockStyle & CBRS_ALIGN_ANY) &&
  242.             (!pDockBar->m_bFloating ||
  243.                 (dwDockStyle & pDockBar->m_dwStyle & CBRS_FLOAT_MULTI)))
  244.         {
  245.             CRect rectBar;
  246.             pDockBar->GetWindowRect(&rectBar);
  247.             if (rectBar.Width() == 0)
  248.                 rectBar.right++;
  249.             if (rectBar.Height() == 0)
  250.                 rectBar.bottom++;
  251.             if (rectBar.IntersectRect(rectBar, rect))
  252.             {
  253.                 if (ppDockBar != NULL)
  254.                     *ppDockBar = pDockBar;
  255.                 return pDockBar->m_dwStyle & dwDockStyle;
  256.             }
  257.         }
  258.     }
  259.     return 0;
  260. }
  261.  
  262. /////////////////////////////////////////////////////////////////////////////
  263.