winfrm2.cpp 8.0 KB

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