GuiDockContext.cpp
上传用户:zhanglf88
上传日期:2013-11-19
资源大小:6036k
文件大小:23k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. //-----------------------------------------------------------------------//
  2. // This is a part of the GuiLib MFC Extention.  //
  3. // Autor  :  Francisco Campos  //
  4. // (C) 2002 Francisco Campos <www.beyondata.com> All rights reserved     //
  5. // This code is provided "as is", with absolutely no warranty expressed  //
  6. // or implied. Any use is at your own risk.  //
  7. // You must obtain the author's consent before you can include this code //
  8. // in a software library.  //
  9. // If the source code in  this file is used in any application  //
  10. // then acknowledgement must be made to the author of this program  //
  11. // fcampos@tutopia.com  //
  12. //-----------------------------------------------------------------------//
  13. #include "stdafx.h"
  14. #include "GuiDockContext.h"
  15. #include "GuiToolBarWnd.h"
  16. #include "MenuBar.h"
  17. #include "GuiControlBar.h"
  18. #define _AfxGetDlgCtrlID(hWnd)          ((UINT)(WORD)::GetDlgCtrlID(hWnd))
  19. #ifdef AFX_CORE3_SEG
  20. #pragma code_seg(AFX_CORE3_SEG)
  21. #endif
  22. #ifdef _DEBUG
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. #define new DEBUG_NEW
  27. #define HORZF(dw) (dw & CBRS_ORIENT_HORZ)
  28. #define VERTF(dw) (dw & CBRS_ORIENT_VERT)
  29. #define CX_BORDER   1
  30. #define CY_BORDER   1
  31. AFX_STATIC void AFXAPI _AfxAdjustRectangle(CRect& rect, CPoint pt)
  32. {
  33. int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
  34. (pt.x > rect.right) ? (pt.x - rect.right) : 0;
  35. int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
  36. (pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
  37. rect.OffsetRect(nXOffset, nYOffset);
  38. }
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CGuiDockContext
  41. CGuiDockContext::CGuiDockContext(CControlBar* pBar):CDockContext(pBar)
  42. {
  43. bFirstClic=TRUE;
  44. bSecondClic=TRUE;
  45. }
  46. CGuiDockContext::~CGuiDockContext()
  47. {
  48. }
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CGuiDockContext Drag Operations
  51. void CGuiDockContext::StartDrag(CPoint pt)
  52. {
  53. ASSERT_VALID(m_pBar);
  54. m_bDragging = TRUE;
  55. InitLoop();
  56. // GetWindowRect returns screen coordinates(not mirrored),
  57. // so if the desktop is mirrored then turn off mirroring
  58. // for the desktop dc so that we get correct focus rect drawn.
  59. // This layout change should be remembered, just in case ...
  60. if (m_pDC->GetLayout() & LAYOUT_RTL)
  61. m_pDC->SetLayout(LAYOUT_LTR);
  62. if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
  63. {
  64. // get true bar size (including borders)
  65. CRect rect;
  66. m_pBar->GetWindowRect(rect);
  67. m_ptLast = pt;
  68. AdjustWindowForFloat(rect);
  69. CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
  70. CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
  71. CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
  72. m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
  73. m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
  74. // calculate frame dragging rectangle
  75. m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
  76. m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat);
  77. CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  78. CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  79. // m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  80. // m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  81. }
  82. else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED)
  83. {
  84. // get true bar size (including borders)
  85. CRect rect;
  86. m_pBar->GetWindowRect(rect);
  87. AdjustWindowForFloat(rect);
  88. m_ptLast = pt;
  89. CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK);
  90. CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK);
  91. // calculate frame dragging rectangle
  92. m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
  93. m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
  94. CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  95. CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  96. // m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  97. // m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  98. }
  99. else
  100. {
  101. // get true bar size (including borders)
  102. CRect rect;
  103. m_pBar->GetWindowRect(rect);
  104. AdjustWindowForFloat(rect);
  105. m_ptLast = pt;
  106. BOOL bHorz = HORZF(m_dwStyle);
  107. DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK;
  108. CSize size = m_pBar->CalcDynamicLayout(-1, dwMode);
  109. // calculate inverted dragging rect
  110. if (bHorz)
  111. {
  112. m_rectDragHorz = rect;
  113. m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size);
  114. }
  115. else // vertical orientation
  116. {
  117. m_rectDragVert = rect;
  118. m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size);
  119. }
  120. // calculate frame dragging rectangle
  121. m_rectFrameDragHorz = m_rectDragHorz;
  122. m_rectFrameDragVert = m_rectDragVert;
  123. CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
  124. CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
  125. // m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  126. // m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  127. }
  128. // adjust rectangles so that point is inside
  129. _AfxAdjustRectangle(m_rectDragHorz, pt);
  130. _AfxAdjustRectangle(m_rectDragVert, pt);
  131. _AfxAdjustRectangle(m_rectFrameDragHorz, pt);
  132. _AfxAdjustRectangle(m_rectFrameDragVert, pt);
  133. // initialize tracking state and enter tracking loop
  134. m_dwOverDockStyle = CanDock();
  135. Move(pt);   // call it here to handle special keys
  136. Track();
  137. }
  138. void CGuiDockContext::AdjustWindowForFloat(CRect& rect)
  139. {
  140. if( m_pBar->IsFloating())
  141. {
  142. rect.top+=(GetSystemMetrics(SM_CYCAPTION));
  143. rect.bottom-=(GetSystemMetrics(SM_CYFRAME)+GetSystemMetrics(SM_CYCAPTION))*2;
  144. }
  145. }
  146. void CGuiDockContext::Move(CPoint pt)
  147. {
  148. CPoint ptOffset = pt - m_ptLast;
  149. // offset all drag rects to new position
  150. m_rectDragHorz.OffsetRect(ptOffset);
  151. m_rectFrameDragHorz.OffsetRect(ptOffset);
  152. m_rectDragVert.OffsetRect(ptOffset);
  153. m_rectFrameDragVert.OffsetRect(ptOffset);
  154. m_ptLast = pt;
  155. // if control key is down don't dock
  156. m_dwOverDockStyle = m_bForceFrame ? 0 : CanDock();
  157. // update feedback
  158. DrawFocusRect();
  159. }
  160. void CGuiDockContext::OnKey(int nChar, BOOL bDown)
  161. {
  162. if (nChar == VK_CONTROL)
  163. UpdateState(&m_bForceFrame, bDown);
  164. if (nChar == VK_SHIFT)
  165. UpdateState(&m_bFlip, bDown);
  166. }
  167. void CGuiDockContext::EndDrag()
  168. {
  169. CancelLoop();
  170. if (m_dwOverDockStyle != 0)
  171. {
  172. CDockBar* pDockBar = GetDockBar(m_dwOverDockStyle);
  173. ASSERT(pDockBar != NULL);
  174. CRect rect = (m_dwOverDockStyle & CBRS_ORIENT_VERT) ?
  175. m_rectDragVert : m_rectDragHorz;
  176. UINT uID = _AfxGetDlgCtrlID(pDockBar->m_hWnd);
  177. if (uID >= AFX_IDW_DOCKBAR_TOP &&
  178. uID <= AFX_IDW_DOCKBAR_BOTTOM)
  179. {
  180. m_uMRUDockID = uID;
  181. m_rectMRUDockPos = rect;
  182. pDockBar->ScreenToClient(&m_rectMRUDockPos);
  183. }
  184. // dock it at the specified position, RecalcLayout will snap
  185. m_pDockSite->DockControlBar(m_pBar, pDockBar, &rect);
  186. m_pDockSite->RecalcLayout();
  187. }
  188. else if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || (HORZF(m_dwStyle) && !m_bFlip) ||
  189. (VERTF(m_dwStyle) && m_bFlip))
  190. {
  191. m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI);
  192. m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft();
  193. m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
  194. }
  195. else // vertical float
  196. {
  197. m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (m_dwDockStyle & CBRS_FLOAT_MULTI);
  198. m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft();
  199. m_pDockSite->FloatControlBar(m_pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
  200. }
  201. }
  202. /////////////////////////////////////////////////////////////////////////////
  203. // CGuiDockContext Resize Operations
  204. #define m_rectRequestedSize     m_rectDragHorz
  205. #define m_rectActualSize        m_rectDragVert
  206. #define m_rectActualFrameSize   m_rectFrameDragHorz
  207. #define m_rectFrameBorders      m_rectFrameDragVert
  208. void CGuiDockContext::StartResize(int nHitTest, CPoint pt)
  209. {
  210. ASSERT_VALID(m_pBar);
  211. ASSERT(m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC);
  212. m_bDragging = FALSE;
  213. InitLoop();
  214. // GetWindowRect returns screen coordinates(not mirrored)
  215. // So if the desktop is mirrored then turn off mirroring
  216. // for the desktop dc so that we draw correct focus rect
  217. if (m_pDC->GetLayout() & LAYOUT_RTL)
  218. m_pDC->SetLayout(LAYOUT_LTR);
  219. // get true bar size (including borders)
  220. CRect rect;
  221. m_pBar->GetWindowRect(rect);
  222. m_ptLast = pt;
  223. m_nHitTest = nHitTest;
  224. CSize size = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
  225. m_rectRequestedSize = CRect(rect.TopLeft(), size);
  226. m_rectActualSize = CRect(rect.TopLeft(), size);
  227. m_rectActualFrameSize = CRect(rect.TopLeft(), size);
  228. // calculate frame rectangle
  229. CMiniFrameWnd::CalcBorders(&m_rectActualFrameSize);
  230. // m_rectActualFrameSize.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
  231. m_rectFrameBorders = CRect(CPoint(0,0),
  232. m_rectActualFrameSize.Size() - m_rectActualSize.Size());
  233. // initialize tracking state and enter tracking loop
  234. m_dwOverDockStyle = 0;
  235. Stretch(pt);   // call it here to handle special keys
  236. Track();
  237. }
  238. void CGuiDockContext::Stretch(CPoint pt)
  239. {
  240. CPoint ptOffset = pt - m_ptLast;
  241. // offset all drag rects to new position
  242. int nLength = 0;
  243. DWORD dwMode = LM_HORZ;
  244. if (m_nHitTest == HTLEFT || m_nHitTest == HTRIGHT)
  245. {
  246. if (m_nHitTest == HTLEFT)
  247. m_rectRequestedSize.left += ptOffset.x;
  248. else
  249. m_rectRequestedSize.right += ptOffset.x;
  250. nLength = m_rectRequestedSize.Width();
  251. }
  252. else
  253. {
  254. dwMode |= LM_LENGTHY;
  255. if (m_nHitTest == HTTOP)
  256. m_rectRequestedSize.top += ptOffset.y;
  257. else
  258. m_rectRequestedSize.bottom += ptOffset.y;
  259. nLength = m_rectRequestedSize.Height();
  260. }
  261. nLength = (nLength >= 0) ? nLength : 0;
  262. CSize size = m_pBar->CalcDynamicLayout(nLength, dwMode);
  263. CRect rectDesk;
  264. HWND hWndDesk = ::GetDesktopWindow();
  265. ::GetWindowRect(hWndDesk, &rectDesk);
  266. CRect rectTemp = m_rectActualFrameSize;
  267. if (m_nHitTest == HTLEFT || m_nHitTest == HTTOP)
  268. {
  269. rectTemp.left = rectTemp.right -
  270. (size.cx + m_rectFrameBorders.Width());
  271. rectTemp.top = rectTemp.bottom -
  272. (size.cy + m_rectFrameBorders.Height());
  273. CRect rect;
  274. if (rect.IntersectRect(rectDesk, rectTemp))
  275. {
  276. m_rectActualSize.left = m_rectActualSize.right - size.cx;
  277. m_rectActualSize.top = m_rectActualSize.bottom - size.cy;
  278. m_rectActualFrameSize.left = rectTemp.left;
  279. m_rectActualFrameSize.top = rectTemp.top;
  280. }
  281. }
  282. else
  283. {
  284. rectTemp.right = rectTemp.left +
  285. (size.cx + m_rectFrameBorders.Width());
  286. rectTemp.bottom = rectTemp.top +
  287. (size.cy + m_rectFrameBorders.Height());
  288. CRect rect;
  289. if (rect.IntersectRect(rectDesk, rectTemp))
  290. {
  291. m_rectActualSize.right = m_rectActualSize.left + size.cx;
  292. m_rectActualSize.bottom = m_rectActualSize.top + size.cy;
  293. m_rectActualFrameSize.right = rectTemp.right;
  294. m_rectActualFrameSize.bottom = rectTemp.bottom;
  295. }
  296. }
  297. m_ptLast = pt;
  298. // update feedback
  299. DrawFocusRect();
  300. }
  301. void CGuiDockContext::EndResize()
  302. {
  303. CancelLoop();
  304. m_pBar->CalcDynamicLayout(m_rectActualSize.Width(), LM_HORZ | LM_COMMIT);
  305. m_pDockSite->FloatControlBar(m_pBar, m_rectActualFrameSize.TopLeft(),
  306. CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI) | CBRS_SIZE_DYNAMIC);
  307. }
  308. /////////////////////////////////////////////////////////////////////////////
  309. // CGuiDockContext Double Click Operations
  310. void CGuiDockContext::ToggleDocking()
  311. {
  312. if (m_pBar->IsFloating())
  313. {
  314. // Dock it only if is allowed to be docked
  315. if (m_pBar->m_dwDockStyle & CBRS_ALIGN_ANY)
  316. {
  317. ASSERT((m_uMRUDockID >= AFX_IDW_DOCKBAR_TOP &&
  318. m_uMRUDockID <= AFX_IDW_DOCKBAR_BOTTOM) ||
  319. m_uMRUDockID == 0);
  320. CRect rect = m_rectMRUDockPos;
  321. CDockBar* pDockBar = NULL;
  322. if (m_uMRUDockID != 0)
  323. {
  324. pDockBar = (CDockBar*)m_pDockSite->GetControlBar(m_uMRUDockID);
  325. pDockBar->ClientToScreen(&rect);
  326. }
  327. // dock it at the specified position, RecalcLayout will snap
  328. m_pDockSite->ReDockControlBar(m_pBar, pDockBar, &rect);
  329. m_pDockSite->RecalcLayout();
  330. }
  331. }
  332. else
  333. {
  334. CPoint ptFloat = m_ptMRUFloatPos;
  335. if (ptFloat.x < 0 || ptFloat.y < 0)
  336. {
  337. ptFloat = m_rectMRUDockPos.TopLeft();
  338. m_pBar->GetParent()->ClientToScreen(&ptFloat);
  339. }
  340. m_pDockSite->FloatControlBar(m_pBar, ptFloat, m_dwMRUFloatStyle);
  341. }
  342. }
  343. /////////////////////////////////////////////////////////////////////////////
  344. // CGuiDockContext Operations
  345. void CGuiDockContext::InitLoop()
  346. {
  347. // handle pending WM_PAINT messages
  348. MSG msg;
  349. while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  350. {
  351. if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  352. return;
  353. DispatchMessage(&msg);
  354. }
  355. // get styles from bar
  356. m_dwDockStyle = m_pBar->m_dwDockStyle;
  357. m_dwStyle = m_pBar->m_dwStyle & CBRS_ALIGN_ANY;
  358. ASSERT(m_dwStyle != 0);
  359. // initialize state
  360. m_rectLast.SetRectEmpty();
  361. m_sizeLast.cx = m_sizeLast.cy = 0;
  362. m_bForceFrame = m_bFlip = m_bDitherLast = FALSE;
  363. // lock window update while dragging
  364. ASSERT(m_pDC == NULL);
  365. CWnd* pWnd = CWnd::GetDesktopWindow();
  366. if (pWnd->LockWindowUpdate())
  367. m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
  368. else
  369. m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE);
  370. ASSERT(m_pDC != NULL);
  371. }
  372. void CGuiDockContext::CancelLoop()
  373. {
  374. DrawFocusRect(TRUE);    // gets rid of focus rect
  375. ReleaseCapture();
  376. CWnd* pWnd = CWnd::GetDesktopWindow();
  377. pWnd->UnlockWindowUpdate();
  378. if (m_pDC != NULL)
  379. {
  380. pWnd->ReleaseDC(m_pDC);
  381. m_pDC = NULL;
  382. }
  383. bFirstClic=TRUE;
  384. bSecondClic=TRUE;
  385. }
  386. /////////////////////////////////////////////////////////////////////////////
  387. // Implementation
  388. void CGuiDockContext::DrawFocusRect(BOOL bRemoveRect)
  389. {
  390. ASSERT(m_pDC != NULL);
  391. // default to thin frame
  392. CSize size(CX_BORDER, CY_BORDER);
  393. // determine new rect and size
  394. CRect rect;
  395. CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH));
  396. CBrush* pDitherBrush = CDC::GetHalftoneBrush();
  397. CBrush* pBrush = pWhiteBrush;
  398. if (HORZF(m_dwOverDockStyle))
  399. rect = m_rectDragHorz;
  400. else if (VERTF(m_dwOverDockStyle))
  401. rect = m_rectDragVert;
  402. else
  403. {
  404. // use thick frame instead
  405. size.cx = GetSystemMetrics(SM_CXFRAME) - CX_BORDER;
  406. size.cy = GetSystemMetrics(SM_CYFRAME) - CY_BORDER;
  407. if ((HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip))
  408. rect = m_rectFrameDragHorz;
  409. else
  410. rect = m_rectFrameDragVert;
  411. pBrush = pDitherBrush;
  412. }
  413. if (bRemoveRect)
  414. size.cx = size.cy = 0;
  415. /* if (afxData.bWin4 &&
  416. (HORZF(m_dwOverDockStyle) || VERTF(m_dwOverDockStyle)))
  417. {
  418. // looks better one pixel in (makes the bar look pushed down)
  419. rect.InflateRect(-CX_BORDER, -CY_BORDER);
  420. }
  421. */
  422. // draw it and remember last size
  423. if (bFirstClic==TRUE)
  424. {
  425. bFirstClic=FALSE;
  426. }
  427. else{
  428. if (bSecondClic==TRUE)
  429. {
  430.   m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
  431. pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
  432.   m_bDitherLast = (pBrush == pDitherBrush);
  433.    m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
  434. pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
  435.   bSecondClic=FALSE;
  436. }
  437. else
  438. {
  439. m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
  440. pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
  441. m_rectLast = rect;
  442. m_sizeLast = size;
  443. m_bDitherLast = (pBrush == pDitherBrush);
  444. }
  445. }
  446. }
  447. void CGuiDockContext::UpdateState(BOOL* pFlag, BOOL bNewValue)
  448. {
  449. if (*pFlag != bNewValue)
  450. {
  451. *pFlag = bNewValue;
  452. m_bFlip = (HORZF(m_dwDockStyle) && VERTF(m_dwDockStyle) && m_bFlip); // shift key
  453. m_dwOverDockStyle = (m_bForceFrame) ? 0 : CanDock();
  454. DrawFocusRect();
  455. }
  456. }
  457. DWORD CGuiDockContext::CanDock()
  458. {
  459. BOOL bStyleHorz;
  460. DWORD dwDock = 0; // Dock Canidate
  461. DWORD dwCurr = 0; // Current Orientation
  462. // let's check for something in our current orientation first
  463. // then if the shift key is not forcing our orientation then
  464. // check for horizontal or vertical orientations as long
  465. // as we are close enough
  466. ASSERT(m_dwStyle != 0);
  467. bStyleHorz = HORZF(m_dwStyle);
  468. bStyleHorz = m_bFlip ? !bStyleHorz : bStyleHorz;
  469. if (bStyleHorz && HORZF(m_dwDockStyle))
  470. dwDock = CanDock(m_rectDragHorz,
  471.   m_dwDockStyle & ~CBRS_ORIENT_VERT);
  472. else if (VERTF(m_dwDockStyle))
  473. dwDock = CanDock(m_rectDragVert,
  474.   m_dwDockStyle & ~CBRS_ORIENT_HORZ);
  475. if (!m_bFlip)
  476. {
  477. if (dwDock == 0 && HORZF(m_dwDockStyle))
  478. {
  479. dwCurr = CanDock(m_rectDragVert,
  480.   m_dwDockStyle & ~CBRS_ORIENT_VERT);
  481. dwDock = CanDock(m_rectDragHorz,
  482.   m_dwDockStyle & ~CBRS_ORIENT_VERT);
  483. dwDock = (dwDock == dwCurr) ? dwDock : 0;
  484. }
  485. if (dwDock == 0 && VERTF(m_dwDockStyle))
  486. {
  487. dwCurr = CanDock(m_rectDragHorz,
  488.   m_dwDockStyle & ~CBRS_ORIENT_HORZ);
  489. dwDock = CanDock(m_rectDragVert,
  490.   m_dwDockStyle & ~CBRS_ORIENT_HORZ);
  491. dwDock = (dwDock == dwCurr) ? dwDock : 0;
  492. }
  493. }
  494. return dwDock;
  495. }
  496. DWORD CGuiDockContext::CanDock(CRect rect, DWORD dwDockStyle, CDockBar** ppDockBar)
  497. {
  498. // dwDockStyle -- allowable styles of bar
  499. // don't allow to dock to floating unless multi is specified
  500. BOOL bTipoToolBar=m_pBar->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd)) ||
  501.               m_pBar->IsKindOf(RUNTIME_CLASS( CMenuBar));
  502. dwDockStyle &= CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI;
  503. if (ppDockBar != NULL)
  504. *ppDockBar = NULL;
  505. POSITION pos = m_pDockSite->m_listControlBars.GetHeadPosition();
  506. while (pos != NULL)
  507. {
  508. CDockBar* pDockBar = (CDockBar*)m_pDockSite->m_listControlBars.GetNext(pos);
  509. if (pDockBar->IsDockBar() && pDockBar->IsWindowVisible() &&
  510. (pDockBar->m_dwStyle & dwDockStyle & CBRS_ALIGN_ANY) &&
  511. (!pDockBar->m_bFloating ||
  512. (dwDockStyle & pDockBar->m_dwStyle & CBRS_FLOAT_MULTI)))
  513. {
  514. int nSize=pDockBar->m_arrBars.GetSize();
  515. for (int i=0;i <nSize;  i++)
  516. {
  517. UINT m_nDockBarID = pDockBar->GetDlgCtrlID();
  518. CControlBar* pBar;
  519.  pBar = (CControlBar*) pDockBar->m_arrBars[i];
  520.  if (HIWORD(pBar) == 0) continue; // placeholder
  521.  if (!pBar->IsVisible()) continue;
  522.  CRect rectBar;
  523.  pBar->GetWindowRect(&rectBar);
  524.  if (rectBar.Width() == 0)
  525. rectBar.right++;
  526.  if (rectBar.Height() == 0)
  527. rectBar.bottom++;
  528.  CRect rectBar1;
  529.  pDockBar->GetWindowRect(&rectBar1);
  530.  if (dwDockStyle==CBRS_ORIENT_VERT)
  531.  {
  532.  if (m_nDockBarID==AFX_IDW_DOCKBAR_LEFT)
  533.   rectBar1.right=rectBar1.left+10;
  534.  if(m_nDockBarID==AFX_IDW_DOCKBAR_RIGHT)
  535.  rectBar1.left=rectBar1.right-10;
  536.  }
  537.  else
  538.  {
  539. if (m_nDockBarID==AFX_IDW_DOCKBAR_BOTTOM)
  540. rectBar1.top=rectBar1.bottom-10;
  541. if (m_nDockBarID==AFX_IDW_DOCKBAR_TOP)
  542. rectBar1.bottom=rectBar1.top+10;
  543.  }
  544.  if (rectBar1.IntersectRect(rectBar1, rect))
  545.  {
  546. if (ppDockBar != NULL)
  547. *ppDockBar = pDockBar;
  548. return pDockBar->m_dwStyle & dwDockStyle;
  549.  }
  550. //***********************************************
  551. if (rectBar.IntersectRect(rectBar, rect))
  552. {
  553. if (bTipoToolBar)
  554. {
  555. if (pBar->IsKindOf(RUNTIME_CLASS( CGuiControlBar)))
  556. return 0;
  557. }
  558. if (ppDockBar != NULL)
  559. *ppDockBar = pDockBar;
  560. return pDockBar->m_dwStyle & dwDockStyle;
  561.  
  562. }
  563.  
  564. }//fin del for
  565. CRect rectBar;
  566. pDockBar->GetWindowRect(&rectBar);
  567. if (rectBar.Width() == 0)
  568. rectBar.right++;
  569. if (rectBar.Height() == 0)
  570. rectBar.bottom++;
  571. if (rectBar.IntersectRect(rectBar, rect))
  572. {
  573. if (ppDockBar != NULL)
  574. *ppDockBar = pDockBar;
  575. return pDockBar->m_dwStyle & dwDockStyle;
  576. }
  577. }
  578. }
  579. return 0;
  580. }
  581. //*********************************************
  582. // return 0 no acepta el docking
  583. //        1 lo acepta
  584. //        2 continue
  585. int  CGuiDockContext::VerLeft(int i,int nSize,CDockBar* pDockBar,CControlBar* pBar)
  586. {
  587. BOOL bTipoToolBar=m_pBar->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd));
  588. //i--;
  589. if (i+1 < nSize)
  590. {
  591. CControlBar* pBartemp;
  592.   pBartemp = (CControlBar*) pDockBar->m_arrBars[i+1];
  593. if (HIWORD(pBartemp) == 0) return 2; // placeholder
  594. if (!pBartemp->IsVisible()) return 2;
  595. if (bTipoToolBar)
  596. if (!pBartemp->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd)))
  597. return 0;
  598. }
  599. if (i > 0)
  600. {
  601. CControlBar* pBartemp;
  602. pBartemp = (CControlBar*) pDockBar->m_arrBars[i-1];
  603. if (HIWORD(pBartemp) == 0) return 2; // placeholder
  604. if (!pBartemp->IsVisible()) return 2;
  605. if (bTipoToolBar)
  606. if (!pBartemp->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd)))
  607. return 0;
  608. }
  609. return 1;
  610. }
  611. //*********************************************
  612. // return 0 no acepta el docking
  613. //        1 lo acepta
  614. //        2 continue
  615. int  CGuiDockContext::VerRight(int i,int nSize,CDockBar* pDockBar,CControlBar* pBar)
  616. {
  617. BOOL bTipoToolBar=m_pBar->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd));
  618. //i--;
  619. if (i==0)
  620. {
  621. CControlBar* pBartemp;
  622. pBartemp = (CControlBar*) pDockBar->m_arrBars[i+1];
  623. if (HIWORD(pBartemp) == 0) return 2; // placeholder
  624. if (!pBartemp->IsVisible()) return 2;
  625. if (bTipoToolBar)
  626. if (!pBartemp->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd)))
  627. return 0;
  628. }
  629. if (i > 0)
  630. {
  631. CControlBar* pBartemp;
  632. pBartemp = (CControlBar*) pDockBar->m_arrBars[i-1];
  633. if (HIWORD(pBartemp) == 0) return 2; // placeholder
  634. if (!pBartemp->IsVisible()) return 2;
  635. if (bTipoToolBar)
  636. if (!pBartemp->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd)))
  637. return 0;
  638. }
  639. return 1;
  640. }
  641. CDockBar* CGuiDockContext::GetDockBar(DWORD dwOverDockStyle)
  642. {
  643. DWORD dw = 0;
  644. CDockBar* pBar;
  645. if (HORZF(dwOverDockStyle))
  646. {
  647. dw = CanDock(m_rectDragHorz,
  648. dwOverDockStyle & ~CBRS_ORIENT_VERT, &pBar);
  649. ASSERT(dw != 0);
  650. ASSERT(pBar != NULL);
  651. return pBar;
  652. }
  653. if (VERTF(dwOverDockStyle))
  654. {
  655. dw =CanDock(m_rectDragVert,
  656. dwOverDockStyle & ~CBRS_ORIENT_HORZ, &pBar);
  657. ASSERT(dw != 0);
  658. ASSERT(pBar != NULL);
  659. return pBar;
  660. }
  661. return NULL;
  662. }
  663. BOOL CGuiDockContext::Track()
  664. {
  665. // don't handle if capture already set
  666. if (::GetCapture() != NULL)
  667. return FALSE;
  668. // set capture to the window which received this message
  669. m_pBar->SetCapture();
  670. ASSERT(m_pBar == CWnd::GetCapture());
  671. // get messages until capture lost or cancelled/accepted
  672. while (CWnd::GetCapture() == m_pBar)
  673. {
  674. MSG msg;
  675. if (!::GetMessage(&msg, NULL, 0, 0))
  676. {
  677. AfxPostQuitMessage(msg.wParam);
  678. break;
  679. }
  680. switch (msg.message)
  681. {
  682. case WM_LBUTTONUP:
  683. if (m_bDragging)
  684. EndDrag();
  685. else
  686. EndResize();
  687. return TRUE;
  688. case WM_MOUSEMOVE:
  689. if (m_bDragging)
  690. Move(msg.pt);
  691. else
  692. Stretch(msg.pt);
  693. break;
  694. case WM_KEYUP:
  695. if (m_bDragging)
  696. OnKey((int)msg.wParam, FALSE);
  697. break;
  698. case WM_KEYDOWN:
  699. if (m_bDragging)
  700. OnKey((int)msg.wParam, TRUE);
  701. if (msg.wParam == VK_ESCAPE)
  702. {
  703. CancelLoop();
  704. return FALSE;
  705. }
  706. break;
  707. case WM_RBUTTONDOWN:
  708. CancelLoop();
  709. return FALSE;
  710. // just dispatch rest of the messages
  711. default:
  712. DispatchMessage(&msg);
  713. break;
  714. }
  715. }
  716. CancelLoop();
  717. return FALSE;
  718. }