CoolTabCtrl.cpp
上传用户:yffx2008
上传日期:2014-10-12
资源大小:12414k
文件大小:13k
源码类别:

交通/航空行业

开发平台:

Visual C++

  1. ////////////////////////////////////////////////////////////////
  2. // CoolTabCtrl.cpp : implementation file                      //
  3. //   //
  4. // Copyright 2001 WangJun   //
  5. // All Rights Reserved.   //
  6. //   //
  7. // Email: wangjun98@sohu.com   //
  8. // URL:   www.vckbase.com   //
  9. //   //
  10. // 1.0     2001/9/30   First release version.   //
  11. //   //
  12. ////////////////////////////////////////////////////////////////
  13. #include "stdafx.h"
  14. #include "CoolTabCtrl.h"
  15. #ifdef _DEBUG
  16. #define new DEBUG_NEW
  17. #undef THIS_FILE
  18. static char THIS_FILE[] = __FILE__;
  19. #endif
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CCoolTabCtrl
  22. IMPLEMENT_DYNCREATE(CCoolTabCtrl, CWnd)
  23. #define ITEMBUTTON_HEIGHT 23
  24. static CPen _penW(PS_SOLID,1 ,RGB(255,255,255));
  25. static CPen _penB(PS_SOLID,1 ,RGB(0,0,0));
  26. static CPen _pen3DFace(PS_SOLID,1,GetSysColor(COLOR_3DFACE));
  27. static CPen _pen3DLight(PS_SOLID,1,GetSysColor(COLOR_3DLIGHT));
  28. static CPen _pen3DShadow(PS_SOLID,1,GetSysColor(COLOR_3DSHADOW));
  29. static CPen _pen3DDKShadow(PS_SOLID,1,GetSysColor(COLOR_3DDKSHADOW));
  30. CCoolTabCtrl::CCoolTabCtrl()
  31. {
  32. m_nStyle = TCS_DOWN;
  33. m_nActivePage = -1;
  34. m_nBorder = 1;
  35. m_bEraseBkgnd = TRUE;
  36. }
  37. CCoolTabCtrl::~CCoolTabCtrl()
  38. {
  39. POSITION pos;
  40. CPageItem* pItem;
  41. for(pos=m_PageList.GetHeadPosition();pos!=NULL;)
  42. {
  43. pItem=(CPageItem*)m_PageList.GetNext(pos);
  44. if(pItem)
  45. {
  46. if(pItem->m_nStyle == 1 &&pItem->m_pWnd) ///Dialog
  47. delete pItem->m_pWnd;
  48. delete pItem;
  49. pItem=NULL;
  50. }
  51. }
  52. m_PageList.RemoveAll();
  53. }
  54. BEGIN_MESSAGE_MAP(CCoolTabCtrl, CWnd)
  55. //{{AFX_MSG_MAP(CCoolTabCtrl)
  56. ON_WM_PAINT()
  57. ON_WM_ERASEBKGND()
  58. ON_WM_LBUTTONDOWN()
  59. ON_WM_SIZING()
  60. ON_WM_SIZE()
  61. ON_WM_TIMER()
  62. //}}AFX_MSG_MAP
  63. END_MESSAGE_MAP()
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CCoolTabCtrl message handlers
  66. BOOL CCoolTabCtrl::Create(UINT wStyle, const CRect &rect, CWnd *pParentWnd, UINT nID)
  67. {
  68. m_nStyle = wStyle & TCS_MASK;
  69. if(m_nStyle == 0)
  70. m_nStyle = TCS_UP;
  71. if (CWnd::Create(AfxRegisterWndClass(CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW, AfxGetApp()->LoadStandardCursor(IDC_ARROW), (HBRUSH)GetStockObject(LTGRAY_BRUSH), NULL),
  72. NULL,
  73. wStyle&~TCS_MASK | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  74. rect, 
  75. pParentWnd, 
  76. nID))
  77. {
  78. LOGFONT logFont;
  79. ZeroMemory((void*)&logFont,sizeof(logFont));
  80. strcpy(logFont.lfFaceName,"宋体");
  81. logFont.lfHeight = -12;
  82. logFont.lfWeight = 400;
  83. logFont.lfCharSet = GB2312_CHARSET;
  84. logFont.lfOutPrecision = 3;
  85. logFont.lfClipPrecision = 2; 
  86. logFont.lfQuality = 1;
  87. logFont.lfPitchAndFamily = 2;
  88. m_font.CreateFontIndirect(&logFont);
  89. SetFont(&m_font);
  90. return TRUE;
  91. }
  92. return FALSE;
  93. }
  94. BOOL CCoolTabCtrl::OnEraseBkgnd(CDC* pDC) 
  95. {
  96. if(m_bEraseBkgnd)
  97. {
  98. CRect rect;
  99. GetWindowRect(&rect);
  100. ScreenToClient(&rect);
  101. CBrush brush(GetSysColor(COLOR_3DFACE));
  102. pDC->FillRect(rect,&brush);
  103. }
  104. return TRUE;
  105. }
  106. void CCoolTabCtrl::OnPaint() 
  107. {
  108. CPaintDC dc(this);
  109. CPen *pOldPen = dc.GetCurrentPen();
  110. CFont *pOldFont = dc.SelectObject(&m_font);
  111. int nOldBkMode = dc.SetBkMode(TRANSPARENT);
  112. CPageItem *pItem;
  113. POSITION pos;
  114. int nItemIndex = 0;
  115. DrawFrame(&dc);
  116. for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
  117. {
  118. pItem=(CPageItem*)m_PageList.GetNext(pos);
  119. if(pItem)
  120. {
  121. pItem->Draw(&dc,m_nStyle,(m_nActivePage==nItemIndex)?TRUE:FALSE);
  122. }
  123. }
  124. dc.SetBkMode(nOldBkMode);
  125. dc.SelectObject(pOldFont);
  126. dc.SelectObject(pOldPen);
  127. }
  128. void CCoolTabCtrl::AddPage(CWnd *pWnd, LPCTSTR sText, UINT IconID)
  129. {
  130. ASSERT(IsWindow(pWnd->m_hWnd));
  131. CPageItem *pItem;
  132. pItem = new CPageItem();
  133. pItem->m_pWnd = pWnd;
  134. pItem->m_nStyle = 0;//Window
  135. pItem->m_sText = sText;
  136. if(IconID)
  137. pItem->m_hIcon = AfxGetApp()->LoadIcon(IconID);
  138. else
  139. pItem->m_hIcon = NULL;
  140. if(pWnd)
  141. {
  142. CRect rect;
  143. GetClientRect(rect);
  144. pWnd->MoveWindow(rect);
  145. }
  146. m_PageList.AddTail(pItem);
  147. }
  148. BOOL CCoolTabCtrl::AddPage(CRuntimeClass* pClass,UINT nIDTemplate, LPCTSTR sText, UINT IconID)
  149. {
  150. CDialog *pDlg = (CDialog*)pClass->CreateObject();
  151. if(pDlg != NULL)
  152. if(pDlg->Create(nIDTemplate,this))
  153. {
  154. CPageItem *pItem;
  155. pItem = new CPageItem();
  156. pItem->m_pWnd = (CWnd*)pDlg;
  157. pItem->m_nStyle = 1;///Dialog
  158. pItem->m_sText = sText;
  159. if(IconID)
  160. pItem->m_hIcon = AfxGetApp()->LoadIcon(IconID);
  161. else
  162. pItem->m_hIcon = NULL;
  163. CRect rect;
  164. GetClientRect(rect);
  165. pDlg->MoveWindow(rect);
  166. m_PageList.AddTail(pItem);
  167. return TRUE;
  168. }
  169. return FALSE;
  170. }
  171. void CCoolTabCtrl::GetClientRect(LPRECT lpRect)
  172. {
  173. CWnd::GetClientRect(lpRect);
  174. if(m_nStyle&TCS_DOWN)
  175. {
  176. lpRect->left += 2;
  177. lpRect->right -= 2;
  178. lpRect->top += 2;
  179. lpRect->bottom -= ITEMBUTTON_HEIGHT;
  180. }
  181. else if(m_nStyle&TCS_UP)
  182. {
  183. lpRect->left += 2;
  184. lpRect->right -= 2;
  185. lpRect->top += ITEMBUTTON_HEIGHT;
  186. lpRect->bottom -= 2;
  187. }
  188. }
  189. ///////取得需要占用的宽度/////
  190. UINT CCoolTabCtrl::CPageItem::GetAreaWidth(CDC *pDC)
  191. {
  192. UINT width = pDC->GetTextExtent(m_sText).cx;
  193. if(m_hIcon)
  194. width += 18;
  195. return width + 9;
  196. }
  197. void CCoolTabCtrl::CPageItem::Draw(CDC *pDC, UINT nStyle, BOOL bActive)
  198. {
  199. CRect rect = m_rect;
  200. if(nStyle&TCS_DOWN)
  201. {
  202. if(bActive)
  203. {
  204. rect.top -= 2;
  205. CBrush brush(GetSysColor(COLOR_3DFACE));
  206. pDC->FillRect(rect,&brush);
  207. rect.top += 1;
  208. }
  209. else
  210. rect.bottom -= 1;
  211. CBrush brush(GetSysColor(COLOR_3DFACE));
  212. pDC->FillRect(m_rect,&brush);
  213. pDC->SelectObject(&_penW);
  214. pDC->MoveTo(rect.left,rect.top);
  215. pDC->LineTo(rect.left,rect.bottom-1);
  216. pDC->SelectObject(&_pen3DShadow);
  217. pDC->MoveTo(rect.left+1,rect.bottom-2);
  218. pDC->LineTo(rect.left+1,rect.bottom-1);
  219. pDC->LineTo(rect.right-1,rect.bottom-1);
  220. pDC->MoveTo(rect.right-2,rect.bottom-2);
  221. pDC->LineTo(rect.right-1,rect.bottom-2);
  222. pDC->LineTo(rect.right-1,rect.top-1);
  223. pDC->SelectObject(&_penB);
  224. pDC->MoveTo(rect.left+2,rect.bottom);
  225. pDC->LineTo(rect.right-2,rect.bottom);
  226. pDC->LineTo(rect.right,rect.bottom-2);
  227. pDC->MoveTo(rect.right,rect.top);
  228. pDC->LineTo(rect.right,rect.bottom-1);
  229. rect.top -= 1;
  230. }//end of TCS_DOWN
  231. else if(nStyle&TCS_UP)
  232. {
  233. CBrush brush(GetSysColor(COLOR_3DFACE));
  234. if(bActive)
  235. {
  236. rect.bottom += 1;
  237. pDC->FillRect(rect,&brush);
  238. rect.bottom -= 1;
  239. }
  240. else
  241. {
  242. rect.top += 2;
  243. pDC->FillRect(rect,&brush);
  244. }
  245. pDC->SelectObject(&_penW);
  246. pDC->MoveTo(rect.left,rect.bottom);
  247. pDC->LineTo(rect.left,rect.top + 2);
  248. pDC->LineTo(rect.left + 2,rect.top);
  249. pDC->LineTo(rect.right,rect.top);
  250. pDC->SelectObject(&_pen3DShadow);
  251. pDC->MoveTo(rect.right - 1,rect.top);
  252. pDC->LineTo(rect.right - 1,rect.bottom);
  253. pDC->SelectObject(&_penB);
  254. pDC->MoveTo(rect.right,rect.top + 1);
  255. pDC->LineTo(rect.right,rect.bottom);
  256. }
  257. ///////////调整位置//////////
  258. rect.left += 5;
  259. rect.right -= 2;
  260. ///////////显示图标//////////
  261. if(rect.Width() > 16 && m_hIcon != NULL)
  262. {
  263. ::DrawIconEx(pDC->m_hDC,rect.left,rect.top + 3,m_hIcon,16,16,0,NULL,DI_NORMAL);
  264. rect.left += 18;
  265. }
  266. if (!m_sText.IsEmpty())
  267. {
  268. ///////////显示文字//////////
  269. rect.top += 5;
  270. CString sText = m_sText;
  271. int l = sText.GetLength();
  272. int i;
  273. for(i=0;i<10 && pDC->GetTextExtent(sText).cx > rect.Width();i++,l-=2)
  274. sText = sText.Left(l-2);
  275. if(i > 0)
  276. {
  277. sText = sText.Left(l-2);
  278. sText += "...";
  279. }
  280. pDC->DrawText(sText, &rect, DT_LEFT /*| DT_VCENTER */| DT_SINGLELINE);
  281. }
  282. }
  283. ////调整尺寸////
  284. void CCoolTabCtrl::AutoSize()
  285. {
  286. UINT PageCount = m_PageList.GetCount();
  287. if(PageCount < 1) return;
  288. CPageItem *pItem;
  289. POSITION pos;
  290. CRect rect,ClientRect,ItemRect;
  291. GetClientRect(ClientRect);
  292. ClientRect.DeflateRect(m_nBorder+1,m_nBorder+1);
  293. GetWindowRect(rect);
  294. ScreenToClient(rect);
  295. CDC* pDC = GetDC();
  296. CFont *pOldFont = pDC->SelectObject(&m_font);
  297. if(m_nStyle&TCS_DOWN)
  298. {
  299. rect.left += 6;
  300. rect.right -= 6;
  301. rect.bottom -= 1;
  302. rect.top = rect.bottom - ITEMBUTTON_HEIGHT + 1;
  303. }
  304. else if(m_nStyle&TCS_UP)
  305. {
  306. rect.left += 2;
  307. rect.right -= 6;
  308. rect.bottom = rect.top + ITEMBUTTON_HEIGHT;
  309. }
  310. ItemRect = rect;
  311. int AreaWidth = 0,ItemMaxWidth,ItemIndex=0;
  312. ItemMaxWidth = rect.Width()/m_PageList.GetCount();
  313. BOOL bMonoSpace = ((m_nStyle&TCS_MONOSPACE) == TCS_MONOSPACE)?1:0;
  314. ////////设置按钮初始宽度,并得到按钮所需占用的总宽度///////
  315. for(pos=m_PageList.GetHeadPosition();pos!=NULL;ItemIndex++)
  316. {
  317. pItem=(CPageItem*)m_PageList.GetNext(pos);
  318. if(pItem)
  319. {
  320. if(!bMonoSpace)
  321. ItemMaxWidth = pItem->GetAreaWidth(pDC);
  322. AreaWidth += ItemMaxWidth;
  323. ItemRect.right = ItemRect.left+ItemMaxWidth-1;
  324. pItem->m_rect = ItemRect;
  325. ItemRect.left = ItemRect.right + 1;
  326. if(pItem->m_pWnd)
  327. pItem->m_pWnd->MoveWindow(ClientRect);
  328. }
  329. }
  330. ////////当需要的空间大于实际空间时进行调整////
  331. if(AreaWidth > rect.Width() && !bMonoSpace)
  332. {
  333. ItemRect = rect;
  334. int AreaWidth,MaxWidth = rect.Width()/PageCount;
  335. for(pos=m_PageList.GetHeadPosition();pos!=NULL;)
  336. {
  337. pItem=(CPageItem*)m_PageList.GetNext(pos);
  338. if(pItem)
  339. {
  340. AreaWidth = pItem->GetAreaWidth(pDC);
  341. ItemMaxWidth = (ItemMaxWidth < AreaWidth)?MaxWidth:AreaWidth;
  342. ItemRect.right = ItemRect.left+ItemMaxWidth;
  343. pItem->m_rect = ItemRect;
  344. ItemRect.left = ItemRect.right + 1;
  345. }
  346. }
  347. }
  348. pDC->SelectObject(pOldFont);
  349. ReleaseDC(pDC);
  350. }
  351. void CCoolTabCtrl::SetActivePage(int nIndex)
  352. {
  353. if(nIndex == m_nActivePage)
  354. return;
  355. CPageItem *pOldItem,*pItem;
  356. if(m_nActivePage >= 0)
  357. {
  358. pOldItem = (CPageItem*)GetPageItem(m_nActivePage);
  359. if(pOldItem)
  360. {
  361. pOldItem->m_pWnd->ShowWindow(SW_HIDE);
  362. }
  363. }
  364. pItem = (CPageItem*)GetPageItem(nIndex);
  365. if(!pItem) return;
  366. m_nActivePage = nIndex;
  367. if(m_nStyle&TCS_ANIMATE)
  368. SetTimer(100,15,NULL);///为了在95或NT4下也有动画效果,没有使用AnimateWindow函数
  369. else
  370. pItem->m_pWnd->ShowWindow(SW_SHOW);
  371. }
  372. void* CCoolTabCtrl::GetPageItem(UINT nIndex)
  373. {
  374. CPageItem *pItem = NULL;
  375. POSITION pos = m_PageList.FindIndex(nIndex);
  376. if(pos)
  377. pItem = (CPageItem*)m_PageList.GetAt(pos);
  378. return pItem;
  379. }
  380. void CCoolTabCtrl::UpdateWindow()
  381. {
  382.   AutoSize();
  383.   if(m_nActivePage < 0)
  384.   SetActivePage(0);
  385.   else
  386.   SetActivePage(m_nActivePage);
  387.   Invalidate();
  388. }
  389. void CCoolTabCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
  390. {
  391. UINT nItemIndex=0;
  392. POSITION pos;
  393. CPageItem *pItem;
  394. for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
  395. {
  396. pItem=(CPageItem*)m_PageList.GetNext(pos);
  397. if(pItem)
  398. {
  399. if(pItem->m_rect.PtInRect(point))
  400. {
  401. SetActivePage(nItemIndex);
  402. Invalidate();
  403. break;
  404. }
  405. }
  406. }
  407. CWnd::OnLButtonDown(nFlags, point);
  408. }
  409. void CCoolTabCtrl::OnSizing(UINT fwSide, LPRECT pRect) 
  410. {
  411. CWnd::OnSizing(fwSide, pRect);
  412. m_bEraseBkgnd = FALSE;
  413. AutoSize();
  414. }
  415. void CCoolTabCtrl::OnSize(UINT nType, int cx, int cy) 
  416. {
  417. CWnd::OnSize(nType, cx, cy);
  418. m_bEraseBkgnd = TRUE;
  419. AutoSize();
  420. Invalidate();
  421. }
  422. void CCoolTabCtrl::DrawFrame(CDC *pDC)
  423. {
  424. CRect rect;
  425. GetClientRect(&rect);
  426. switch(m_nBorder)
  427. {
  428. case 1:
  429. pDC->Draw3dRect(rect,RGB(0xff,0xff,0xff),RGB(0,0,0));
  430. break;
  431. case 2:
  432. pDC->Draw3dRect(rect,RGB(0xff,0xff,0xff),RGB(0,0,0));
  433. rect.DeflateRect(1, 1);
  434. pDC->Draw3dRect(rect, GetSysColor(COLOR_3DFACE), GetSysColor(COLOR_3DSHADOW));
  435. break;
  436. default:break;
  437. }
  438. }
  439. void CCoolTabCtrl::SetStyle(UINT style)
  440. {
  441. m_nStyle = style;
  442. }
  443. UINT CCoolTabCtrl::GetStyle()
  444. {
  445. return m_nStyle;
  446. }
  447. void CCoolTabCtrl::OnTimer(UINT nIDEvent) 
  448. {
  449. static step,times = 10;
  450. UINT width;
  451. CRect rect;
  452. GetClientRect(&rect);
  453. rect.DeflateRect(m_nBorder+1,m_nBorder+1);
  454. POSITION pos = m_PageList.FindIndex(m_nActivePage);
  455. if(pos)
  456. {
  457. CPageItem *pItem = (CPageItem*)m_PageList.GetAt(pos);
  458. if(pItem)
  459. {
  460. width = rect.Width();
  461. if(times == 10)
  462. {
  463. rect.right = 10;
  464. rect.left = rect.right - width + 1;
  465. step = width/times;
  466. times--;
  467. m_bEraseBkgnd = FALSE;
  468. pItem->m_pWnd->ShowWindow(SW_SHOW);
  469. }
  470. else
  471. {
  472. if(times <= 0)
  473. {
  474. times = 10;
  475. KillTimer(nIDEvent);
  476. m_bEraseBkgnd = TRUE;
  477. }
  478. else
  479. {
  480. rect.right = width - times*step;
  481. rect.left = rect.right - width + 1;
  482. times--;
  483. }
  484. }
  485. pItem->m_pWnd->MoveWindow(rect);
  486. }
  487. }
  488. }
  489. void CCoolTabCtrl::SetStyleAnimate(BOOL bEnable)
  490. {
  491. UINT style = GetStyle();
  492. if(bEnable)
  493. style |= TCS_ANIMATE;
  494. else
  495. style &= ~TCS_ANIMATE;
  496. SetStyle(style);
  497. }
  498. void CCoolTabCtrl::SetStyleDirection(int Direction)
  499. {
  500. UINT style = GetStyle();
  501. switch(Direction)
  502. {
  503. case TCS_DOWN:
  504. style &= ~TCS_UP;
  505. style |= TCS_DOWN;
  506. break;
  507. case TCS_UP:
  508. default:
  509. style &= ~TCS_DOWN;
  510. style |= TCS_UP;
  511. break;
  512. }
  513. SetStyle(style);
  514. UpdateWindow();
  515. }
  516. void CCoolTabCtrl::SetStyleMonoSpace(BOOL bEnable)
  517. {
  518. UINT style = GetStyle();
  519. if(bEnable)
  520. style |= TCS_MONOSPACE;
  521. else
  522. style &= ~TCS_MONOSPACE;
  523. SetStyle(style);
  524. UpdateWindow();
  525. }