CoolControlBar.cpp
上传用户:czfddz
上传日期:2013-03-20
资源大小:1517k
文件大小:27k
源码类别:

酒店行业

开发平台:

C/C++

  1. /*########################################################################
  2. Filename:  CoolControlbar.cpp
  3. ----------------------------------------------------
  4. Remarks: ...
  5. ----------------------------------------------------
  6. Author: 成真
  7. Email: anyou@sina.com
  8. anyou@msn.com
  9. Created: 7/3/2003 21:52
  10.   ########################################################################*/
  11. #include "stdafx.h"
  12. #include "resource.h"
  13. #include "CoolControlBar.h"
  14. #ifdef _DEBUG
  15. #define new DEBUG_NEW
  16. #undef THIS_FILE
  17. static char THIS_FILE[] = __FILE__;
  18. #endif
  19. CCoolBarArray CCoolControlBar::m_arrBars; 
  20. /*########################################################################
  21.   ------------------------------------------------
  22.   class CCoolControlBar
  23.   ------------------------------------------------
  24.   ########################################################################*/
  25. CCoolControlBar::CCoolControlBar()
  26. {
  27. m_bTracking = FALSE;
  28. m_bParentSizing = FALSE;
  29. }
  30. CCoolControlBar::~CCoolControlBar()
  31. {
  32. }
  33. BOOL CCoolControlBar::Create(CWnd *pParentWnd, CSize size, UINT dwStyle, UINT uID)
  34. {
  35. ASSERT_VALID(pParentWnd);
  36. ASSERT( (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_TOP    ||
  37. (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_BOTTOM ||
  38. (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_LEFT   ||
  39. (dwStyle & CBRS_ALIGN_ANY) == CBRS_ALIGN_RIGHT);
  40.     ASSERT (!((dwStyle & CBRS_SIZE_FIXED) && (dwStyle & CBRS_SIZE_DYNAMIC)));
  41. m_dwStyle = (dwStyle & CBRS_ALL);
  42. // keep only the generic window styles--------------
  43. dwStyle &= ~CBRS_ALL;
  44. // force WS_CLIPSIBLINGS (otherwise will cause repaint problems)---
  45. dwStyle |= WS_CLIPSIBLINGS;
  46. BOOL bRets = CControlBar::Create(NULL, NULL, dwStyle, 
  47. CRect(0, 0, 0, 0), pParentWnd, uID, NULL);
  48. if (bRets)
  49. {
  50. m_szDefault = size;    
  51. m_szHorz = size;
  52. m_szVert = size;
  53. m_szFloat   = size;
  54. // force the size to zero - resizing bar will occur later----------
  55. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
  56. }
  57. return bRets;
  58. }
  59. BOOL CCoolControlBar::DestroyWindow() 
  60. {
  61.     int nPos = FindCoolBar(this);
  62.     ASSERT(nPos >= 0);
  63.     m_arrBars.RemoveAt(nPos);
  64. return CControlBar::DestroyWindow();
  65. }
  66. CSize CCoolControlBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)
  67. {
  68. if (bStretch) 
  69. {
  70. return CSize(bHorz ? 32767 : m_szVert.cx, bHorz ? m_szHorz.cy : 32767);
  71. }
  72. else
  73. {
  74. // dirty cast - using CCoolDockBar to access protected CDockBar members
  75. CFriendDockBar* pDockBar = (CFriendDockBar*)m_pDockBar;
  76. if (pDockBar != NULL)
  77. {
  78. // force imediate RecalcDelayShow() for all sizing bars on the row
  79. // with delayShow/delayHide flags set to avoid IsVisible() problems
  80. CCoolBarArray arrCoolBars;
  81. GetCoolBars(arrCoolBars);
  82. AFX_SIZEPARENTPARAMS layout;
  83. layout.hDWP = pDockBar->m_bLayoutQuery ? NULL 
  84. : ::BeginDeferWindowPos(arrCoolBars.GetSize());
  85. for (int i = 0; i < arrCoolBars.GetSize(); i++)
  86. {
  87. arrCoolBars[i]->RecalcDelayShow(&layout);
  88. }
  89. if (layout.hDWP != NULL)
  90. {
  91. ::EndDeferWindowPos(layout.hDWP);
  92. }
  93. if (IsVisible() && !IsFloating() && m_bParentSizing && arrCoolBars[0] == this)
  94. {
  95. m_bParentSizing = FALSE;
  96. CRect rc = pDockBar->m_rectLayout;
  97. if (rc.IsRectEmpty())
  98. {
  99. m_pDockSite->GetClientRect(&rc);
  100. }
  101. int nLengthAvail = bHorz ? rc.Width() + 2 : rc.Height();
  102. if (AutoSize(nLengthAvail, bHorz))
  103. {
  104. AutoAlign();
  105. }
  106. }
  107. }
  108. return bHorz ? m_szHorz : m_szVert;
  109. }
  110. }
  111. CSize CCoolControlBar::CalcDynamicLayout(int nLength, DWORD dwMode)
  112. {
  113. if (dwMode & (LM_HORZDOCK | LM_VERTDOCK)) // docked ?
  114.     {
  115. if (nLength == -1) m_bParentSizing = TRUE;
  116.         return CControlBar::CalcDynamicLayout(nLength, dwMode);
  117.     }
  118.     if (dwMode & LM_MRUWIDTH) return m_szFloat;
  119.     if (dwMode & LM_COMMIT)   return m_szFloat; // already committed
  120.     ((dwMode & LM_LENGTHY) ? m_szFloat.cy : m_szFloat.cx) = nLength;
  121.     m_szFloat.cx = max(m_szFloat.cx, m_szDefault.cx);
  122.     m_szFloat.cy = max(m_szFloat.cy, m_szDefault.cy);
  123.    return m_szFloat;
  124. }
  125. IMPLEMENT_DYNAMIC(CCoolControlBar, CControlBar);
  126. /*########################################################################
  127.   ------------------------------------------------
  128. Message handlers
  129.   ------------------------------------------------
  130.   ########################################################################*/
  131. BEGIN_MESSAGE_MAP(CCoolControlBar, CControlBar)
  132. //{{AFX_MSG_MAP(CCoolControlBar)
  133. ON_WM_NCCALCSIZE()
  134. ON_WM_NCPAINT()
  135. ON_WM_ERASEBKGND()
  136. ON_WM_NCLBUTTONDOWN()
  137. ON_WM_WINDOWPOSCHANGING()
  138. ON_WM_NCHITTEST()
  139. ON_WM_MOUSEMOVE()
  140. ON_WM_LBUTTONUP()
  141. ON_WM_CREATE()
  142. ON_WM_PAINT()
  143. ON_WM_NCLBUTTONUP()
  144. //}}AFX_MSG_MAP
  145. END_MESSAGE_MAP()
  146. int CCoolControlBar::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  147. {
  148.     m_arrBars.Add(this);
  149. if (CControlBar::OnCreate(lpCreateStruct) == -1)
  150. {
  151. return -1;
  152. }
  153. return 0;
  154. }
  155. void CCoolControlBar::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos) 
  156. {
  157. // force non-client recalc if moved or resized
  158.     lpwndpos->flags |= SWP_FRAMECHANGED;
  159. CControlBar::OnWindowPosChanging(lpwndpos);
  160. }
  161. void CCoolControlBar::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp) 
  162. {
  163. CRect rect = lpncsp->rgrc[0];
  164. BOOL bALignLeft   = (m_dwStyle & CBRS_ALIGN_LEFT  );
  165. BOOL bALignRight  = (m_dwStyle & CBRS_ALIGN_RIGHT );
  166. BOOL bALignTop    = (m_dwStyle & CBRS_ALIGN_TOP   );
  167. BOOL bALignBottom = (m_dwStyle & CBRS_ALIGN_BOTTOM);
  168. if ((m_dwStyle & CBRS_FLOATING) != CBRS_FLOATING)
  169. {
  170. if (m_pDockBar != NULL)
  171. {
  172. rect.DeflateRect(5, 5);
  173. }
  174. else
  175. {
  176. if (bALignLeft) rect.DeflateRect(1, 1, 3, 0);
  177. else if (bALignRight) rect.DeflateRect(3, 0, 1, 0);
  178. else if (bALignTop) rect.DeflateRect(0, 0, 0, 3);
  179. else rect.DeflateRect(0, 3, 0, 0);
  180. }
  181. if (m_dwStyle & CBRS_TITLEBAR)
  182. {
  183. (IsHorizontal() ? rect.left : rect.top) += 16;
  184. }
  185. }
  186.     lpncsp->rgrc[0] = rect;
  187. }
  188. void CCoolControlBar::OnNcPaint() 
  189. {
  190.     CWindowDC dc(this);
  191. dc.SetBkMode(TRANSPARENT);
  192.     CRect rcClient, rcWindow;
  193.     GetWindowRect(&rcWindow);
  194.     GetClientRect(&rcClient);
  195. ClientToScreen(&rcClient);
  196.     rcClient.OffsetRect(-rcWindow.TopLeft());
  197.     rcWindow.OffsetRect(-rcWindow.TopLeft());
  198. //填充背景-----------------------------------------
  199. if (rcClient.bottom > rcClient.top && rcClient.right > rcClient.left)
  200. {
  201.  dc.ExcludeClipRect(rcClient);
  202. }
  203. dc.FillSolidRect(rcWindow, ::GetSysColor(COLOR_3DFACE));
  204. //绘制边框-----------------------------------------
  205. if (m_pDockBar != NULL)
  206. {
  207. dc.Draw3dRect(rcWindow, RGB(128, 128, 128), RGB(255, 255, 255));
  208. rcWindow.DeflateRect(1, 1);
  209. dc.Draw3dRect(rcWindow, RGB(255, 255, 255), RGB(128, 128, 128));
  210. }
  211. //绘制标题栏---------------------------------------
  212. if (m_dwStyle & CBRS_TITLEBAR)
  213. {
  214. CRect rcTitleBar(rcWindow);
  215. if (IsHorizontal())
  216. {
  217. rcTitleBar.right = rcTitleBar.left + 19;
  218. rcTitleBar.DeflateRect(0, 4);
  219. if (m_pDockBar == NULL)
  220. {
  221. rcTitleBar.OffsetRect(-2, 0);
  222. }
  223. m_rcCloseButton.right = rcTitleBar.right - 1;
  224. m_rcCloseButton.top   = rcTitleBar.top + 1;
  225. }
  226. else
  227. {
  228. rcTitleBar.bottom = rcTitleBar.top + 19;
  229. rcTitleBar.DeflateRect(4, 0);
  230. if (m_pDockBar == NULL)
  231. {
  232. rcTitleBar.OffsetRect(0, -2);
  233. }
  234. m_rcCloseButton.right = rcTitleBar.right - 1;
  235. m_rcCloseButton.top   = rcTitleBar.top + 4;
  236. }
  237. m_rcCloseButton.left = m_rcCloseButton.right - 12;
  238. m_rcCloseButton.bottom = m_rcCloseButton.top + 12;
  239. DrawTitleBar(&dc, rcTitleBar, IsHorizontal());
  240. DrawCloseButton(&dc, m_dwButtonState);
  241. }
  242. ReleaseDC(&dc);
  243. }
  244. void CCoolControlBar::OnPaint() 
  245. {
  246. CPaintDC dc(this); 
  247. }
  248. BOOL CCoolControlBar::OnEraseBkgnd(CDC* pDC) 
  249. {
  250. CRect rect;
  251. GetClientRect(&rect);
  252. pDC->FillSolidRect(rect, ::GetSysColor(COLOR_3DFACE));
  253. return CControlBar::OnEraseBkgnd(pDC);
  254. }
  255. UINT CCoolControlBar::OnNcHitTest(CPoint point) 
  256. {
  257. if (IsFloating())
  258. {
  259. return CControlBar::OnNcHitTest(point);
  260. }
  261.     CRect rcWindow, rcTrack;
  262.     GetWindowRect(rcWindow);
  263. if (m_dwStyle & CBRS_TITLEBAR)
  264. {
  265. CRect rc(m_rcCloseButton);
  266. rc.OffsetRect(rcWindow.TopLeft());
  267. if (rc.PtInRect(point))
  268. {
  269. return HTCLOSE;
  270. }
  271. }
  272. for (int i = 0; i < 4; i++)
  273. {
  274. if (GetTrackRect(rcTrack, i) && rcTrack.PtInRect(point)) 
  275. {
  276. switch (i) 
  277. {
  278. case 0:  return HTLEFT;   break;
  279. case 1:  return HTTOP;    break;
  280. case 2:  return HTRIGHT;  break;
  281. case 3:  return HTBOTTOM; break;
  282. }
  283. }
  284. }
  285. return HTCLIENT; 
  286. }
  287. void CCoolControlBar::OnNcLButtonDown(UINT nHitTest, CPoint point) 
  288. {
  289. if (IsFloating())
  290. {
  291. CControlBar::OnNcLButtonDown(nHitTest, point);
  292. return;
  293. }
  294. if ((nHitTest >= HTSIZEFIRST) && (nHitTest <= HTSIZELAST))
  295. {
  296. SetCapture();
  297. m_bTracking  = TRUE;
  298. m_bTrackType = nHitTest;
  299. m_oldPoint   = point;
  300. }
  301. }
  302. void CCoolControlBar::OnNcLButtonUp(UINT nHitTest, CPoint point) 
  303. {
  304. if (nHitTest == HTCLOSE)
  305. {
  306. GetParentFrame()->ShowControlBar(this, FALSE, FALSE);
  307. return;
  308. }
  309. CControlBar::OnNcLButtonUp(nHitTest, point);
  310. }
  311. void CCoolControlBar::OnMouseMove(UINT nFlags, CPoint point) 
  312. {
  313. if (m_bTracking)
  314. {
  315. ClientToScreen(&point);
  316. UpdateWndSize(point);
  317. }
  318. CControlBar::OnMouseMove(nFlags, point);
  319. }
  320. void CCoolControlBar::OnLButtonUp(UINT nFlags, CPoint point) 
  321. {
  322. ReleaseCapture();
  323. if (m_bTracking)
  324. {
  325. m_bTracking = FALSE;
  326. return;
  327. }
  328. CControlBar::OnLButtonUp(nFlags, point);
  329. }
  330. void CCoolControlBar::OnUpdateCmdUI(CFrameWnd *pTarget, BOOL bDisableIfNoHndler)
  331. {
  332. CPoint point;
  333.     ::GetCursorPos(&point);
  334. CRect rcWindow;
  335. GetWindowRect(&rcWindow);
  336. point = point - rcWindow.TopLeft();
  337. DWORD dwoldState = m_dwButtonState;
  338. m_dwButtonState = m_rcCloseButton.PtInRect(point) ?
  339. ((::GetKeyState(VK_LBUTTON) < 0) ? 2 : 1) : 0;
  340. // if need paint---------------------------------------
  341.     if (dwoldState != m_dwButtonState)
  342. {
  343.         SendMessage(WM_NCPAINT);
  344. }
  345. }
  346. /*########################################################################
  347.   ------------------------------------------------
  348.   ------------------------------------------------
  349.   ########################################################################*/
  350. BOOL CCoolControlBar::GetTrackRect(CRect& rcTrack, int nEdge)
  351. {
  352. CRect rcWindow;
  353.     GetWindowRect(rcWindow);
  354.     rcTrack = rcWindow;
  355. BOOL bAtStart = TRUE;
  356. BOOL bAtEnd   = TRUE;
  357. if (m_pDockBar != NULL)
  358. {
  359. CCoolBarArray arrCoolBars;
  360. GetCoolBars  (arrCoolBars);
  361. bAtStart  =  (arrCoolBars[0] == this);
  362. bAtEnd    =  (arrCoolBars[arrCoolBars.GetSize() - 1] == this);
  363. }
  364. BOOL bALignLeft   = (m_dwStyle & CBRS_ALIGN_LEFT  );
  365. BOOL bALignRight  = (m_dwStyle & CBRS_ALIGN_RIGHT );
  366. BOOL bALignTop    = (m_dwStyle & CBRS_ALIGN_TOP   );
  367. BOOL bALignBottom = (m_dwStyle & CBRS_ALIGN_BOTTOM);
  368.     BOOL bHorz = IsHorizontal();
  369.     switch (nEdge)
  370.     {
  371. case 0:
  372. {
  373. if (!bALignRight) return FALSE;
  374. rcTrack.right = rcTrack.left + SIZING_WIDTH;
  375. }
  376. break;
  377. case 1:
  378. {
  379. if (!bALignBottom) return FALSE;
  380. rcTrack.bottom = rcTrack.top + SIZING_WIDTH;
  381. }
  382. break;
  383. case 2:
  384. {
  385. if (bALignRight || (bAtEnd && (bALignTop || bALignBottom))) return FALSE;
  386. rcTrack.left = rcTrack.right - SIZING_WIDTH;
  387. }
  388. break;
  389. case 3:
  390. {
  391. if (bALignBottom || (bAtEnd && (bALignLeft || bALignRight))) return FALSE;
  392. rcTrack.top = rcTrack.bottom - SIZING_WIDTH;
  393. }
  394. break;
  395.     default:
  396.         ASSERT(FALSE); // invalid hit test code
  397.     }
  398.     return TRUE;
  399. }
  400. void CCoolControlBar::UpdateWndSize(CPoint point)
  401. {
  402. ASSERT(m_bTracking);
  403. if (!m_bTracking) return;
  404. BOOL bHorz = IsHorizontal();
  405. CSize szOld = (bHorz ? m_szHorz : m_szVert);
  406. CSize szNew = szOld;
  407. //仅在控制栏所在的行内改变大小--------------------------
  408. if ((m_bTrackType == HTRIGHT && bHorz) || (m_bTrackType == HTBOTTOM && !bHorz))
  409. {
  410. CCoolBarArray arrCoolBars;
  411. GetCoolBars(arrCoolBars);
  412. //取得与它相邻的下一条控制条的指针------------------
  413. for (int i = 0; i < arrCoolBars.GetSize(); i++)
  414. {
  415. if (arrCoolBars.GetAt(i) == this) break;
  416. }
  417. CCoolControlBar *pCoolBar = arrCoolBars.GetAt(i + 1);
  418. if (bHorz)
  419. {
  420. if ((m_szHorz.cx == TITLE_HEIGHT && (point.x < m_oldPoint.x))
  421. || (pCoolBar->m_szHorz.cx == TITLE_HEIGHT && (point.x > m_oldPoint.x))) 
  422. {
  423. return;
  424. }
  425. m_szHorz.cx += (point.x - m_oldPoint.x);
  426. pCoolBar->m_szHorz.cx -= (point.x - m_oldPoint.x);
  427. if (m_szHorz.cx < TITLE_HEIGHT)
  428. {
  429. pCoolBar->m_szHorz.cx += m_szHorz.cx - TITLE_HEIGHT;
  430. m_szHorz.cx = TITLE_HEIGHT;
  431. }
  432. else if (pCoolBar->m_szHorz.cx < TITLE_HEIGHT)
  433. {
  434. m_szHorz.cx -= TITLE_HEIGHT - pCoolBar->m_szHorz.cx;
  435. pCoolBar->m_szHorz.cx = TITLE_HEIGHT;
  436. }
  437. AutoAlign();
  438. }
  439. else
  440. {
  441. if ((m_szVert.cy == TITLE_HEIGHT && (point.y < m_oldPoint.y))
  442.  || (pCoolBar->m_szVert.cy == TITLE_HEIGHT && (point.y > m_oldPoint.y))) 
  443. {
  444. return;
  445. }
  446. m_szVert.cy += (point.y - m_oldPoint.y);
  447. pCoolBar->m_szVert.cy -= (point.y - m_oldPoint.y);
  448. if (m_szVert.cy < TITLE_HEIGHT)
  449. {
  450. pCoolBar->m_szVert.cy += m_szVert.cy - TITLE_HEIGHT;
  451. m_szVert.cy = TITLE_HEIGHT;
  452. }
  453. else if (pCoolBar->m_szVert.cy < TITLE_HEIGHT)
  454. {
  455. m_szVert.cy -= TITLE_HEIGHT - pCoolBar->m_szVert.cy;
  456. pCoolBar->m_szVert.cy = TITLE_HEIGHT;
  457. }
  458. AutoAlign();
  459. }
  460. m_oldPoint = point;
  461. return;
  462. }
  463. switch (m_bTrackType) 
  464. {
  465. case HTLEFT:   szNew.cx -= (point.x - m_oldPoint.x); break;
  466. case HTRIGHT:  szNew.cx += (point.x - m_oldPoint.x); break;
  467. case HTTOP:    szNew.cy -= (point.y - m_oldPoint.y); break;
  468. case HTBOTTOM: szNew.cy += (point.y - m_oldPoint.y); break;
  469. default: return; break;
  470. }
  471. //取得可用的最大尺寸---------------------------------
  472. CRect rc;
  473. m_pDockSite->RepositionBars(0, 0xFFFF, AFX_IDW_PANE_FIRST, reposQuery, &rc, NULL, TRUE);
  474.     CSize szMax = szOld + rc.Size() - CSize(4, 4);
  475. //限制它的最小和最大尺寸-----------------------------
  476. szNew.cx = max(TITLE_HEIGHT, min(szNew.cx, szMax.cx));
  477. szNew.cy = max(TITLE_HEIGHT, min(szNew.cy, szMax.cy));
  478. //是否改变了尺寸-------------------------------------
  479. if ((szNew.cx - szOld.cx) == 0 && (szNew.cy - szOld.cy) == 0) return;
  480. (bHorz ? m_szHorz : m_szVert) = szNew;
  481. m_pDockSite->DelayRecalcLayout();
  482. m_oldPoint = point;
  483. }
  484. int CCoolControlBar::GetFirstBar()
  485. {
  486. ASSERT_VALID(m_pDockBar); 
  487.     int nThis = m_pDockBar->FindBar(this);
  488.     ASSERT(nThis != -1);
  489.     // find the first bar in row
  490.     for (int i = nThis - 1; i >= 0; i--)
  491. {
  492.         if (m_pDockBar->m_arrBars[i] == NULL)
  493. {
  494. return(i + 1);
  495. }
  496. }
  497.     ASSERT(FALSE);
  498. return -1;
  499. }
  500. int CCoolControlBar::GetLastBar()
  501. {
  502. ASSERT_VALID(m_pDockBar); 
  503.     int nThis = m_pDockBar->FindBar(this);
  504.     ASSERT(nThis != -1);
  505.     int nBarsCount = m_pDockBar->m_arrBars.GetSize();
  506.     // find the last bar in row
  507.     for (int i = nThis + 1; i < nBarsCount; i++)
  508. {
  509.         if (m_pDockBar->m_arrBars[i] == NULL)
  510. {
  511.             return(i - 1);
  512. }
  513. }
  514.     ASSERT(FALSE);
  515. return -1;
  516. }
  517. void CCoolControlBar::GetCoolBars(CCoolBarArray &arrCoolBars)
  518. {
  519. ASSERT_VALID(m_pDockBar); 
  520.     arrCoolBars.RemoveAll();
  521. int nFirst = GetFirstBar();
  522. int nLast  = GetLastBar();
  523.     for (int i = nFirst; i <= nLast; i++)
  524.     {
  525.         CControlBar* pBar = (CControlBar*)m_pDockBar->m_arrBars[i];
  526.         if (HIWORD(pBar) == 0)  continue; // placeholder
  527.         if (!pBar->IsVisible()) continue;
  528.         if (FindCoolBar(pBar) >= 0)
  529. {
  530.             arrCoolBars.Add((CCoolControlBar*)pBar);
  531. }
  532.     }
  533. }
  534. int CCoolControlBar::FindCoolBar(CControlBar *pBar)
  535. {
  536.    for (int nPos = 0; nPos < m_arrBars.GetSize(); nPos++)
  537.    {
  538.         if (m_arrBars[nPos] == pBar)
  539. {
  540.             return nPos; // got it
  541. }
  542.    }
  543.     return -1; // not found
  544. }
  545. /*========================================================================
  546. Params:
  547. nLengthAvail: 此行中所有控制条共有的有用的长度
  548. bHorz: 控制条停泊方向
  549.     ----------------------------------------------------------
  550. returns:
  551.     ----------------------------------------------------------
  552. Remarks: 自动分配各控制条的尺寸
  553. ==========================================================================*/
  554. BOOL CCoolControlBar::AutoSize(int nLengthAvail, BOOL bHorz)
  555. {
  556. CCoolBarArray  arrCoolBars;
  557.     GetCoolBars(arrCoolBars);
  558.     CCoolControlBar *pCoolBar = NULL;
  559.     int nActualLength = 0;
  560.     int nWidth = 0, nSizingWidth = 0;
  561. int nFirst = GetFirstBar();
  562. int nLast  = GetLastBar();
  563. // 减去可见的固定长度的控制栏的长度
  564.     // subtract the visible fixed bars' lengths-----------------
  565.     for (int i = nFirst; i <= nLast; i++)
  566.     {
  567.         CControlBar* pFixedBar = (CControlBar*)m_pDockBar->m_arrBars[i];
  568.         if (HIWORD(pFixedBar) == 0) 
  569. {
  570. continue; // 占位符(placeholder)
  571. }
  572.         else if (!pFixedBar->IsVisible() || FindCoolBar(pFixedBar) >= 0) 
  573. {
  574. continue; // 不可见或不是固定控制栏.
  575. }
  576. CRect rcBarWindow;
  577.         pFixedBar->GetWindowRect(&rcBarWindow);
  578.         nLengthAvail -= (bHorz ? rcBarWindow.Width() - 2 : rcBarWindow.Height() - 2);
  579.     }
  580. // 计算实际长度以及公共宽度.
  581.     // compute actual and min lengths; also the common width----
  582.     for (i = 0; i < arrCoolBars.GetSize(); i++)
  583.     {
  584.         pCoolBar = arrCoolBars[i];
  585.         nActualLength += bHorz ? pCoolBar->m_szHorz.cx - 2 : pCoolBar->m_szVert.cy - 2;
  586.         nWidth = max(nWidth, bHorz ? pCoolBar->m_szHorz.cy : pCoolBar->m_szVert.cx);
  587. if (pCoolBar->m_bTracking)
  588. {
  589. //如果此控制栏正在被用户改变大小----------------------------
  590. //if this control bar is sizing now-------------------------
  591. nSizingWidth = bHorz ? pCoolBar->m_szHorz.cy: pCoolBar->m_szVert.cx;
  592. }
  593.     }
  594. //如果其中有控制栏在改变大小,则公共宽度为当前正在改变宽度的控制栏的
  595. //宽度,否则为当前栏中,宽度最大的那条控制栏的宽度------------------
  596. if (nSizingWidth > 0)
  597. {
  598. nWidth = nSizingWidth;
  599. }
  600.     
  601. // 使所有的控制栏具有相同的宽度.
  602.     // make the bars same width---------------------------------
  603. for (i = 0; i < arrCoolBars.GetSize(); i++)
  604. {
  605.         (bHorz ? arrCoolBars[i]->m_szHorz.cy : arrCoolBars[i]->m_szVert.cx) = nWidth;
  606. }
  607. // no change------------------------------------------------
  608.     if (nActualLength == nLengthAvail)
  609. {
  610.         return FALSE; 
  611. }
  612.     int nLengthDelta = nLengthAvail - nActualLength - 2;
  613. int nCount = arrCoolBars.GetSize();
  614. int bSizingBar = -1;
  615. int nlength = 0;
  616. //查看有否有控制栏处于拖动中----------------------------
  617. for (i = 0; i < nCount; i++)
  618. {
  619. if (arrCoolBars[i]->m_bTracking)
  620. {
  621. if ((!arrCoolBars[i]->IsHorizontal() && (arrCoolBars[i]->m_bTrackType == HTLEFT || arrCoolBars[i]->m_bTrackType == HTRIGHT))
  622.   || (arrCoolBars[i]->IsHorizontal() && (arrCoolBars[i]->m_bTrackType == HTTOP  || arrCoolBars[i]->m_bTrackType == HTBOTTOM)))
  623. {
  624. return FALSE;
  625. }
  626. bSizingBar = i;
  627. break;
  628. }
  629. }
  630. // 分配各控制栏尺寸.
  631.     // distribute the difference between the bars, but-----------
  632.     // don't shrink them below minsize
  633. BOOL bChangeDefaultSize = FALSE;
  634. while (nLengthDelta != 0)
  635. {
  636. BOOL bDefaultSize = TRUE;
  637. BOOL bMinSize = TRUE;
  638. for (i = 0; i < nCount; i++)
  639. {
  640. pCoolBar = arrCoolBars[i];
  641. int nLenght = bHorz ? pCoolBar->m_szHorz.cx : pCoolBar->m_szVert.cy;
  642. if (nLenght == TITLE_HEIGHT && nLengthDelta < 0) // already at min length--
  643. {
  644. continue;
  645. }
  646. bMinSize = FALSE;
  647. if (nLenght < m_szDefault.cy && nLengthDelta < 0 && !bChangeDefaultSize) // already at default length--
  648. {
  649. continue;
  650. }
  651. // sign of nLengthDelta-------------------------------------------
  652. (bHorz ? pCoolBar->m_szHorz.cx : pCoolBar->m_szVert.cy) += nLengthDelta / abs(nLengthDelta);
  653. nLengthDelta -= nLengthDelta / abs(nLengthDelta);
  654. bDefaultSize = FALSE;
  655. if (nLengthDelta == 0) break;
  656. }// end for
  657. if (bMinSize) return FALSE;
  658. bChangeDefaultSize = bDefaultSize;
  659. }// end while
  660.     return TRUE;
  661. }
  662. void CCoolControlBar::AutoAlign()
  663. {
  664. int nFirst = GetFirstBar();
  665. int nLast  = GetLastBar();
  666.     BOOL bHorz = (m_dwStyle & (CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM));
  667.     //是否需要重新调整-------------------------------
  668. BOOL bNeedRecalc = FALSE;
  669.     int nPos, nAlign = bHorz ? -2 : 0;
  670.     CRect rcControlWnd, rcDockWnd;
  671.     m_pDockBar->GetWindowRect(&rcDockWnd);
  672.     for (int i = nFirst; i <= nLast; i++)
  673.     {
  674.         CControlBar* pControlBar = (CControlBar*)m_pDockBar->m_arrBars[i];
  675. //placeholder-----------------------------
  676. if (HIWORD(pControlBar) == 0)  continue;
  677. //it's not visible------------------------
  678.         else if (!pControlBar->IsVisible()) continue;
  679. //Get rect and offset---------------------
  680.         pControlBar->GetWindowRect(&rcControlWnd);
  681.         rcControlWnd.OffsetRect(-rcDockWnd.TopLeft());
  682. //Is CCoolControlBar----------------------
  683.         if ((nPos = FindCoolBar(pControlBar)) >= 0)
  684. {
  685.             rcControlWnd = CRect(rcControlWnd.TopLeft(), bHorz ?
  686.                 m_arrBars[nPos]->m_szHorz : m_arrBars[nPos]->m_szVert);
  687. }
  688. //Align-----------------------------------
  689.         if ((bHorz ? rcControlWnd.left : rcControlWnd.top) != nAlign)
  690.         {
  691.             if (!bHorz)
  692. {
  693.                 rcControlWnd.OffsetRect(0, nAlign - rcControlWnd.top -2);
  694. }
  695.             else
  696. {
  697.                 rcControlWnd.OffsetRect(nAlign - rcControlWnd.left, -2);
  698. }
  699.             pControlBar->MoveWindow(rcControlWnd);
  700.             bNeedRecalc = TRUE;
  701.         }
  702.         nAlign += (bHorz ? rcControlWnd.Width() - 2 : rcControlWnd.Height() - 2);
  703.     }
  704. //if need recalc-------------------------------
  705.     if (bNeedRecalc)
  706.     {
  707.         m_pDockSite->DelayRecalcLayout();
  708.     }
  709. }
  710. inline BOOL CCoolControlBar::IsHorizontal()
  711. {
  712.     return (m_dwStyle & (CBRS_ALIGN_TOP | CBRS_ALIGN_BOTTOM));
  713. }
  714. /*####################################################################
  715. ------------------------------------------------
  716.  Load / Save controlbar states
  717. ------------------------------------------------
  718.   ####################################################################*/
  719. void CCoolControlBar::LoadState(LPCTSTR lpszProfileName)
  720. {
  721.     ASSERT_VALID(this);
  722.     ASSERT(GetSafeHwnd() != NULL); // must be called after Create()
  723.     CWinApp* pApp = AfxGetApp();
  724.     TCHAR szSection[256];
  725.     wsprintf(szSection, _T("%s\CoolControlBar(%d)"), lpszProfileName, GetDlgCtrlID());
  726.     m_szHorz.cx  = (int)pApp->GetProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
  727.     m_szHorz.cy  = (int)pApp->GetProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);
  728.     m_szVert.cx  = (int)pApp->GetProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
  729.     m_szVert.cy  = (int)pApp->GetProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);
  730.     m_szFloat.cx = (int)pApp->GetProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
  731.     m_szFloat.cy = (int)pApp->GetProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
  732. }
  733. void CCoolControlBar::SaveState(LPCTSTR lpszProfileName)
  734. {
  735.     // place your SaveState or GlobalSaveState call in
  736.     // CMainFrame::DestroyWindow(), not in OnDestroy()
  737.     ASSERT_VALID(this);
  738.     ASSERT(GetSafeHwnd() != NULL);
  739.     CWinApp* pApp = AfxGetApp();
  740.     TCHAR szSection[256];
  741.     wsprintf(szSection, _T("%s\CoolControlBar(%d)"), lpszProfileName, GetDlgCtrlID());
  742.     pApp->WriteProfileInt(szSection, _T("sizeHorzCX"), m_szHorz.cx);
  743.     pApp->WriteProfileInt(szSection, _T("sizeHorzCY"), m_szHorz.cy);
  744.     pApp->WriteProfileInt(szSection, _T("sizeVertCX"), m_szVert.cx);
  745.     pApp->WriteProfileInt(szSection, _T("sizeVertCY"), m_szVert.cy);
  746.     pApp->WriteProfileInt(szSection, _T("sizeFloatCX"), m_szFloat.cx);
  747.     pApp->WriteProfileInt(szSection, _T("sizeFloatCY"), m_szFloat.cy);
  748. }
  749. void CCoolControlBar::LoadStates(LPCTSTR lpszProfileName)
  750. {
  751.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  752. {
  753.         ((CCoolControlBar*) m_arrBars[i])->LoadState(lpszProfileName);
  754. }
  755. }
  756. void CCoolControlBar::SaveStates(LPCTSTR lpszProfileName)
  757. {
  758.     for (int i = 0; i < m_arrBars.GetSize(); i++)
  759. {
  760.         ((CCoolControlBar*) m_arrBars[i])->SaveState(lpszProfileName);
  761. }
  762. }
  763. /*########################################################################
  764.   ------------------------------------------------
  765.    绘制标题栏函数
  766.   ------------------------------------------------
  767.   ########################################################################*/
  768. void CCoolControlBar::DrawTitleBar(CDC *pDC, const CRect &rect, BOOL bHorz)
  769. {
  770. CRect rcTitleBar(rect);
  771. CPen pen(0, 1, ::GetSysColor(COLOR_3DSHADOW));
  772. CPen *oldpen = pDC->SelectObject(&pen);
  773. pDC->SetTextColor(RGB(0, 0, 0));
  774. CString strWindowText;
  775. GetWindowText(strWindowText);
  776. if (bHorz)
  777. {
  778. CFont font, *oldfont;
  779. font.CreateFont(-12,0,900,0,400,0,0,0,0,0,0,0,0,"宋体");
  780. oldfont = pDC->SelectObject(&font);
  781. pDC->TextOut(rcTitleBar.left + 3, rcTitleBar.bottom - 3, strWindowText);
  782. pDC->FillSolidRect(4, 2, 14, 16, ::GetSysColor(COLOR_3DFACE));
  783. pDC->SelectObject(&oldfont);
  784. rcTitleBar.DeflateRect(2, -1, 1, -1);
  785. pDC->Draw3dRect(rcTitleBar, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
  786. }
  787. else
  788. {
  789. rcTitleBar.DeflateRect(-1, 2, -1, 1);
  790. pDC->Draw3dRect(rcTitleBar, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
  791. CFont font, *oldfont;
  792. font.CreateFont(-12,0,0,0,400,0,0,0,0,0,0,0,0,"宋体");
  793. oldfont = pDC->SelectObject(&font);
  794. rcTitleBar.DeflateRect(5, 0, 15, 0);
  795. pDC->DrawText(strWindowText, rcTitleBar, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
  796. pDC->SelectObject(oldfont);
  797. }
  798. pDC->SelectObject(oldpen);
  799. }
  800. void CCoolControlBar::DrawCloseButton(CDC *pDC, DWORD dwState)
  801. {
  802. //hot-----------------------
  803. if (dwState == 1)
  804. {
  805. pDC->FillSolidRect(m_rcCloseButton, RGB(225,225,255));
  806. pDC->Draw3dRect(m_rcCloseButton, RGB(80,80,100), RGB(80,80,100));
  807. }
  808. //pressed--------------------
  809. else if(dwState == 2)
  810. {
  811. pDC->FillSolidRect(m_rcCloseButton, RGB(130,150,200));
  812. pDC->Draw3dRect(m_rcCloseButton, RGB(80,80,100), RGB(80,80,100));
  813. pDC->SelectStockObject(WHITE_PEN);
  814. }
  815. //draw 'x' sign---------------------------------------
  816. pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 3);
  817. pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 9);
  818. pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 8);
  819. pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 2);
  820. pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 4);
  821. pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 10);
  822. pDC->MoveTo(m_rcCloseButton.left + 3, m_rcCloseButton.top + 9);
  823. pDC->LineTo(m_rcCloseButton.left + 9, m_rcCloseButton.top + 3);
  824. pDC->SelectStockObject(BLACK_PEN);
  825. }