XTExcelTabCtrl.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:32k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTExcelTabCtrl.cpp : implementation of the CXTExcelTabCtrl class.
  2. //
  3. // This file is a part of the XTREME CONTROLS MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Resource.h"
  22. #include "Common/XTPResourceManager.h"
  23. #include "Common/XTPColorManager.h"
  24. #include "Common/XTPDrawHelpers.h"
  25. #include "XTGlobal.h"
  26. #include "XTExcelTabCtrl.h"
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. static const int GRIPPER_WIDTH = 6;
  33. static const int BUTTON_COUNT = 4;
  34. #define XT_IDC_BTN_LEFT                 100
  35. #define XT_IDC_BTN_RIGHT                101
  36. #define XT_IDC_BTN_HOME                 102
  37. #define XT_IDC_BTN_END                  103
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CXTExcelTabCtrlButtonState
  40. CXTExcelTabCtrlButtonState::CXTExcelTabCtrlButtonState()
  41. : m_rect(0, 0, 0, 0)
  42. , m_bPressed(false)
  43. , m_bEnabled(true)
  44. , m_bHilight(false)
  45. {
  46. m_iCommand = 0;
  47. }
  48. void CXTExcelTabCtrlButtonState::SetInfo(CRect rect, int iCommand, XTArrowIcon iconType)
  49. {
  50. m_rect = rect;
  51. m_iCommand = iCommand;
  52. m_IconType = iconType;
  53. }
  54. IMPLEMENT_THEME_HOST(CXTExcelTabCtrl)
  55. IMPLEMENT_THEME_REFRESH(CXTExcelTabCtrl, CWnd)
  56. /////////////////////////////////////////////////////////////////////////////
  57. // CXTExcelTabCtrl
  58. CXTExcelTabCtrl::CXTExcelTabCtrl()
  59. : CXTThemeManagerStyleHost(GetThemeFactoryClass())
  60. , m_iBtnLeft(-1)
  61. , m_iBtnRight(-1)
  62. , m_iBtnHome(-1)
  63. , m_iBtnEnd(-1)
  64. , m_bPainted(false)
  65. , m_iBtnHilight(-1)
  66. {
  67. m_dwStyle = NULL;
  68. m_nCurSel = -1;
  69. m_nOffset = 0;
  70. m_nClientWidth = 0;
  71. m_nClientHeight = 0;
  72. m_pNormFont = &XTAuxData().font;
  73. m_pBoldFont = &XTAuxData().fontBold;
  74. m_bManagingViews = false;
  75. m_rectGripper = CRect(0, 0, 0, 0);
  76. m_bTracking = false;
  77. m_bUserColors = false;
  78. m_pWndLastFocus = NULL;
  79. m_iGripperPosPerCent = 0;
  80. m_xGripperPos = -1;
  81. // Initialize the width and height for the left, right, home
  82. // and end buttons.
  83. m_cy = ::GetSystemMetrics(SM_CYHSCROLL);
  84. m_cx = ::GetSystemMetrics(SM_CXHSCROLL)-1;
  85. UpdateDefaultColors();
  86. // Create the icons used by the left, right, home and end buttons.
  87. CreateButtonIcons();
  88. }
  89. CXTExcelTabCtrl::~CXTExcelTabCtrl()
  90. {
  91. // Cleanup
  92. ClearAllItems();
  93. FreeButtonIcons();
  94. }
  95. IMPLEMENT_DYNAMIC(CXTExcelTabCtrl, CWnd)
  96. BEGIN_MESSAGE_MAP(CXTExcelTabCtrl, CWnd)
  97. //{{AFX_MSG_MAP(CXTExcelTabCtrl)
  98. ON_WM_CREATE()
  99. ON_WM_PAINT()
  100. ON_MESSAGE(WM_PRINTCLIENT, OnPrintClient)
  101. ON_WM_ERASEBKGND()
  102. ON_BN_CLICKED(XT_IDC_BTN_LEFT, OnLeftArrow)
  103. ON_BN_CLICKED(XT_IDC_BTN_RIGHT, OnRightArrow)
  104. ON_BN_CLICKED(XT_IDC_BTN_HOME, OnHomeArrow)
  105. ON_BN_CLICKED(XT_IDC_BTN_END, OnEndArrow)
  106. ON_WM_SIZE()
  107. ON_WM_LBUTTONDOWN()
  108. ON_WM_MOUSEMOVE()
  109. ON_WM_SETCURSOR()
  110. ON_WM_LBUTTONUP()
  111. ON_WM_LBUTTONDBLCLK()
  112. ON_WM_HSCROLL()
  113. ON_WM_TIMER()
  114. //}}AFX_MSG_MAP
  115. END_MESSAGE_MAP()
  116. BOOL CXTExcelTabCtrl::Create(DWORD dwStyle, const CRect& rect, CWnd* pParentWnd, UINT nID)
  117. {
  118. ASSERT(pParentWnd != NULL); // must be valid.
  119. // Call the base class for creation.
  120. if (!CWnd::Create(NULL, NULL, dwStyle, rect, pParentWnd, nID))
  121. {
  122. TRACE0("Failed to create flat tab control.n");
  123. return FALSE;
  124. }
  125. return TRUE;
  126. }
  127. int CXTExcelTabCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
  128. {
  129. if (CWnd::OnCreate(lpCreateStruct) == -1)
  130. return -1;
  131. // Save the window style.
  132. m_dwStyle = lpCreateStruct->style;
  133. m_nClientWidth = lpCreateStruct->cx;
  134. m_nClientHeight = lpCreateStruct->cy;
  135. SetTabStyle(m_dwStyle);
  136. return 0;
  137. }
  138. void CXTExcelTabCtrl::SetGripperPosition(int x, bool bPercent)
  139. {
  140. // only valid for tabs with horizontal scroll bars
  141. if (!(m_dwStyle & FTS_XT_HSCROLL)) return;
  142. int x_percent;
  143. if (bPercent)
  144. {
  145. x_percent = x;
  146. x = m_nClientWidth * x / 100;
  147. }
  148. else
  149. {
  150. x_percent = x * 100 / m_nClientWidth;
  151. }
  152. // too far to the left ?
  153. const int arrowWidth = 0; //GetTotalArrowWidth();
  154. if (x < arrowWidth) x = arrowWidth;
  155. // too far to the right ?
  156. const int sbExtreme = (m_nClientWidth - 4 * m_cx - m_cy);
  157. if (x > sbExtreme) x = sbExtreme;
  158. m_xGripperPos = x;
  159. m_iGripperPosPerCent = x_percent;
  160. m_rectGripper = m_rectTabs;
  161. m_rectGripper.left += x;
  162. m_rectGripper.right = m_rectGripper.left + GRIPPER_WIDTH;
  163. const int isbottom = ((m_dwStyle & FTS_XT_BOTTOM) == FTS_XT_BOTTOM);
  164. m_rectSB_H = CRect(
  165. m_rectGripper.right,
  166. m_rectTabs.top - !isbottom,
  167. m_rectTabs.right - m_cy,
  168. m_rectTabs.bottom + isbottom);
  169. m_wndHScrollBar.MoveWindow(m_rectSB_H);
  170. EnableButtons();
  171. InvalidateRect(m_rectTabs);
  172. }
  173. void CXTExcelTabCtrl::SetTabStyle(DWORD dwStyle)
  174. {
  175. m_dwStyle = dwStyle;
  176. if (!GetSafeHwnd())
  177. return;
  178. if (m_dwStyle & FTS_XT_HASHOMEEND) m_dwStyle |= FTS_XT_HASARROWS;
  179. // If we use tooltips, create the control.
  180. if (m_dwStyle & FTS_XT_TOOLTIPS)
  181. {
  182. if (m_ToolTip.GetSafeHwnd() == 0)
  183. {
  184. CString strTipText;
  185. XTPResourceManager()->LoadString(&strTipText, XT_IDS_TIPTEXT);
  186. m_ToolTip.Create(this);
  187. m_ToolTip.Activate(TRUE);
  188. m_ToolTip.AddTool(this, strTipText);
  189. m_ToolTip.SendMessage(TTM_SETMAXTIPWIDTH, 0, SHRT_MAX); // Allow multi line tooltips
  190. }
  191. }
  192. else
  193. {
  194. m_ToolTip.DestroyWindow();
  195. }
  196. CRect rectDummy(0, 0, 0, 0);
  197. // If we use arrow buttons, create the buttons.
  198. if (m_dwStyle & FTS_XT_HASARROWS)
  199. {
  200. int nIndex = 0;
  201. // Create the home button.
  202. if (m_dwStyle & FTS_XT_HASHOMEEND)
  203. {
  204. m_buttons[nIndex].SetInfo(rectDummy, XT_IDC_BTN_HOME,
  205. xtArrowIconLeftHome);
  206. m_iBtnHome = nIndex;
  207. ++nIndex;
  208. }
  209. else
  210. {
  211. m_iBtnHome = 3;
  212. }
  213. // Create the left button.
  214. m_buttons[nIndex].SetInfo(rectDummy, XT_IDC_BTN_LEFT, xtArrowIconLeft);
  215. m_iBtnLeft = nIndex;
  216. ++nIndex;
  217. // Create the right button.
  218. m_buttons[nIndex].SetInfo(rectDummy, XT_IDC_BTN_RIGHT, xtArrowIconRight);
  219. m_iBtnRight = nIndex;
  220. ++nIndex;
  221. // Create the end button.
  222. if (m_dwStyle & FTS_XT_HASHOMEEND)
  223. {
  224. m_buttons[nIndex].SetInfo(rectDummy, XT_IDC_BTN_END,
  225. xtArrowIconRightHome);
  226. m_iBtnEnd = nIndex;
  227. ++nIndex;
  228. }
  229. else
  230. {
  231. m_iBtnEnd = 3;
  232. }
  233. }
  234. if (m_dwStyle & FTS_XT_HSCROLL)
  235. {
  236. if (m_wndHScrollBar.GetSafeHwnd() == 0)
  237. {
  238. CRect rc(0, 0, 0, 0);
  239. VERIFY(m_wndHScrollBar.Create(WS_VISIBLE | WS_CHILD | SBS_HORZ,
  240. rc, this, AFX_IDW_HSCROLL_FIRST));
  241. SetGripperPosition(60, true);
  242. }
  243. }
  244. else
  245. {
  246. m_wndHScrollBar.DestroyWindow();
  247. m_rectSB_H = CRect(0, 0, 0, 0);
  248. }
  249. RecalcLayout();
  250. SetGripperPosition(m_iGripperPosPerCent, true);
  251. RedrawWindow();
  252. }
  253. int CXTExcelTabCtrl::GetGripperPosition() const
  254. {
  255. return m_xGripperPos;
  256. }
  257. BOOL CXTExcelTabCtrl::OnEraseBkgnd(CDC* pDC)
  258. {
  259. if (GetItemCount() == 0)
  260. {
  261. pDC->FillSolidRect(m_rectViews, GetXtremeColor(COLOR_3DFACE));
  262. }
  263. return TRUE;
  264. }
  265. void CXTExcelTabCtrl::CreateButtonIcons()
  266. {
  267. // obsolete
  268. }
  269. void CXTExcelTabCtrl::FreeButtonIcons()
  270. {
  271. // obsolete
  272. }
  273. int CXTExcelTabCtrl::GetTabWidth(int nItem) const
  274. {
  275. CDC *pDC = CDC::FromHandle(::GetDC(m_hWnd));
  276. CFont* pOldFont = pDC->SelectObject((m_nCurSel == nItem) ?
  277. m_pBoldFont : m_pNormFont);
  278. CSize size = pDC->GetTextExtent(m_tcbItems[nItem]->szTabLabel);
  279. pDC->SelectObject(pOldFont);
  280. ::ReleaseDC(m_hWnd, pDC->m_hDC);
  281. return size.cx + m_cy + (m_cy / 2);
  282. }
  283. int CXTExcelTabCtrl::GetTotalTabWidth() const
  284. {
  285. int iWidth = 0;
  286. const int cItems = GetItemCount();
  287. const int iOverlap = GetOverlap();
  288. int i;
  289. for (i = 0; i < cItems; i++)
  290. {
  291. iWidth += GetTabWidth(i);
  292. if (i != 0)
  293. {
  294. iWidth -= iOverlap;
  295. }
  296. }
  297. return iWidth;
  298. }
  299. int CXTExcelTabCtrl::GetTotalArrowWidth() const
  300. {
  301. int iWidth = 0;
  302. if (m_dwStyle & FTS_XT_HASARROWS)
  303. iWidth += (m_cx * 2);
  304. if (m_dwStyle & FTS_XT_HASHOMEEND)
  305. iWidth += (m_cx * 2);
  306. return iWidth;
  307. }
  308. int CXTExcelTabCtrl::GetTotalTabAreaWidth() const
  309. {
  310. int iWidth;
  311. if (m_dwStyle & FTS_XT_HSCROLL)
  312. {
  313. iWidth = m_xGripperPos;
  314. }
  315. else
  316. {
  317. iWidth = m_nClientWidth;
  318. }
  319. iWidth -= GetTotalArrowWidth();
  320. return iWidth;
  321. }
  322. void CXTExcelTabCtrl::InvalidateTabs()
  323. {
  324. if (GetSafeHwnd())
  325. {
  326. // invalidate the visible tab area
  327. // to minimize flicker - don't erase the background
  328. CRect rcTabs;
  329. rcTabs.left = GetTotalArrowWidth();
  330. rcTabs.top = m_rectTabs.top;
  331. rcTabs.right = rcTabs.left + (GetTotalTabWidth() - m_nOffset);
  332. rcTabs.bottom = m_rectTabs.bottom;
  333. InvalidateRect(&rcTabs, FALSE);
  334. // invalidate the blank area to the right of the tabs
  335. if (rcTabs.right < m_nClientWidth)
  336. {
  337. rcTabs.left = rcTabs.right;
  338. rcTabs.right = m_nClientWidth;
  339. InvalidateRect(&rcTabs, TRUE);
  340. }
  341. }
  342. }
  343. void CXTExcelTabCtrl::EnableButtons()
  344. {
  345. if (m_dwStyle & FTS_XT_HASARROWS)
  346. {
  347. m_buttons[m_iBtnLeft].m_bEnabled = (m_nOffset > 0);
  348. m_buttons[m_iBtnRight].m_bEnabled =
  349. (GetTotalTabWidth() - m_nOffset > GetTotalTabAreaWidth() - 1);
  350. if (m_dwStyle & FTS_XT_HASHOMEEND)
  351. {
  352. m_buttons[m_iBtnHome].m_bEnabled = m_buttons[m_iBtnLeft].m_bEnabled;
  353. m_buttons[m_iBtnEnd].m_bEnabled = m_buttons[m_iBtnRight].m_bEnabled;
  354. }
  355. CRect rc = m_buttons[m_iBtnLeft].m_rect;
  356. rc.left = 0;
  357. rc.right = GetTotalArrowWidth();
  358. InvalidateRect(rc);
  359. }
  360. else
  361. {
  362. InvalidateRect(CRect(0, 0, GetTotalArrowWidth(), m_nClientHeight));
  363. }
  364. }
  365. BOOL CXTExcelTabCtrl::GetItemRect(int nItem, LPRECT lpRect)
  366. {
  367. const int cItems = GetItemCount();
  368. if (nItem < 0 || nItem >= cItems)
  369. return FALSE;
  370. const int iOverlap = GetOverlap();
  371. int x = GetTotalArrowWidth();
  372. int i;
  373. for (i = 0; i < nItem; i++)
  374. {
  375. x += GetTabWidth(i) - iOverlap;
  376. }
  377. lpRect->left = x - m_nOffset;
  378. lpRect->top = m_rectTabs.top;
  379. lpRect->right = lpRect->left + GetTabWidth(nItem);
  380. lpRect->bottom = m_rectTabs.bottom;
  381. return TRUE;
  382. }
  383. void CXTExcelTabCtrl::ResetMouseOver()
  384. {
  385. for (int i = 0; i < BUTTON_COUNT; ++i)
  386. {
  387. m_buttons[i].m_bHilight = false;
  388. }
  389. }
  390. int CXTExcelTabCtrl::ButtonHitTest(CPoint& pt)
  391. {
  392. ResetMouseOver();
  393. int i;
  394. for (i = 0; i < BUTTON_COUNT; ++i)
  395. {
  396. if (m_buttons[i].m_rect.PtInRect(pt))
  397. {
  398. m_buttons[i].m_bHilight = true;
  399. return i;
  400. }
  401. }
  402. return -1;
  403. }
  404. int CXTExcelTabCtrl::HitTest(TCHITTESTINFO* pHitTestInfo) const
  405. {
  406. // ignore hits on the buttons
  407. int iHitX = pHitTestInfo->pt.x;
  408. if (iHitX < GetTotalArrowWidth())
  409. return -1;
  410. // on or to the right of the the scroll bar/gripper ?
  411. if ((m_dwStyle & FTS_XT_HSCROLL) && iHitX > m_rectGripper.left)
  412. {
  413. return -1;
  414. }
  415. const int iOverlap = GetOverlap();
  416. // check if any tabs were hit
  417. int x = GetTotalArrowWidth() - m_nOffset;
  418. const int cItems = GetItemCount();
  419. int i;
  420. for (i = 0; i < cItems; i++)
  421. {
  422. int iTabWidth = GetTabWidth(i);
  423. if (i != cItems - 1)
  424. {
  425. iTabWidth -= iOverlap;
  426. }
  427. if ((x <= iHitX) && (iHitX <= x + iTabWidth))
  428. {
  429. return i;
  430. }
  431. x += iTabWidth;
  432. }
  433. // hit point is right of rightmost tab
  434. return -1;
  435. }
  436. void CXTExcelTabCtrl::OnLeftArrow()
  437. {
  438. // Move the tabs right, ensuring that we move right by one
  439. // whole tab each time ala Microsoft Access
  440. CPoint Point(GetTotalArrowWidth() + 1 + GetOverlap(), 1);
  441. TCHITTESTINFO htInfo;
  442. htInfo.pt = Point;
  443. int iTab = HitTest(&htInfo);
  444. if (iTab != -1)
  445. {
  446. m_nOffset = 0;
  447. RECT rect;
  448. if (GetItemRect(iTab - 1, &rect))
  449. {
  450. m_nOffset += rect.left;
  451. m_nOffset -= GetTotalArrowWidth();
  452. EnableButtons();
  453. InvalidateTabs();
  454. }
  455. }
  456. }
  457. void CXTExcelTabCtrl::OnRightArrow()
  458. {
  459. // Move the tabs left, ensuring that we move left by one
  460. // whole tab each time ala Microsoft Access
  461. CPoint Point(GetTotalArrowWidth()+ 1 + GetOverlap(), 1);
  462. TCHITTESTINFO htInfo;
  463. htInfo.pt = Point;
  464. int iTab = HitTest(&htInfo);
  465. if (iTab != -1)
  466. {
  467. RECT rect;
  468. if (GetItemRect(iTab + 1, &rect))
  469. {
  470. m_nOffset += rect.left - GetTotalArrowWidth();
  471. EnableButtons();
  472. InvalidateTabs();
  473. }
  474. }
  475. }
  476. void CXTExcelTabCtrl::OnHomeArrow()
  477. {
  478. m_nOffset = 0;
  479. EnableButtons();
  480. InvalidateTabs();
  481. }
  482. void CXTExcelTabCtrl::OnEndArrow()
  483. {
  484. m_nOffset = GetTotalTabWidth() - GetTotalTabAreaWidth() + 1;
  485. EnableButtons();
  486. InvalidateTabs();
  487. }
  488. void CXTExcelTabCtrl::OnSize(UINT nType, int cx, int cy)
  489. {
  490. CWnd::OnSize(nType, cx, cy);
  491. m_nClientWidth = cx;
  492. m_nClientHeight = cy;
  493. RecalcLayout();
  494. SetGripperPosition(m_iGripperPosPerCent, true);
  495. SyncScrollBar();
  496. }
  497. int CXTExcelTabCtrl::InsertItem(int nItem, LPCTSTR lpszItem, CWnd* pWndControl)
  498. {
  499. const int cItems = GetItemCount();
  500. if (nItem < 0 || nItem > cItems)
  501. return -1;
  502. if (pWndControl)
  503. {
  504. ASSERT(::IsWindow(pWndControl->m_hWnd));
  505. // managed view should be a hidden child
  506. ASSERT((::GetWindowLong(pWndControl->m_hWnd, GWL_STYLE) & (WS_VISIBLE | WS_CHILD)) == WS_CHILD);
  507. // can't have both managed and non-managed tabs
  508. ASSERT(m_bManagingViews || cItems == 0);
  509. m_bManagingViews = true;
  510. pWndControl->SetParent(this);
  511. pWndControl->SetWindowPos(NULL, m_rectViews.left, m_rectViews.top,
  512. m_rectViews.Width(), m_rectViews.Height(),
  513. SWP_NOZORDER | SWP_NOREDRAW);
  514. }
  515. // Allocate a new CXTTcbItem object.
  516. CXTTcbItem* pMember = new CXTTcbItem;
  517. if (pMember == NULL)
  518. return -1;
  519. pMember->pWnd = pWndControl;
  520. pMember->szTabLabel = lpszItem;
  521. pMember->szToolTipLabel = lpszItem;
  522. pMember->uiToolTipId = GetItemCount();
  523. if (nItem <= m_nCurSel) ++m_nCurSel;
  524. // Add the new CXTTcbItem to the tab item list.
  525. m_tcbItems.InsertAt(nItem, pMember);
  526. if (m_nCurSel < 0) m_nCurSel = 0;
  527. EnableButtons();
  528. InvalidateTabs();
  529. SetCurSel(nItem);
  530. return nItem;
  531. }
  532. BOOL CXTExcelTabCtrl::_DeleteItem(int nItem)
  533. {
  534. const int cItems = (int)m_tcbItems.GetSize();
  535. if (nItem < 0 || nItem >= cItems)
  536. return FALSE;
  537. // Remove the item from the string arrays.
  538. CWnd *pWndControl = m_tcbItems[nItem]->pWnd;
  539. if (::IsWindow(pWndControl->GetSafeHwnd()))
  540. {
  541. pWndControl->ShowWindow(SW_HIDE);
  542. pWndControl->SetParent(NULL);
  543. }
  544. SAFE_DELETE(m_tcbItems[nItem]);
  545. m_tcbItems.RemoveAt(nItem);
  546. if (m_tcbItems.GetSize() == 0)
  547. {
  548. m_bManagingViews = false;
  549. }
  550. return TRUE;
  551. }
  552. BOOL CXTExcelTabCtrl::DeleteItem(int nItem)
  553. {
  554. if (!_DeleteItem(nItem))
  555. {
  556. return FALSE;
  557. }
  558. const int cItems = GetItemCount();
  559. ASSERT(cItems >= 0);
  560. if (cItems == 0)
  561. {
  562. m_nCurSel = -1;
  563. }
  564. else
  565. {
  566. if (nItem == m_nCurSel)
  567. {
  568. m_nCurSel = 0;
  569. SetCurSel(0);
  570. }
  571. else if (m_nCurSel > nItem)
  572. {
  573. --m_nCurSel;
  574. }
  575. }
  576. EnableButtons();
  577. InvalidateTabs();
  578. return TRUE;
  579. }
  580. void CXTExcelTabCtrl::ClearAllItems()
  581. {
  582. while (_DeleteItem(0))
  583. {
  584. };
  585. }
  586. BOOL CXTExcelTabCtrl::DeleteAllItems()
  587. {
  588. ClearAllItems();
  589. // Reset the currently selected tab to -1 as we have no tabs in our list now.
  590. m_nCurSel = -1;
  591. EnableButtons();
  592. InvalidateTabs();
  593. return TRUE;
  594. }
  595. int CXTExcelTabCtrl::SetCurSel(int nItem)
  596. {
  597. const int cItems = GetItemCount();
  598. if (nItem < 0 || nItem >= cItems)
  599. return -1;
  600. int iPrevSel = m_nCurSel;
  601. m_nCurSel = nItem;
  602. // test if we need to center on the selected tab
  603. CRect rcItem;
  604. if (GetItemRect(nItem, &rcItem))
  605. {
  606. // test if the tab is off on the left
  607. int iTotalArrowWidth = GetTotalArrowWidth();
  608. rcItem.left -= iTotalArrowWidth;
  609. if (rcItem.left <= 0)
  610. m_nOffset += rcItem.left;
  611. else
  612. {
  613. // test if the tab is off on the right
  614. rcItem.right -= iTotalArrowWidth;
  615. int iTabAreaWidth = GetTotalTabAreaWidth();
  616. if (rcItem.right > iTabAreaWidth)
  617. m_nOffset += (rcItem.right - iTabAreaWidth);
  618. }
  619. }
  620. // hide/show managed controls
  621. ASSERT(iPrevSel >= 0);
  622. if (iPrevSel < cItems && m_tcbItems[iPrevSel]->pWnd->GetSafeHwnd())
  623. {
  624. m_tcbItems[iPrevSel]->pWnd->ShowWindow(SW_HIDE);
  625. }
  626. if (m_tcbItems[m_nCurSel]->pWnd->GetSafeHwnd())
  627. {
  628. m_tcbItems[m_nCurSel]->pWnd->ShowWindow(SW_SHOW);
  629. }
  630. // reset scroll bar position
  631. SyncScrollBar();
  632. EnableButtons();
  633. InvalidateTabs();
  634. return iPrevSel;
  635. }
  636. void CXTExcelTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
  637. {
  638. TCHITTESTINFO tchtinfo;
  639. tchtinfo.pt = point;
  640. // sizing grip ?
  641. if (m_rectGripper.PtInRect(point))
  642. {
  643. ASSERT(m_bTracking == false);
  644. SetTracking(true);
  645. return;
  646. }
  647. // on a button ?
  648. int iButton = ButtonHitTest(point);
  649. if (iButton >= 0)
  650. {
  651. CXTExcelTabCtrlButtonState& b = m_buttons[iButton];
  652. if (b.m_bEnabled)
  653. {
  654. b.m_bPressed = true;
  655. RedrawWindow(b.m_rect);
  656. SetCapture();
  657. }
  658. return;
  659. }
  660. int iTab = HitTest(&tchtinfo);
  661. if ((iTab != -1) && (iTab != m_nCurSel))
  662. {
  663. // warn parent that the selection is about to change
  664. int id = GetDlgCtrlID();
  665. NMHDR hdr;
  666. hdr.hwndFrom = m_hWnd;
  667. hdr.idFrom = id;
  668. hdr.code = TCN_SELCHANGING;
  669. if (GetOwner()->SendMessage(WM_NOTIFY, id, (LPARAM)&hdr) == 0)
  670. {
  671. // parent has given permission for the selection to change
  672. SetCurSel(iTab);
  673. InvalidateTabs();
  674. // notify parent that the selection has changed
  675. hdr.hwndFrom = m_hWnd;
  676. hdr.idFrom = id;
  677. hdr.code = TCN_SELCHANGE;
  678. GetOwner()->SendMessage(WM_NOTIFY, id, (LPARAM)&hdr);
  679. }
  680. }
  681. CWnd::OnLButtonDown(nFlags, point);
  682. }
  683. void CXTExcelTabCtrl::OnLButtonUp(UINT nFlags, CPoint point)
  684. {
  685. if (m_bTracking)
  686. {
  687. SetTracking(false);
  688. }
  689. // on a button ?
  690. int i;
  691. for (i = 0; i < BUTTON_COUNT; ++i)
  692. {
  693. CXTExcelTabCtrlButtonState& b = m_buttons[i];
  694. if (b.m_bEnabled & b.m_bPressed)
  695. {
  696. PostMessage(WM_COMMAND, b.m_iCommand, NULL);
  697. b.m_bPressed = false;
  698. RedrawWindow(b.m_rect);
  699. ReleaseCapture();
  700. return;
  701. }
  702. }
  703. CWnd::OnLButtonUp(nFlags, point);
  704. }
  705. void CXTExcelTabCtrl::OnPaint()
  706. {
  707. CPaintDC dc(this);
  708. if (m_dwStyle & FTS_XT_HSCROLL)
  709. {
  710. dc.ExcludeClipRect(&m_rectSB_H);
  711. }
  712. CXTPBufferDC memDC(dc, m_rectTabs);
  713. OnDraw(&memDC);
  714. }
  715. LRESULT CXTExcelTabCtrl::OnPrintClient(WPARAM wParam, LPARAM /*lParam*/)
  716. {
  717. CDC* pDC = CDC::FromHandle((HDC)wParam);
  718. if (pDC)
  719. {
  720. OnDraw(pDC);
  721. }
  722. return TRUE;
  723. }
  724. void CXTExcelTabCtrl::OnDraw(CDC* pDC)
  725. {
  726. CRect rectPaint(m_rectTabs);  // this the only part we care about
  727. pDC->FillSolidRect(rectPaint, GetXtremeColor(COLOR_3DFACE));
  728. // Exclude the arrow buttons from being repainted.
  729. const int iTotalArrowWidth = GetTotalArrowWidth();
  730. CRect rcArrows(rectPaint);
  731. rcArrows.top += 1;
  732. rcArrows.right = rcArrows.left + iTotalArrowWidth-1;
  733. pDC->FillSolidRect(0, (m_dwStyle & FTS_XT_BOTTOM) ? rectPaint.top : rectPaint.bottom - 1,
  734. rectPaint.Width(), 1, GetTheme()->m_clr3DShadow);
  735. int i;
  736. for (i = 0; i < BUTTON_COUNT; ++i)
  737. {
  738. if (CRect().IntersectRect(rectPaint, m_buttons[i].m_rect))
  739. {
  740. GetTheme()->DrawButton(pDC, this, m_buttons[i]);
  741. }
  742. }
  743. if (rectPaint.right >= rcArrows.right)
  744. {
  745. const int nTotalTabWidth = GetTotalTabWidth();
  746. // Draw the tabs to an offscreen device context, this is done
  747. // so that we can "scroll" the entire tab group left or right whenever
  748. // any of the arrow buttons are pressed.
  749. CDC tabDC;
  750. tabDC.CreateCompatibleDC(pDC);
  751. CBitmap bitmap;
  752. bitmap.CreateCompatibleBitmap(pDC, nTotalTabWidth, m_cy);
  753. CBitmap* pOldBitmap = tabDC.SelectObject(&bitmap);
  754. // Fill the background color.
  755. CRect rcTabs(0, 0, nTotalTabWidth, m_cy);
  756. tabDC.FillSolidRect(rcTabs, GetXtremeColor(COLOR_3DFACE));
  757. // Define xy coordinates to draw each tab.
  758. const int iOverlap = GetOverlap();
  759. int x = 0;
  760. int iSelX = 0;
  761. int y = 0;
  762. // Draw all of the non-selected tabs first...
  763. const int cItems = GetItemCount();
  764. for (i = 0; i < cItems; i++)
  765. {
  766. if (i != m_nCurSel)
  767. {
  768. const int cx = GetTheme()->DrawTab(&tabDC, this,
  769. CPoint(x, y), false, m_tcbItems[i]);
  770. x += cx;
  771. }
  772. else
  773. {
  774. iSelX = x;
  775. x += GetTabWidth(i);
  776. }
  777. x -= iOverlap;
  778. }
  779. // then draw the selected tab. Make sure that m_TabList is not empty.
  780. if (m_nCurSel >= 0 && cItems > 0)
  781. {
  782. GetTheme()->DrawTab(&tabDC, this,
  783. CPoint(iSelX, y), true, m_tcbItems[m_nCurSel]);
  784. }
  785. // blit the bitmap onto the pDC->
  786. pDC->BitBlt(iTotalArrowWidth, rectPaint.top, GetTotalTabAreaWidth(),
  787. m_cy, &tabDC, m_nOffset, 0, SRCCOPY);
  788. // cleanup.
  789. tabDC.SelectObject(pOldBitmap);
  790. }
  791. if (m_dwStyle & FTS_XT_HSCROLL)
  792. {
  793. DrawGripper(pDC, m_rectGripper);
  794. }
  795. }
  796. void CXTExcelTabCtrl::DrawGripper(CDC* pDC, CRect rect) const
  797. {
  798. pDC->Draw3dRect(rect, GetXtremeColor(COLOR_3DHILIGHT), GetXtremeColor(COLOR_3DSHADOW));
  799. rect.InflateRect(-CX_BORDER, -CY_BORDER);
  800. // fill the middle
  801. pDC->FillSolidRect(rect, GetXtremeColor(COLOR_3DFACE));
  802. }
  803. BOOL CXTExcelTabCtrl::PreTranslateMessage(MSG* pMsg)
  804. {
  805. ASSERT_VALID(this);
  806. if (pMsg->message == WM_KEYDOWN)
  807. {
  808. if (pMsg->wParam == VK_ESCAPE)
  809. {
  810. if (m_bTracking)
  811. {
  812. SetTracking(false);
  813. }
  814. return TRUE; // eat ESC keyboard press...
  815. }
  816. }
  817. if (::IsWindow(m_ToolTip.m_hWnd))
  818. {
  819. if (pMsg->message == WM_MOUSEMOVE && pMsg->hwnd == m_hWnd)
  820. {
  821. CPoint Point(LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
  822. TCHITTESTINFO htInfo;
  823. htInfo.pt = Point;
  824. int iTab = HitTest(&htInfo);
  825. if (iTab >= 0)
  826. {
  827. CString strOldTipText;
  828. CString strNewTipText = m_tcbItems[iTab]->szToolTipLabel;
  829. m_ToolTip.GetText(strOldTipText, this);
  830. // If the tip text differs, update the tooltip control.
  831. if (strNewTipText != strOldTipText)
  832. {
  833. m_ToolTip.DelTool(this);
  834. m_ToolTip.AddTool(this, strNewTipText);
  835. }
  836. // Pass on to tooltip.
  837. m_ToolTip.RelayEvent(pMsg);
  838. }
  839. else
  840. {
  841. m_ToolTip.SendMessage(TTM_POP, 0, 0L);
  842. }
  843. }
  844. else
  845. {
  846. m_ToolTip.SendMessage(TTM_POP, 0, 0L);
  847. }
  848. }
  849. return CWnd::PreTranslateMessage(pMsg);
  850. }
  851. void CXTExcelTabCtrl::SetTipText(int nItem, LPCTSTR lpszTabTip)
  852. {
  853. const int cItems = GetItemCount();
  854. if (nItem < 0 || nItem >= cItems)
  855. {
  856. ASSERT(0);
  857. return;
  858. }
  859. m_tcbItems[nItem]->szToolTipLabel = lpszTabTip;
  860. }
  861. CString CXTExcelTabCtrl::GetTipText(int nItem)
  862. {
  863. const int cItems = GetItemCount();
  864. if (nItem < 0 || nItem >= cItems)
  865. {
  866. ASSERT(0);
  867. return _T("");
  868. }
  869. return m_tcbItems[nItem]->szToolTipLabel;
  870. }
  871. void CXTExcelTabCtrl::Home()
  872. {
  873. OnHomeArrow();
  874. }
  875. void CXTExcelTabCtrl::OnMouseMove(UINT nFlags, CPoint point)
  876. {
  877. if (m_bTracking)
  878. {
  879. // resize
  880. SetGripperPosition(point.x + m_xTrackingDelta, false);
  881. }
  882. else
  883. {
  884. if (ButtonHitTest(point) != m_iBtnHilight)
  885. {
  886. SetTimer(1, 10, NULL);
  887. OnTimer(1);
  888. }
  889. }
  890. CWnd::OnMouseMove(nFlags, point);
  891. }
  892. BOOL CXTExcelTabCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  893. {
  894. if (m_bTracking && GetCapture() != this)
  895. {
  896. m_bTracking = FALSE;
  897. }
  898. POINT pt;
  899. GetCursorPos(&pt);
  900. ScreenToClient(&pt);
  901. if (m_bTracking || m_rectGripper.PtInRect(pt))
  902. {
  903. ::SetCursor(XTAuxData().hcurHSplitBar);
  904. return TRUE;
  905. }
  906. return CWnd::OnSetCursor(pWnd, nHitTest, message);
  907. }
  908. void CXTExcelTabCtrl::SetTracking(bool bTracking)
  909. {
  910. if (m_bTracking == bTracking)
  911. {
  912. return;
  913. }
  914. m_bTracking = bTracking;
  915. if (bTracking)
  916. {
  917. SetCapture();
  918. POINT pt;
  919. GetCursorPos(&pt);
  920. ScreenToClient(&pt);
  921. m_xTrackingDelta = GetGripperPosition() - pt.x;
  922. m_pWndLastFocus = SetFocus();
  923. }
  924. else
  925. {
  926. ReleaseCapture();
  927. if (::IsWindow(m_pWndLastFocus->GetSafeHwnd()))
  928. {
  929. m_pWndLastFocus->SetFocus();
  930. }
  931. else
  932. {
  933. m_pWndLastFocus = NULL;
  934. }
  935. }
  936. }
  937. void CXTExcelTabCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
  938. {
  939. // on a button ?
  940. int iButton = ButtonHitTest(point);
  941. if (iButton >= 0)
  942. {
  943. CXTExcelTabCtrlButtonState& b = m_buttons[iButton];
  944. if (b.m_bEnabled)
  945. {
  946. SetCapture();
  947. b.m_bPressed = true;
  948. RedrawWindow(b.m_rect);
  949. }
  950. return;
  951. }
  952. CWnd::OnLButtonDblClk(nFlags, point);
  953. }
  954. void CXTExcelTabCtrl::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /*pScrollBar*/)
  955. {
  956. CWnd *pWndControl = m_tcbItems[m_nCurSel]->pWnd;
  957. if (pWndControl->GetSafeHwnd())
  958. {
  959. if (nSBCode == SB_THUMBPOSITION || nSBCode == SB_THUMBTRACK)
  960. {
  961. int dx = nPos - pWndControl->GetScrollPos(SB_HORZ);
  962. if (dx)
  963. {
  964. pWndControl->SendMessage(LVM_SCROLL, dx, 0);
  965. }
  966. }
  967. // pass message to control's scroll bar
  968. _AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
  969. pWndControl->SendMessage(
  970. pThreadState->m_lastSentMsg.message,
  971. pThreadState->m_lastSentMsg.wParam,
  972. (LPARAM)pWndControl->GetScrollBarCtrl(SB_HORZ)->GetSafeHwnd());
  973. // reflect changes in our scroll bar
  974. SyncScrollBar();
  975. }
  976. }
  977. void CXTExcelTabCtrl::SyncScrollBar()
  978. {
  979. if (!m_wndHScrollBar.m_hWnd)
  980. {
  981. return;
  982. }
  983. CWnd *pWndControl = NULL;
  984. if (m_nCurSel >= 0)
  985. {
  986. pWndControl = m_tcbItems[m_nCurSel]->pWnd;
  987. }
  988. if (pWndControl && pWndControl->GetSafeHwnd())
  989. {
  990. pWndControl->ShowScrollBar(SB_HORZ, FALSE);
  991. pWndControl->ModifyStyle(WS_HSCROLL, 0, SWP_DRAWFRAME);
  992. SCROLLINFO si;
  993. ZeroMemory(&si, sizeof(si));
  994. si.cbSize = sizeof(si);
  995. si.fMask = SIF_ALL;
  996. if (!pWndControl->GetScrollInfo (SB_HORZ, &si) ||
  997. si.nPage == 0 ||
  998. si.nMin + (int) si.nPage >= si.nMax)
  999. {
  1000. m_wndHScrollBar.EnableWindow(FALSE);
  1001. }
  1002. else
  1003. {
  1004. m_wndHScrollBar.EnableWindow(TRUE);
  1005. m_wndHScrollBar.SetScrollInfo(&si);
  1006. }
  1007. }
  1008. else
  1009. {
  1010. m_wndHScrollBar.EnableWindow(FALSE);
  1011. }
  1012. }
  1013. BOOL CXTExcelTabCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  1014. {
  1015. NMHDR* pNMHDR = (NMHDR*)lParam;
  1016. ASSERT (pNMHDR != NULL);
  1017. BOOL bRetVal = CWnd::OnNotify(wParam, lParam, pResult);
  1018. if (pNMHDR && pNMHDR->code == HDN_ITEMCHANGED)
  1019. {
  1020. SyncScrollBar();
  1021. }
  1022. return bRetVal;
  1023. }
  1024. void CXTExcelTabCtrl::RecalcLayout()
  1025. {
  1026. m_rectViews.left = m_rectTabs.left = 0;
  1027. m_rectViews.right = m_rectTabs.right = m_nClientWidth;
  1028. if (m_dwStyle & FTS_XT_BOTTOM)
  1029. {
  1030. m_rectTabs.top = m_nClientHeight - m_cy;
  1031. m_rectViews.top = 0;
  1032. }
  1033. else
  1034. {
  1035. m_rectTabs.top = 0;
  1036. m_rectViews.top = m_cy;
  1037. }
  1038. m_rectTabs.bottom = m_rectTabs.top + m_cy;
  1039. m_rectViews.bottom = m_rectViews.top + m_nClientHeight - m_cy;
  1040. int nIndex;
  1041. // update managed view positions
  1042. if (m_bManagingViews)
  1043. {
  1044. const int cItems = GetItemCount();
  1045. for (nIndex = 0; nIndex < cItems; ++nIndex)
  1046. {
  1047. ASSERT(m_tcbItems[nIndex]->pWnd->GetSafeHwnd());
  1048. m_tcbItems[nIndex]->pWnd->SetWindowPos(NULL,
  1049. m_rectViews.left, m_rectViews.top,
  1050. m_rectViews.Width(), m_rectViews.Height(),
  1051. SWP_NOZORDER | SWP_NOREDRAW);
  1052. }
  1053. }
  1054. // update arrow buttons if we have them
  1055. if (m_dwStyle & FTS_XT_HASARROWS)
  1056. {
  1057. CRect btnRects[] =
  1058. {
  1059. CRect(0, m_rectTabs.top + 1, m_cx, m_rectTabs.bottom),
  1060. CRect(m_cx, m_rectTabs.top + 1, m_cx * 2, m_rectTabs.bottom),
  1061. CRect(m_cx * 2, m_rectTabs.top + 1, m_cx * 3, m_rectTabs.bottom),
  1062. CRect(m_cx * 3, m_rectTabs.top + 1, m_cx * 4, m_rectTabs.bottom)
  1063. };
  1064. const int cButtons = (m_dwStyle & FTS_XT_HASHOMEEND) ? 4 : 2;
  1065. for (nIndex = 0; nIndex < cButtons; ++nIndex)
  1066. {
  1067. m_buttons[nIndex].m_rect = btnRects[nIndex];
  1068. }
  1069. }
  1070. EnableButtons();
  1071. }
  1072. LPCTSTR CXTExcelTabCtrl::GetItemText(int nIndex) const
  1073. {
  1074. if (nIndex < 0 || nIndex >= GetItemCount())
  1075. {
  1076. return NULL;
  1077. }
  1078. return m_tcbItems[nIndex]->szTabLabel;
  1079. }
  1080. bool CXTExcelTabCtrl::SetItemText(int nIndex, LPCTSTR pszText)
  1081. {
  1082. if (nIndex < 0 || nIndex >= GetItemCount())
  1083. {
  1084. return false;
  1085. }
  1086. m_tcbItems[nIndex]->szTabLabel = pszText;
  1087. RecalcLayout();
  1088. InvalidateTabs();
  1089. return true;
  1090. }
  1091. CWnd *CXTExcelTabCtrl::GetItemWindow(int nIndex) const
  1092. {
  1093. if (nIndex < 0 || nIndex >= GetItemCount())
  1094. {
  1095. return NULL;
  1096. }
  1097. return m_tcbItems[nIndex]->pWnd;
  1098. }
  1099. int CXTExcelTabCtrl::GetOverlap() const
  1100. {
  1101. return ((m_cy / 2) + 2);
  1102. }
  1103. void CXTExcelTabCtrl::UpdateDefaultColors()
  1104. {
  1105. GetTheme()->RefreshMetrics();
  1106. }
  1107. void CXTExcelTabCtrl::SetTabShadowColor(COLORREF crShadow)
  1108. {
  1109. GetTheme()->m_clr3DShadow.SetCustomValue(crShadow);
  1110. }
  1111. COLORREF CXTExcelTabCtrl::GetTabShadowColor() const
  1112. {
  1113. return GetTheme()->m_clr3DShadow;
  1114. }
  1115. void CXTExcelTabCtrl::SetTabHilightColor(COLORREF crHilight)
  1116. {
  1117. GetTheme()->m_clr3DHilight.SetCustomValue(crHilight);
  1118. }
  1119. COLORREF CXTExcelTabCtrl::GetTabHilightColor() const
  1120. {
  1121. return GetTheme()->m_clr3DHilight;
  1122. }
  1123. void CXTExcelTabCtrl::SetTabBackColor(COLORREF crBack)
  1124. {
  1125. GetTheme()->m_clr3DFace.SetCustomValue(crBack);
  1126. }
  1127. COLORREF CXTExcelTabCtrl::GetTabBackColor() const
  1128. {
  1129. return GetTheme()->m_clr3DFace;
  1130. }
  1131. void CXTExcelTabCtrl::SetTabTextColor(COLORREF crText)
  1132. {
  1133. GetTheme()->m_clrBtnText.SetCustomValue(crText);
  1134. }
  1135. COLORREF CXTExcelTabCtrl::GetTabTextColor() const
  1136. {
  1137. return GetTheme()->m_clrBtnText;
  1138. }
  1139. void CXTExcelTabCtrl::SetSelTabBackColor(COLORREF crBack)
  1140. {
  1141. GetTheme()->m_clrWindow.SetCustomValue(crBack);
  1142. }
  1143. COLORREF CXTExcelTabCtrl::GetSelTabBackColor() const
  1144. {
  1145. return GetTheme()->m_clrWindow;
  1146. }
  1147. void CXTExcelTabCtrl::SetSelTabTextColor(COLORREF crText)
  1148. {
  1149. GetTheme()->m_clrWindowText.SetCustomValue(crText);
  1150. }
  1151. COLORREF CXTExcelTabCtrl::GetSelTabTextColor() const
  1152. {
  1153. return GetTheme()->m_clrWindowText;
  1154. }
  1155. CScrollBar* CXTExcelTabCtrl::GetScrollBarCtrl(int nBar) const
  1156. {
  1157. if (nBar == SB_HORZ && ::IsWindow(m_wndHScrollBar.m_hWnd))
  1158. {
  1159. return (CScrollBar*)&m_wndHScrollBar;
  1160. }
  1161. return CWnd::GetScrollBarCtrl(nBar);
  1162. }
  1163. CRect CXTExcelTabCtrl::GetTotalButtonRect() const
  1164. {
  1165. CRect rect;
  1166. rect.CopyRect(&m_buttons[0].m_rect);
  1167. int iWidth = 0;
  1168. for (int i = 0; i < BUTTON_COUNT; ++i)
  1169. {
  1170. iWidth += m_buttons[i].m_rect.Width();
  1171. }
  1172. rect.right = rect.left + iWidth;
  1173. return rect;
  1174. }
  1175. void CXTExcelTabCtrl::OnTimer(UINT_PTR nIDEvent)
  1176. {
  1177. if (nIDEvent == 1)
  1178. {
  1179. CRect rc;
  1180. GetWindowRect(rc);
  1181. CPoint point;
  1182. GetCursorPos(&point);
  1183. ScreenToClient(&point);
  1184. int iBtnHilight = ButtonHitTest(point);
  1185. if (iBtnHilight == -1)
  1186. {
  1187. KillTimer(1);
  1188. if (m_bPainted == TRUE)
  1189. {
  1190. CRect rect = GetTotalButtonRect();
  1191. InvalidateRect(&rect);
  1192. }
  1193. m_iBtnHilight = iBtnHilight;
  1194. m_bPainted = FALSE;
  1195. }
  1196. // On mouse over, show raised button.
  1197. else if (!m_bPainted || (iBtnHilight != m_iBtnHilight))
  1198. {
  1199. CRect rect = GetTotalButtonRect();
  1200. InvalidateRect(&rect);
  1201. m_iBtnHilight = iBtnHilight;
  1202. m_bPainted = TRUE;
  1203. }
  1204. }
  1205. else
  1206. {
  1207. CWnd::OnTimer(nIDEvent);
  1208. }
  1209. }
  1210. void CXTExcelTabCtrl::SetTabBackColor(int nIndex, COLORREF crBack)
  1211. {
  1212. if (nIndex >= 0 || nIndex < GetItemCount())
  1213. {
  1214. m_tcbItems[nIndex]->crTabBack = crBack;
  1215. CRect rcItem;
  1216. GetItemRect(nIndex, &rcItem);
  1217. InvalidateRect(rcItem);
  1218. }
  1219. }
  1220. void CXTExcelTabCtrl::SetTabTextColor(int nIndex, COLORREF crText)
  1221. {
  1222. if (nIndex >= 0 || nIndex < GetItemCount())
  1223. {
  1224. m_tcbItems[nIndex]->crTabText = crText;
  1225. CRect rcItem;
  1226. GetItemRect(nIndex, &rcItem);
  1227. InvalidateRect(rcItem);
  1228. }
  1229. }
  1230. void CXTExcelTabCtrl::SetSelTabBackColor(int nIndex, COLORREF crSelBack)
  1231. {
  1232. if (nIndex >= 0 || nIndex < GetItemCount())
  1233. {
  1234. m_tcbItems[nIndex]->crTabSelBack = crSelBack;
  1235. CRect rcItem;
  1236. GetItemRect(nIndex, &rcItem);
  1237. InvalidateRect(rcItem);
  1238. }
  1239. }
  1240. void CXTExcelTabCtrl::SetSelTabTextColor(int nIndex, COLORREF crSelText)
  1241. {
  1242. if (nIndex >= 0 || nIndex < GetItemCount())
  1243. {
  1244. m_tcbItems[nIndex]->crTabSelText = crSelText;
  1245. CRect rcItem;
  1246. GetItemRect(nIndex, &rcItem);
  1247. InvalidateRect(rcItem);
  1248. }
  1249. }
  1250. COLORREF CXTExcelTabCtrl::GetTabBackColor(int nIndex) const
  1251. {
  1252. return GetTheme()->GetTabBackColor(m_tcbItems[nIndex]);
  1253. }
  1254. COLORREF CXTExcelTabCtrl::GetTabTextColor(int nIndex) const
  1255. {
  1256. return GetTheme()->GetTabTextColor(m_tcbItems[nIndex]);
  1257. }
  1258. COLORREF CXTExcelTabCtrl::GetSelTabBackColor(int nIndex) const
  1259. {
  1260. return GetTheme()->GetSelTabBackColor(m_tcbItems[nIndex]);
  1261. }
  1262. COLORREF CXTExcelTabCtrl::GetSelTabTextColor(int nIndex) const
  1263. {
  1264. return GetTheme()->GetSelTabTextColor(m_tcbItems[nIndex]);
  1265. }
  1266. //{{AFX_CODEJOCK_PRIVATE
  1267. IMPLEMENT_DYNAMIC(CXTFlatTabCtrl, CXTExcelTabCtrl) // deprecated.
  1268. //}}AFX_CODEJOCK_PRIVATE