GuiDockContext.cpp
上传用户:wlkj888
上传日期:2022-08-01
资源大小:806k
文件大小:22k
源码类别:

对话框与窗口

开发平台:

Visual C++

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