RTTabCtrl.cpp
上传用户:qhonly
上传日期:2013-06-10
资源大小:487k
文件大小:12k
源码类别:

界面编程

开发平台:

Visual C++

  1. // RTTabCtrl.cpp : 实现文件
  2. //
  3. #include "stdafx.h"
  4. #include "RTTabCtrl.h"
  5. #include "RTDraw.h"
  6. // CRTTabCtrl
  7. IMPLEMENT_DYNAMIC(CRTTabCtrl, CTabCtrl)
  8. CRTTabCtrl::CRTTabCtrl()
  9. {
  10. m_CurSel = -1;//no sel page
  11. m_IsShowTabItem = TRUE;
  12. }
  13. CRTTabCtrl::~CRTTabCtrl()
  14. {
  15. }
  16. BOOL CRTTabCtrl::m_IsEnableSkin = TRUE;
  17. CBitmap* CRTTabCtrl::m_TabBitmap[5] = {NULL,NULL,NULL,NULL,NULL};
  18. UINT     CRTTabCtrl::m_TabBitmapDrawMode[5] = {0,0,0,0,0};
  19. BEGIN_MESSAGE_MAP(CRTTabCtrl, CTabCtrl)
  20. ON_WM_ERASEBKGND()
  21. ON_WM_PAINT()
  22. ON_WM_SIZE()
  23. END_MESSAGE_MAP()
  24. // CRTTabCtrl 消息处理程序
  25. BOOL CRTTabCtrl::OnEraseBkgnd(CDC* pDC)
  26. {
  27. CRect rt;
  28. CTabCtrl::GetClientRect(&rt);
  29. TCITEM tm;
  30. tm.mask = TCIF_PARAM;
  31. if(GetItem(m_CurSel,&tm) && tm.lParam != NULL)
  32. {
  33. CRect rtArea;
  34. GetClientRect(&rtArea);
  35. pDC->ExcludeClipRect(&rtArea);
  36. }
  37. if(m_TabBitmap[BMP_BACK] == NULL || !m_IsEnableSkin)
  38. {
  39. if(!CTabCtrl::OnEraseBkgnd(pDC))
  40. return FALSE;
  41. }
  42. else
  43. {
  44. CRTDraw::RTDrawBitmap(pDC,&rt,m_TabBitmap[BMP_BACK],m_TabBitmapDrawMode[BMP_BACK]);
  45. }
  46. int ItemCount = GetItemCount();
  47. CRect rtClient;
  48. if(ItemCount <= 0 || !m_IsShowTabItem)
  49. {
  50. rtClient.SetRect(rt.left + 2,rt.top + 2,rt.right - 2,rt.bottom - 2);
  51. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_RECT);
  52. return TRUE;
  53. }
  54. DWORD dwStyle = GetStyle();
  55. if(dwStyle & TCS_BOTTOM || dwStyle & TCS_RIGHT)
  56. {
  57.         CRect rcItem;
  58. GetItemRect(ItemCount - 1,&rcItem);
  59. if(rcItem.right < rt.right)
  60. {
  61. rcItem.left = rcItem.right;
  62. rcItem.right = rt.right - 2;
  63. pDC->DrawEdge(&rcItem,BDR_SUNKENOUTER,BF_TOP);
  64. }
  65. rtClient.SetRect(rt.left + 2,rt.top + 2,rt.right - 2,rcItem.top);
  66. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_TOP);
  67. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_RIGHT);
  68. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_LEFT);
  69. }
  70. else if((dwStyle & TCS_VERTICAL) && (dwStyle & TCS_MULTILINE))
  71. {
  72.         CRect rcItem;
  73. GetItemRect(ItemCount - 1,&rcItem);
  74. if(rcItem.bottom < rt.bottom)
  75. {
  76. rcItem.top = rcItem.bottom;
  77. rcItem.bottom = rt.bottom - 2;
  78. pDC->DrawEdge(&rcItem,BDR_SUNKENOUTER,BF_RIGHT);
  79. }
  80. rtClient.SetRect(rcItem.right,rt.top + 2,rt.right - 2,rt.bottom - 2);
  81. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_TOP);
  82. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_RIGHT);
  83. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_BOTTOM);
  84. }
  85. else
  86. {
  87. CRect rcItem;
  88. GetItemRect(ItemCount - 1,&rcItem);
  89. if(rcItem.right < rt.right)
  90. {
  91. rcItem.left = rcItem.right;
  92. rcItem.right = rt.right - 2;
  93. pDC->DrawEdge(&rcItem,BDR_SUNKENOUTER,BF_BOTTOM);
  94. }
  95. rtClient.SetRect(rt.left + 2,rcItem.bottom,rt.right - 2,rt.bottom - 2);
  96. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_LEFT);
  97. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_RIGHT);
  98. pDC->DrawEdge(&rtClient,BDR_RAISEDINNER,BF_BOTTOM);
  99. }
  100. return TRUE;
  101. }
  102. void CRTTabCtrl::GetClientRect(LPRECT lpRect)
  103. {
  104. CRect rtWnd;
  105. CTabCtrl::GetClientRect(&rtWnd);
  106. int ItemCount = GetItemCount();
  107. if(ItemCount <= 0 || !m_IsShowTabItem)
  108. {
  109. lpRect->left = rtWnd.left + 5;
  110. lpRect->right = rtWnd.right - 5;
  111. lpRect->bottom = rtWnd.bottom - 5;
  112. lpRect->top = rtWnd.top + 5;
  113. }
  114. else
  115. {
  116. DWORD dwStyle = GetStyle();
  117. CRect rtItem;
  118. GetItemRect(0,&rtItem);
  119. if(dwStyle & TCS_BOTTOM || dwStyle & TCS_RIGHT)
  120. {
  121. lpRect->left = rtWnd.left + 5;
  122. lpRect->right = rtWnd.right - 5;
  123. lpRect->bottom = rtWnd.bottom - rtItem.Height() - 4;
  124. lpRect->top = rtWnd.top + 5;
  125. }
  126. else if((dwStyle & TCS_VERTICAL) && (dwStyle & TCS_MULTILINE))
  127. {
  128. lpRect->left = rtWnd.left + rtItem.Width() + 4;
  129. lpRect->right = rtWnd.right - 5;
  130. lpRect->bottom = rtWnd.bottom - 5;
  131. lpRect->top = rtWnd.top + 5;
  132. }
  133. else
  134. {
  135. lpRect->left = rtWnd.left + 5;
  136. lpRect->right = rtWnd.right - 5;
  137. lpRect->bottom = rtWnd.bottom - 5;
  138. lpRect->top = rtWnd.top + rtItem.Height() + 4;
  139. }
  140. }
  141. }
  142. void CRTTabCtrl::OnPaint()
  143. {
  144. CPaintDC dc(this); 
  145. if(m_CurSel != GetCurSel())
  146. {
  147. OnTcnSelchanging(m_CurSel);
  148. OnTcnSelchange();
  149. m_CurSel = GetCurSel();
  150. }
  151. if(!m_IsShowTabItem)return;
  152. int ItemCount = GetItemCount();
  153. if(ItemCount <= 0)return;
  154. CRect rt;
  155. CTabCtrl::GetClientRect(rt);
  156. CRgn rgn;
  157. rgn.CreateRectRgn(2,2,rt.right - 2,rt.bottom - 2);
  158. dc.SelectClipRgn(&rgn);
  159. CRect rcItem;
  160. DWORD dwStyle = GetStyle();
  161. int OldModule = dc.SetBkMode(TRANSPARENT);
  162. CFont *pFont = GetFont();
  163. CFont* pOldFont = dc.SelectObject(pFont);
  164. for(int i = 0; i < ItemCount; i ++)
  165. {
  166. char ItemText[1025] = "";
  167. TCITEM tim;
  168. tim.mask = TCIF_IMAGE | TCIF_STATE | TCIF_TEXT;
  169. tim.pszText = ItemText;
  170. tim.cchTextMax = 1024;
  171. if(!GetItem(i,&tim))continue;
  172. GetItemRect(i,&rcItem);
  173. DWORD ItemState = 0;
  174. if(i == GetCurSel())ItemState = TCIS_BUTTONPRESSED;
  175. if(dwStyle & TCS_BOTTOM || dwStyle & TCS_RIGHT)
  176. {
  177. if(ItemState & TCIS_BUTTONPRESSED)
  178. {
  179. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_BOTTOM);
  180. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_LEFT);
  181. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_RIGHT);
  182. }
  183. else
  184. {
  185. dc.DrawEdge(&rcItem,BDR_SUNKENOUTER,BF_TOP);
  186. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_BOTTOM);
  187. CRect rtTemp;
  188. rtTemp.SetRect(rcItem.left,rcItem.top + 1,rcItem.right,rcItem.bottom);
  189. if(i != GetCurSel() - 1)
  190. {
  191. dc.DrawEdge(&rtTemp,BDR_RAISEDINNER,BF_RIGHT);
  192. }
  193. dc.DrawEdge(&rtTemp,BDR_RAISEDINNER,BF_LEFT);
  194. }
  195. CRect rcText;
  196. TEXTMETRIC Metrics;
  197. dc.GetTextMetrics(&Metrics);
  198. CImageList *ImgList = GetImageList();
  199. if(ImgList != NULL)
  200. {
  201. CRect rtIcon;
  202. rtIcon.top = rcItem.top + 1;
  203. rtIcon.bottom = rcItem.bottom - 1;
  204. rtIcon.left = rcItem.left + 1;
  205. rtIcon.right = rtIcon.left + rtIcon.Height() - 2;
  206. HICON hIcon = ImgList->ExtractIcon(tim.iImage);
  207. if(hIcon != NULL)
  208. {
  209. DrawIconEx(dc.m_hDC,rtIcon.left,rtIcon.top,hIcon, rtIcon.Width(),rtIcon.Height(),0,NULL,DI_NORMAL);
  210. DeleteObject(hIcon);
  211. }
  212. rcText.SetRect(rcItem.left + rcItem.Height(),rcItem.top + (rcItem.Height() - Metrics.tmHeight)/2,rcItem.right,rcItem.bottom);
  213. dc.DrawText(ItemText,(int)strlen(ItemText),&rcText,DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS);
  214. }
  215. else
  216. {
  217. rcText.SetRect(rcItem.left,rcItem.top + (rcItem.Height() - Metrics.tmHeight)/2,rcItem.right,rcItem.bottom);
  218. dc.DrawText(ItemText,(int)strlen(ItemText),&rcText,DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
  219. }
  220. }
  221. else if((dwStyle & TCS_VERTICAL) && (dwStyle & TCS_MULTILINE))
  222. {
  223. if(ItemState & TCIS_BUTTONPRESSED)
  224. {
  225. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_TOP);
  226. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_LEFT);
  227. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_BOTTOM);
  228. }
  229. else
  230. {
  231. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_LEFT);
  232. dc.DrawEdge(&rcItem,BDR_SUNKENOUTER,BF_RIGHT);
  233. CRect rtTemp;
  234. rtTemp.SetRect(rcItem.left + 1,rcItem.top,rcItem.right - 1,rcItem.bottom);
  235. dc.DrawEdge(&rtTemp,BDR_RAISEDINNER,BF_TOP);
  236. if(i != GetCurSel() - 1)
  237. {
  238. dc.DrawEdge(&rtTemp,BDR_RAISEDOUTER,BF_BOTTOM);
  239. }
  240. }
  241. CRect rcText;
  242. CImageList *ImgList = GetImageList();
  243. if(ImgList != NULL)
  244. {
  245. CRect rtIcon;
  246. rtIcon.left = rcItem.left + 1;
  247. rtIcon.right = rcItem.right - 1;
  248. rtIcon.top = rcItem.top + 1;
  249. rtIcon.bottom = rtIcon.top + rcItem.Width() - 2;
  250. HICON hIcon = ImgList->ExtractIcon(tim.iImage);
  251. if(hIcon != NULL)
  252. {
  253. DrawIconEx(dc.m_hDC,rtIcon.left,rtIcon.top,hIcon, rtIcon.Width(),rtIcon.Height(),0,NULL,DI_NORMAL);
  254. DeleteObject(hIcon);
  255. }
  256. rcText.SetRect(rcItem.left,rcItem.top + rcItem.Width(),rcItem.right,rcItem.bottom);
  257. LOGFONT lf ;
  258. pFont->GetLogFont(&lf);
  259. CRTDraw::RTDrawVerticalText(&dc,&rcText,ItemText,(int)strlen(ItemText), DT_LEFT | DT_SINGLELINE,&lf);
  260. }
  261. else
  262. {
  263. rcText.SetRect(rcItem.left,rcItem.top + 4,rcItem.right,rcItem.bottom);
  264. LOGFONT lf ;
  265. pFont->GetLogFont(&lf);
  266. CRTDraw::RTDrawVerticalText(&dc,&rcText,ItemText,(int)strlen(ItemText), DT_LEFT | DT_SINGLELINE,&lf);
  267. }
  268. }
  269. else
  270. {
  271. if(ItemState & TCIS_BUTTONPRESSED)
  272. {
  273. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_TOP);
  274. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_LEFT);
  275. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_RIGHT);
  276. }
  277. else
  278. {
  279. dc.DrawEdge(&rcItem,BDR_SUNKENOUTER,BF_BOTTOM);
  280. dc.DrawEdge(&rcItem,BDR_RAISEDINNER,BF_TOP);
  281. CRect rtTemp;
  282. rtTemp.SetRect(rcItem.left,rcItem.top,rcItem.right,rcItem.bottom - 1);
  283. if(i != GetCurSel() - 1)
  284. {
  285. dc.DrawEdge(&rtTemp,BDR_RAISEDINNER,BF_RIGHT);
  286. }
  287. dc.DrawEdge(&rtTemp,BDR_RAISEDINNER,BF_LEFT);
  288. }
  289. CRect rcText;
  290. TEXTMETRIC Metrics;
  291. dc.GetTextMetrics(&Metrics);
  292. CImageList *ImgList = GetImageList();
  293. if(ImgList != NULL)
  294. {
  295. CRect rtIcon;
  296. rtIcon.top = rcItem.top + 1;
  297. rtIcon.bottom = rcItem.bottom - 1;
  298. rtIcon.left = rcItem.left + 1;
  299. rtIcon.right = rtIcon.left + rtIcon.Height() - 2;
  300. HICON hIcon = ImgList->ExtractIcon(tim.iImage);
  301. if(hIcon != NULL)
  302. {
  303. DrawIconEx(dc.m_hDC,rtIcon.left,rtIcon.top,hIcon, rtIcon.Width(),rtIcon.Height(),0,NULL,DI_NORMAL);
  304. DeleteObject(hIcon);
  305. }
  306. rcText.SetRect(rcItem.left + rcItem.Height(),rcItem.top + (rcItem.Height() - Metrics.tmHeight)/2,rcItem.right,rcItem.bottom);
  307. dc.DrawText(ItemText,(int)strlen(ItemText),&rcText,DT_LEFT | DT_SINGLELINE | DT_END_ELLIPSIS);
  308. }
  309. else
  310. {
  311. rcText.SetRect(rcItem.left,rcItem.top + (rcItem.Height() - Metrics.tmHeight)/2,rcItem.right,rcItem.bottom);
  312. dc.DrawText(ItemText,(int)strlen(ItemText),&rcText,DT_CENTER | DT_SINGLELINE | DT_END_ELLIPSIS);
  313. }
  314. }
  315. }
  316. dc.SetBkMode(OldModule);
  317. dc.SelectObject(pOldFont);
  318. }
  319. void CRTTabCtrl::OnSize(UINT nType, int cx, int cy)
  320. {
  321. CTabCtrl::OnSize(nType, cx, cy);
  322. int ItemCount = GetItemCount();
  323. CRect rtClient;
  324. GetClientRect(&rtClient);
  325. for(int i = 0; i < ItemCount; i++)
  326. {
  327. TCITEM tm;
  328. ZeroMemory(&tm,sizeof(tm));
  329. tm.mask = TCIF_PARAM;
  330. if(GetItem(i,&tm))
  331. {
  332. CWnd* pWnd = (CWnd *)tm.lParam;
  333. if(pWnd != NULL && IsWindow(pWnd->m_hWnd))
  334. {
  335. pWnd->MoveWindow(&rtClient);
  336. }
  337. }
  338. }
  339. }
  340. void CRTTabCtrl::SetTabBitmap(CBitmap* TabBitmap[], UINT DrawMode[])
  341. {
  342. for(int i = 0; i < 5; i++)
  343. {
  344. m_TabBitmap[i] = TabBitmap[i];
  345. m_TabBitmapDrawMode[i] = DrawMode[i];
  346. }
  347. }
  348. BOOL CRTTabCtrl::PreCreateWindow(CREATESTRUCT& cs)
  349. {
  350. if(!CTabCtrl::PreCreateWindow(cs))
  351. return FALSE;
  352. cs.style &= ~TCS_MULTISELECT;
  353. return TRUE;
  354. }
  355. void CRTTabCtrl::PreSubclassWindow()
  356. {
  357. CTabCtrl::PreSubclassWindow();
  358. }
  359. void CRTTabCtrl::ShowTabItem(BOOL IsVisable)
  360. {
  361. m_IsShowTabItem = IsVisable;
  362. }
  363. LONG CRTTabCtrl::Add(int Position,LPCTSTR lpszItemText,int Image,CWnd* pItemWnd)
  364. {
  365. TCITEM tm;
  366. ZeroMemory(&tm,sizeof(tm));
  367. tm.lParam = (LPARAM)pItemWnd;
  368. tm.pszText = (LPSTR)lpszItemText;
  369. tm.cchTextMax = (int)strlen(lpszItemText);
  370. tm.iImage = Image;
  371. tm.mask = TCIF_IMAGE|TCIF_PARAM|TCIF_TEXT;
  372. int pos = CTabCtrl::InsertItem(Position,&tm);
  373. if(pos == -1)return -1;
  374. if(pItemWnd != NULL && IsWindow(pItemWnd->m_hWnd))
  375. {
  376. pItemWnd->SetParent(this);
  377. if(pos == GetCurSel())
  378. {
  379. pItemWnd->ShowWindow(SW_SHOW);
  380. }
  381. else
  382. {
  383. pItemWnd->ShowWindow(SW_HIDE);
  384. }
  385. }
  386. return pos;
  387. }
  388. void CRTTabCtrl::OnTcnSelchange()
  389. {
  390. int i = GetCurSel();
  391. if(i >= 0)
  392. {
  393. TCITEM tm;
  394. ZeroMemory(&tm,sizeof(tm));
  395. tm.mask = TCIF_PARAM;
  396. if(GetItem(i,&tm))
  397. {
  398. CWnd* pWnd = (CWnd *)tm.lParam;
  399. if(pWnd != NULL && IsWindow(pWnd->m_hWnd))
  400. {
  401. pWnd->ShowWindow(SW_SHOW);
  402. }
  403. }
  404. }
  405. }
  406. void CRTTabCtrl::OnTcnSelchanging(int oldSel)
  407. {
  408. int i = oldSel;
  409. if(i >= 0)
  410. {
  411. TCITEM tm;
  412. ZeroMemory(&tm,sizeof(tm));
  413. tm.mask = TCIF_PARAM;
  414. if(GetItem(i,&tm))
  415. {
  416. CWnd* pWnd = (CWnd *)tm.lParam;
  417. if(pWnd != NULL && IsWindow(pWnd->m_hWnd))
  418. {
  419. pWnd->ShowWindow(SW_HIDE);
  420. }
  421. }
  422. }
  423. }
  424. void CRTTabCtrl::EnableSkin(BOOL IsEnable)
  425. {
  426. m_IsEnableSkin = IsEnable;
  427. }
  428. BOOL CRTTabCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  429. {
  430. GetParent()->SendMessage(WM_NOTIFY,wParam,lParam);
  431. return CTabCtrl::OnNotify(wParam, lParam, pResult);
  432. }