CustomTabCtrl.cpp
上传用户:huashan618
上传日期:2013-03-26
资源大小:261k
文件大小:74k
源码类别:

浏览器

开发平台:

Visual C++

  1. /**********************************************************************
  2. **
  3. ** CustomTabCtrl.cpp : implementation file of CCustomTabCtrl class
  4. **
  5. ** by Andrzej Markowski June 2004
  6. **
  7. **  teazlemoon add it's funcation,in oct 2005
  8. **  在本代码段中,去除了修改TAB键上的编辑标志功能,增加了GDI+的相关内容
  9. **  处理按钮的透明色绘制、视图窗口的建立和管理部分
  10. **********************************************************************/
  11. #include "stdafx.h"
  12. #include "CustomTabCtrl.h"
  13. #include "resource.h"
  14. #ifndef _GDIPLUS_USED
  15.   #include <gdiplus.h>
  16. #include ".customtabctrl.h"
  17. #pragma comment(lib,"gdiplus.lib")
  18.   using namespace Gdiplus;
  19. #endif
  20. // CCustomTabCtrlItem
  21. ULONG_PTR g_token;
  22. CCustomTabCtrlItem::CCustomTabCtrlItem(CString sText,/*LPARAM*/CWnd* lParam) : 
  23. m_sText(sText), 
  24. m_lParam(lParam),
  25. m_bShape(TAB_SHAPE1),
  26. m_fSelected(FALSE),
  27. m_fHighlighted(FALSE),
  28. m_fHighlightChanged(FALSE),
  29. m_OpenURL(FALSE)
  30. {
  31. GdiplusStartupInput start;
  32. GdiplusStartup(&g_token,&start,NULL);
  33. }
  34. void CCustomTabCtrlItem::operator=(const CCustomTabCtrlItem &other)
  35. {
  36. m_sText = other.m_sText;
  37. m_lParam = other.m_lParam;
  38. }
  39. void CCustomTabCtrlItem::ComputeRgn()
  40. {
  41. m_rgn.DeleteObject();
  42. CPoint pts[6];
  43. GetRegionPoints(m_rect,pts);
  44. m_rgn.CreatePolygonRgn(pts, 6, WINDING);
  45. }
  46. void CCustomTabCtrlItem::GetRegionPoints(const CRect& rc, CPoint* pts) const
  47. {
  48. switch(m_bShape)
  49. {
  50. case TAB_SHAPE2:
  51. {
  52. pts[0] = rc.TopLeft();
  53. pts[1] = CPoint(rc.left, rc.bottom);
  54. pts[2] = CPoint(rc.left + rc.Height()/2, rc.top);
  55. pts[3] = CPoint(rc.left + rc.Height()/2, rc.top);
  56. pts[4] = CPoint(rc.left + rc.Height()/2, rc.top);
  57. pts[5] = CPoint(rc.left + rc.Height()/2, rc.top);
  58. }
  59. break;
  60. case TAB_SHAPE3:
  61. {
  62. pts[0] = rc.TopLeft();
  63. pts[1] = CPoint(rc.left + rc.Height()/4, rc.Height()/2);
  64. pts[2] = CPoint(rc.left, rc.bottom);
  65. pts[3] = CPoint(rc.left, rc.bottom);
  66. pts[4] = CPoint(rc.left, rc.bottom);
  67. pts[5] = CPoint(rc.left, rc.bottom);
  68. }
  69. break;
  70. case TAB_SHAPE4:
  71. {
  72. pts[0] = rc.TopLeft();
  73. pts[1] = CPoint(rc.left + rc.Height()/4, rc.Height()/2);
  74. pts[2] = CPoint(rc.left + rc.Height()/2, rc.bottom);
  75. pts[3] = CPoint(rc.right - rc.Height()/2, rc.bottom);
  76. pts[4] = CPoint(rc.right - rc.Height()/4, rc.Height()/2);
  77. pts[5] = CPoint(rc.right, rc.top);
  78. }
  79. break;
  80. case TAB_SHAPE5:
  81. {
  82. pts[0] = rc.TopLeft();
  83. pts[1] = CPoint(rc.left + rc.Height()/4, rc.Height()/2);
  84. pts[2] = CPoint(rc.left + rc.Height()/2 , rc.bottom);
  85. pts[3] = CPoint(rc.right - rc.Height()/2, rc.bottom);
  86. pts[4] = CPoint(rc.right - rc.Height()/4, rc.Height()/2);
  87. pts[5] = CPoint(rc.right - rc.Height()/2, rc.top);
  88. }
  89. break;
  90. default:
  91. {
  92. pts[0] = CPoint(0,0);
  93. pts[1] = CPoint(0,0);
  94. pts[2] = CPoint(0,0);
  95. pts[3] = CPoint(0,0);
  96. pts[4] = CPoint(0,0);
  97. pts[5] = CPoint(0,0);
  98. }
  99. break;
  100. }
  101. }
  102. void CCustomTabCtrlItem::GetDrawPoints(const CRect& rc, CPoint* pts) const
  103. {
  104. switch(m_bShape)
  105. {
  106. case TAB_SHAPE2:
  107. case TAB_SHAPE3:
  108. {
  109. pts[0] = CPoint(rc.left, rc.bottom);
  110. pts[1] = CPoint(rc.left + rc.Height()/2, rc.top);
  111. }
  112. break;
  113. case TAB_SHAPE4:
  114. case TAB_SHAPE5:
  115. {
  116. pts[0] = rc.TopLeft();
  117. pts[1] = CPoint(rc.left + rc.Height()/2, rc.bottom);
  118. pts[2] = CPoint(rc.right - rc.Height()/2, rc.bottom);
  119. pts[3] = CPoint(rc.right, rc.top);
  120. }
  121. break;
  122. }
  123. }
  124. //绘制TAB项,在这里,使用GDI+的一些方面,实现颜色渐变和半透明
  125. void CCustomTabCtrlItem::Draw(CDC& dc, CFont& font)
  126. {
  127. //设置前景和背景色
  128. COLORREF bgColor = GetSysColor((m_fSelected||m_fHighlighted) ? COLOR_WINDOW     : COLOR_3DFACE);
  129. COLORREF fgColor = GetSysColor((m_fSelected ||m_fHighlighted) ? COLOR_WINDOWTEXT : COLOR_BTNTEXT);
  130.     //COLORREF bgColor=RGB(255,128,128);
  131. // COLORREF fgColor=RGB(0,0,0);
  132. dc.SetBkMode(TRANSPARENT);
  133. Graphics graph(dc.m_hDC);
  134. CRect rect;
  135. m_rgn.GetRgnBox(&rect);
  136. LinearGradientBrush linbrush(Point(rect.left,rect.top),Point(rect.left,rect.bottom),
  137.                              Color(255,192,214,192),Color(198,128,128,128));
  138.     Region reg((HRGN)m_rgn);
  139. graph.FillRegion(&linbrush,&reg);
  140. //CBrush brush(RGB(128,168,128));//(bgColor);
  141.     //设置TAB框线的颜色
  142. // CPen blackPen(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
  143. // CPen shadowPen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
  144.     CPen blackPen(PS_SOLID, 2, RGB(64,0,0));
  145. CPen shadowPen(PS_SOLID, 2, RGB(0,0,128));
  146. CPoint pts[4];
  147. CRect rc = m_rect;
  148. GetDrawPoints(rc, pts);
  149. // Paint item background
  150. //dc.FillRgn(&m_rgn, &brush);
  151. CPen* pOldPen = dc.SelectObject(&blackPen);
  152. // draw item
  153. switch(m_bShape)
  154. {
  155. case TAB_SHAPE2:
  156. case TAB_SHAPE3:
  157. {
  158. dc.MoveTo(pts[0]);
  159. dc.LineTo(pts[1]);
  160. if(!m_fSelected)
  161. {
  162. dc.SelectObject(&shadowPen);
  163. dc.MoveTo(pts[0].x-1,pts[0].y);
  164. dc.LineTo(pts[1].x-1,pts[1].y);
  165. }
  166. }
  167. break;
  168. case TAB_SHAPE4:
  169. case TAB_SHAPE5:
  170. {
  171. dc.MoveTo(pts[0]);
  172. dc.LineTo(pts[1]);
  173. dc.SelectObject(&shadowPen);
  174. dc.LineTo(pts[2]);
  175. if(!m_fSelected)
  176. {
  177. dc.MoveTo(pts[2].x-1,pts[2].y);
  178. dc.LineTo(pts[3].x-1,pts[3].y);
  179. }
  180. dc.SelectObject(&blackPen);
  181. dc.MoveTo(pts[2]);
  182. dc.LineTo(pts[3]);
  183. // draw item text
  184. COLORREF bgOldColor = dc.SetBkColor(bgColor);
  185. COLORREF fgOldColor = dc.SetTextColor(fgColor);
  186. rc.DeflateRect(rc.Height()/2, 2,rc.Height()/2,2);
  187. CFont* pOldFont = dc.SelectObject(&font);
  188. dc.DrawText(m_sText, &rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  189. dc.SelectObject(pOldFont);
  190. dc.SetTextColor(fgOldColor);
  191. dc.SetBkColor(bgOldColor);
  192. }
  193. break;
  194. }
  195. dc.SelectObject(pOldPen);
  196. }
  197. // CCustomTabCtrl
  198. LOGFONT CCustomTabCtrl::lf_default = {14, 0, 0, 0, FW_NORMAL, 0, 0, 0,
  199. DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
  200. DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Microsoft Sans Serif"};
  201. BYTE CCustomTabCtrl::m_bBitsGlyphs[] = {0xBD,0xFB,0xDF,0xBD,
  202. 0xB9,0xF3,0xCF,0x9D,
  203. 0xB1,0xE3,0xC7,0x8D,
  204. 0xA3,0xC7,0xE3,0xC5,
  205. 0xB1,0xE3,0xC7,0x8D,
  206. 0xB9,0xF3,0xCF,0x9D,
  207. 0xBD,0xFB,0xDF,0xBD};
  208. CCustomTabCtrl::CCustomTabCtrl() :
  209. m_nButtonIDDown(CTCID_NOBUTTON),
  210. m_nPrevState(BNST_INVISIBLE),
  211. m_nNextState(BNST_INVISIBLE),
  212. m_nFirstState(BNST_INVISIBLE),
  213. m_nLastState(BNST_INVISIBLE),
  214. m_nItemSelected(-1),
  215. m_nItemNdxOffset(0),
  216. m_dwLastRepeatTime(0),
  217. m_hBmpBkLeftSpin(NULL),
  218. m_hBmpBkRightSpin(NULL),
  219. m_hCursorMove(NULL),
  220. m_hCursorCopy(NULL),
  221. m_nItemDragDest(0)
  222. {
  223. RegisterWindowClass();
  224. SetControlFont(GetDefaultFont());
  225. m_bmpGlyphsMono.CreateBitmap(32,7,1,1,m_bBitsGlyphs);
  226. m_rClient.SetRect(0,0,0,0);
  227. m_hSwitch=DEF_SWITCH_HEIGHT;
  228. // m_orgial=FALSE;
  229. m_oldwnd=NULL;
  230. }
  231. // Register the window class if it has not already been registered.
  232. BOOL CCustomTabCtrl::RegisterWindowClass()
  233. {
  234.     WNDCLASS wndcls;
  235.     HINSTANCE hInst = AfxGetInstanceHandle();
  236.     if (!(::GetClassInfo(hInst, CustomTabCtrl_CLASSNAME, &wndcls)))
  237.     {
  238.         wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
  239.         wndcls.lpfnWndProc      = ::DefWindowProc;
  240.         wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
  241.         wndcls.hInstance        = hInst;
  242.         wndcls.hIcon            = NULL;
  243.         wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
  244.         wndcls.hbrBackground    = (HBRUSH) (COLOR_3DFACE + 1);
  245.         wndcls.lpszMenuName     = NULL;
  246.         wndcls.lpszClassName    = CustomTabCtrl_CLASSNAME;
  247.         if (!AfxRegisterClass(&wndcls))
  248.         {
  249.             AfxThrowResourceException();
  250.             return FALSE;
  251.         }
  252.     }
  253.     return TRUE;
  254. }
  255. CCustomTabCtrl::~CCustomTabCtrl()
  256. {
  257. for(int i=0; i< m_aItems.GetSize(); i++)
  258. {
  259. CCustomTabCtrlItem* pItem =(CCustomTabCtrlItem*)m_aItems.GetAt(i);
  260. ((CIEView*)pItem->m_lParam)->SendMessage(WM_DESTROY);
  261. delete m_aItems[i];
  262. }
  263. m_aItems.RemoveAll();
  264. ::DeleteObject(m_hBmpBkLeftSpin);
  265. m_hBmpBkLeftSpin = NULL;
  266. ::DeleteObject(m_hBmpBkRightSpin);
  267. m_hBmpBkRightSpin = NULL;
  268. ::DestroyCursor(m_hCursorMove);
  269. m_hCursorMove = NULL;
  270. ::DestroyCursor(m_hCursorCopy);
  271. m_hCursorCopy = NULL;
  272. GdiplusShutdown(g_token);
  273. }
  274. BEGIN_MESSAGE_MAP(CCustomTabCtrl, CWnd)
  275. //{{AFX_MSG_MAP(CCustomTabCtrl)
  276. ON_WM_ERASEBKGND()
  277. ON_WM_LBUTTONDOWN()
  278. ON_WM_LBUTTONUP()
  279. ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
  280. ON_MESSAGE(THM_WM_THEMECHANGED,OnThemeChanged)
  281. ON_WM_MOUSEMOVE()
  282. ON_WM_PAINT()
  283. ON_WM_SIZE()
  284. ON_WM_LBUTTONDBLCLK()
  285. ON_WM_TIMER()
  286. //}}AFX_MSG_MAP
  287. // ON_WM_NCRBUTTONDOWN()
  288. //ON_WM_RBUTTONDOWN()
  289. ON_WM_RBUTTONDOWN()
  290. END_MESSAGE_MAP()
  291. // CCustomTabCtrl message handlers
  292. BOOL CCustomTabCtrl::Create(UINT dwStyle, const CRect & rect, CWnd * pParentWnd, UINT nID)
  293. {
  294.     m_rClient=rect;
  295. dwStyle|=WS_BORDER;
  296. if(m_rClient.Height()>m_hSwitch)
  297. {
  298. m_rClient.bottom=m_rClient.bottom-m_hSwitch-DEF_STOWND_LENGTH;
  299. }
  300. CRect switchrect;
  301. switchrect.SetRect(rect.left,rect.bottom-m_hSwitch,rect.right,rect.bottom);
  302. return CWnd::Create(CustomTabCtrl_CLASSNAME, _T(""), dwStyle, switchrect, pParentWnd, nID);
  303. }
  304. BOOL CCustomTabCtrl::OnEraseBkgnd(CDC* pDC)
  305. {
  306. return TRUE;
  307. }
  308. void CCustomTabCtrl::OnPaint()
  309. {
  310. CPaintDC dc(this);
  311. if(!m_hBmpBkLeftSpin)
  312. {
  313. m_rgbGlyph[0] =RGB(0,0,255);// GetSysColor(COLOR_BTNTEXT);切换按钮平常箭头色
  314. m_rgbGlyph[1] =RGB(255,0,0);// GetSysColor(COLOR_BTNTEXT);切换按钮在MOUSE位于其上箭头色
  315. m_rgbGlyph[2] =RGB(0,0,192);// GetSysColor(COLOR_BTNTEXT);
  316. m_rgbGlyph[3] =RGB(0,255,0);// GetSysColor(COLOR_BTNTEXT);
  317. }
  318. CRect rCl;
  319. GetClientRect(&rCl);
  320. // CPen blackPen(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
  321. //绘制按钮边框的颜色
  322.     CPen blackPen(PS_SOLID, 2, RGB(0,0,128));
  323. CDC dcMem;
  324. CBitmap bmpMem;
  325. CBitmap* pOldBmp=NULL;
  326. if(dcMem.CreateCompatibleDC(&dc))
  327. {
  328. if(bmpMem.CreateCompatibleBitmap(&dc,rCl.Width(),rCl.Height()))
  329. pOldBmp = dcMem.SelectObject(&bmpMem);
  330. else
  331. return;
  332.     }
  333. else
  334. return;
  335. int nBtns = 2;
  336. if(GetStyle()&CTCS_FOURBUTTONS)
  337. nBtns = 4;
  338. {
  339. // clear background
  340. // dcMem.FillSolidRect(&rCl,GetSysColor(COLOR_BTNFACE));
  341. dcMem.FillSolidRect(&rCl,RGB(192,192,255));
  342. }
  343. {
  344. // 以下部分绘制按钮
  345. if(m_nPrevState && m_nNextState)
  346. {
  347. int nA = rCl.Height()-3;
  348. CRect rAll(0,1,nBtns*nA+3,rCl.Height());
  349. CRect rFirst,rPrev,rNext,rLast;
  350. if(nBtns==2)
  351. {
  352. rPrev.SetRect(1,2,nA+1,rCl.Height()-1);
  353. rNext.SetRect(nA+2,2,2*nA+2,rCl.Height()-1);
  354. }
  355. else
  356. {
  357. rFirst.SetRect(1,2,nA+1,rCl.Height()-1);
  358. rPrev.SetRect(nA+1,2,2*nA+1,rCl.Height()-1);
  359. rNext.SetRect(2*nA+2,2,3*nA+2,rCl.Height()-1);
  360. rLast.SetRect(3*nA+2,2,4*nA+2,rCl.Height()-1);
  361. }
  362. CPen* pOldPen = dcMem.SelectObject(&blackPen);
  363. dcMem.Rectangle(rAll);
  364. dcMem.SelectObject(pOldPen);
  365. if(nBtns==4)
  366. {
  367. CPoint ptFirst(rFirst.left+(rFirst.Width()-8)/2,rFirst.top+(rFirst.Height()-7)/2);
  368. if(m_hBmpBkLeftSpin)
  369. DrawBkLeftSpin(dcMem,rFirst,m_nFirstState-1);
  370. else
  371. {
  372. if(m_nFirstState==BNST_PRESSED)//绘制指向TAB第一个项
  373. {
  374. Graphics graph(dcMem.m_hDC);
  375.         LinearGradientBrush linbrush(Point(rFirst.left,rFirst.top),Point(rFirst.left,rFirst.bottom),
  376.                           Color(128,192,64,64),Color(255,128,64,64));
  377.         graph.FillRectangle(&linbrush,rFirst.left,rFirst.top,rFirst.Width(),rFirst.Height());
  378.     dcMem.DrawEdge(&rFirst,BDR_SUNKENOUTER,BF_RECT);
  379. // dcMem.DrawFrameControl(rFirst,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_PUSHED);
  380. }
  381. else
  382. {
  383.    Graphics graph(dcMem.m_hDC);
  384.        LinearGradientBrush linbrush(Point(rFirst.left,rFirst.top),Point(rFirst.left,rFirst.bottom),
  385.                           Color(128,255,128,128),Color(255,192,64,64));
  386.        graph.FillRectangle(&linbrush,rFirst.left,rFirst.top,rFirst.Width(),rFirst.Height());
  387.        dcMem.DrawEdge(&rFirst,BDR_RAISEDOUTER,BF_RECT);
  388. //dcMem.DrawFrameControl(rFirst,DFC_BUTTON,DFCS_BUTTONPUSH);
  389. }
  390. }
  391. DrawGlyph(dcMem,ptFirst,0,m_nFirstState-1);
  392. CPoint ptLast(rLast.left+(rLast.Width()-8)/2,rLast.top+(rLast.Height()-7)/2);
  393. if(m_hBmpBkRightSpin)
  394. DrawBkRightSpin(dcMem,rLast,m_nLastState-1);
  395. else//绘制TAB最后一个项按钮
  396. {
  397. if(m_nLastState==BNST_PRESSED)
  398. {
  399. Graphics graph(dcMem.m_hDC);
  400.         LinearGradientBrush linbrush(Point(rLast.left,rLast.top),Point(rLast.left,rLast.bottom),
  401.                           Color(128,192,64,64),Color(255,128,64,64));
  402. // rPrev.InflateRect(1,1,-1,-1);
  403.         graph.FillRectangle(&linbrush,rLast.left+1,rLast.top+1,rLast.Width()-2,rLast.Height()-2);
  404.     dcMem.DrawEdge(&rLast,BDR_SUNKENOUTER,BF_RECT);
  405. // dcMem.DrawFrameControl(rLast,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_PUSHED);
  406. }
  407. else
  408. {
  409.    Graphics graph(dcMem.m_hDC);
  410.        LinearGradientBrush linbrush(Point(rLast.left,rLast.top),Point(rLast.left,rLast.bottom),
  411.                           Color(128,255,128,128),Color(255,192,64,64));
  412.        graph.FillRectangle(&linbrush,rLast.left,rLast.top,rLast.Width(),rLast.Height());
  413.        dcMem.DrawEdge(&rLast,BDR_RAISEDOUTER,BF_RECT);
  414. // dcMem.DrawFrameControl(rLast,DFC_BUTTON,DFCS_BUTTONPUSH);
  415. }
  416. DrawGlyph(dcMem,ptLast,3,m_nLastState-1);
  417. }
  418. CPoint ptPrev(rPrev.left+(rPrev.Width()-8)/2,rPrev.top+(rPrev.Height()-7)/2);
  419. if(m_hBmpBkLeftSpin)
  420. DrawBkLeftSpin(dcMem,rPrev,m_nPrevState-1);
  421. else//以下绘制TAB向前的按钮
  422. {
  423. if(m_nPrevState==BNST_PRESSED)
  424. {
  425. Graphics graph(dcMem.m_hDC);
  426.     LinearGradientBrush linbrush(Point(rPrev.left,rPrev.top),Point(rPrev.left,rPrev.bottom),
  427.                           Color(128,192,64,64),Color(255,128,64,64));
  428. // rPrev.InflateRect(1,1,-1,-1);
  429.      graph.FillRectangle(&linbrush,rPrev.left,rPrev.top,rPrev.Width(),rPrev.Height());
  430.  dcMem.DrawEdge(&rPrev,BDR_SUNKENOUTER,BF_RECT);
  431.  //dcMem.DrawFrameControl(rPrev,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_PUSHED);
  432. }
  433. else
  434. {
  435.                   Graphics graph(dcMem.m_hDC);
  436.   LinearGradientBrush linbrush(Point(rPrev.left,rPrev.top),Point(rPrev.left,rPrev.bottom),
  437.                           Color(128,255,128,128),Color(255,192,64,64));
  438.   graph.FillRectangle(&linbrush,rPrev.left,rPrev.top,rPrev.Width(),rPrev.Height());
  439.    dcMem.DrawEdge(&rPrev,BDR_RAISEDOUTER,BF_RECT);
  440. // dcMem.DrawFrameControl(rPrev,DFC_BUTTON,DFCS_BUTTONPUSH);
  441. }
  442. }
  443. DrawGlyph(dcMem,ptPrev,1,m_nPrevState-1);
  444. CPoint ptNext(rNext.left+(rNext.Width()-8)/2,rNext.top+(rNext.Height()-7)/2);
  445. if(m_hBmpBkRightSpin)
  446. DrawBkRightSpin(dcMem,rNext,m_nNextState-1);
  447. else//以下绘制下一个TAB的按钮
  448. {
  449. rNext.left -= 1;
  450. if(m_nNextState==BNST_PRESSED)
  451. {
  452.  Graphics graph(dcMem.m_hDC);
  453.  LinearGradientBrush linbrush(Point(rNext.left,rNext.top),Point(rNext.left,rNext.bottom),
  454.                           Color(128,192,64,64),Color(255,128,64,64));
  455.  graph.FillRectangle(&linbrush,rNext.left,rNext.top,rNext.Width(),rNext.Height());
  456.  dcMem.DrawEdge(&rNext,BDR_SUNKENOUTER,BF_RECT);
  457. // dcMem.DrawFocusRect(&rNext);
  458. //dcMem.DrawFrameControl(rNext,DFC_BUTTON,DFCS_BUTTONPUSH|DFCS_PUSHED);
  459. }
  460. else
  461. {
  462.   Graphics graph(dcMem.m_hDC);
  463.   LinearGradientBrush linbrush(Point(rNext.left,rNext.top),Point(rNext.left,rNext.bottom),
  464.                           Color(128,255,128,128),Color(255,192,64,64));
  465.  graph.FillRectangle(&linbrush,rNext.left,rNext.top,rNext.Width(),rNext.Height());
  466.  dcMem.DrawEdge(&rNext,BDR_RAISEDOUTER,BF_RECT);
  467.                  //   dcMem.Draw3dRect(rNext.left,rNext.top,rNext.Width(),rNext.Height(),RGB(255,0,0),RGB(0,255,0));
  468. // dcMem.DrawFrameControl(rNext,DFC_BUTTON,DFCS_BUTTONPUSH);
  469. }
  470. }
  471. DrawGlyph(dcMem,ptNext,2,m_nNextState-1);
  472. }
  473. }
  474. {
  475. // draw tab items visible and not selected
  476. //绘制TAB项中可见但为非选的项
  477. for(int i= 0; i<m_aItems.GetSize(); i++)
  478. {
  479. if(m_aItems[i]->m_bShape && !m_aItems[i]->m_fSelected)
  480. {
  481. if(m_aItems[i]->m_fHighlighted)
  482. m_aItems[i]->Draw(dcMem,m_FontSelected);
  483. else
  484. m_aItems[i]->Draw(dcMem,m_Font);
  485. }
  486. }
  487. // draw selected tab item
  488. if(m_nItemSelected!=-1 && m_aItems[m_nItemSelected]->m_bShape)
  489.    m_aItems[m_nItemSelected]->Draw(dcMem,m_FontSelected);
  490.  
  491. }
  492. {
  493. // draw black lines
  494. int nOffsetX = 0;
  495. if(m_nPrevState && m_nNextState)
  496. nOffsetX = nBtns*(rCl.Height()-3)+3;
  497. CPoint pts[4];
  498. if(m_nItemSelected==-1)
  499. {
  500. pts[0] = CPoint(nOffsetX,1); 
  501. pts[1] = CPoint(nOffsetX,1); 
  502. pts[2] = CPoint(nOffsetX,1); 
  503. pts[3] = CPoint(rCl.right,1);
  504. }
  505. else
  506. {
  507. if(m_aItems[m_nItemSelected]->m_bShape)
  508. {
  509. pts[0] = CPoint(nOffsetX,1); 
  510. pts[1] = CPoint(m_aItems[m_nItemSelected]->m_rect.left,1); 
  511. pts[2] = CPoint(m_aItems[m_nItemSelected]->m_rect.right,1); 
  512. pts[3] = CPoint(rCl.right,1);
  513. }
  514. else
  515. {
  516. pts[0] = CPoint(nOffsetX,1); 
  517. pts[1] = CPoint(nOffsetX,1); 
  518. pts[2] = CPoint(nOffsetX,1); 
  519. pts[3] = CPoint(rCl.right,1);
  520. }
  521. }
  522. CPen* pOldPen = dcMem.SelectObject(&blackPen);
  523. dcMem.MoveTo(pts[0]);
  524. dcMem.LineTo(pts[1]);
  525. dcMem.MoveTo(pts[2]);
  526. dcMem.LineTo(pts[3]);
  527. dcMem.SelectObject(pOldPen);
  528. }
  529. {
  530. if(m_nButtonIDDown>=0 && 
  531. (GetCursor()==m_hCursorMove || GetCursor()==m_hCursorCopy))
  532. {
  533. // Draw drag destination marker
  534. CPen* pOldPen = dcMem.SelectObject(&blackPen);
  535. int x;
  536. if(m_nItemDragDest==m_aItems.GetSize())
  537. x= m_aItems[m_nItemDragDest-1]->m_rectText.right + rCl.Height()/4-3;
  538. else
  539. x= m_aItems[m_nItemDragDest]->m_rectText.left - rCl.Height()/4-3;
  540. if(x>=rCl.right-7)
  541. x = rCl.right-7;
  542. dcMem.MoveTo(x,1);
  543. dcMem.LineTo(x+7,1);
  544. dcMem.MoveTo(x+1,2);
  545. dcMem.LineTo(x+6,2);
  546. dcMem.MoveTo(x+2,3);
  547. dcMem.LineTo(x+5,3);
  548. dcMem.MoveTo(x+3,4);
  549. dcMem.LineTo(x+4,4);
  550. }
  551. }
  552. dc.BitBlt(rCl.left,
  553.                    rCl.top,
  554.                    rCl.Width(),
  555.                    rCl.Height(),
  556.                    &dcMem,
  557.                    rCl.left,
  558.                    rCl.top,
  559.                    SRCCOPY);
  560. dcMem.SelectObject(pOldBmp);
  561. }
  562. void CCustomTabCtrl::OnSize(UINT nType, int cx, int cy) 
  563. {
  564. CWnd::OnSize(nType, cx, cy);
  565. if(cx && cy)
  566. RecalcLayout(RECALC_RESIZED, m_nItemSelected);
  567. }
  568. void CCustomTabCtrl::OnLButtonDown(UINT nFlags, CPoint point)
  569. {
  570. int nHitTest = HitTest(point);
  571. NotifyParent(CTCN_CLICK,nHitTest,point);//发送消息到父窗口
  572. ProcessLButtonDown(nHitTest,nFlags,point);//处理按下左端按钮
  573. CWnd::OnLButtonDown(nFlags,point);
  574. }
  575. /*void CCustomTabCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) 
  576. {
  577. int nHTRet = ProcessLButtonDown(HitTest(point),nFlags,point);
  578. if(nHTRet>=0)
  579. {
  580. m_nButtonIDDown = CTCID_NOBUTTON;
  581. // if(nHTRet==HitTest(point))
  582. // EditLabel(nHTRet,TRUE);
  583. }
  584. CWnd::OnLButtonDblClk(nFlags, point);
  585. }*/
  586. //按下左键后,执行相应的操作首先处理前面切换视图的按钮,是移到第一视图、
  587. int CCustomTabCtrl::ProcessLButtonDown(int nHitTest, UINT nFlags, CPoint point)
  588. {
  589. SetCapture();
  590. switch(nHitTest)
  591. {
  592. case CTCHT_NOWHERE:
  593. m_nButtonIDDown = CTCID_NOBUTTON;
  594. break;
  595. case CTCHT_ONFIRSTBUTTON://移到第一个视图
  596. {
  597. m_nButtonIDDown = CTCID_FIRSTBUTTON;
  598. m_nFirstState = BNST_PRESSED;
  599. RecalcLayout(RECALC_FIRST_PRESSED,m_nItemSelected);
  600. Invalidate(FALSE);
  601. m_dwLastRepeatTime = ::GetTickCount();
  602. SetTimer(1,100,NULL);
  603. }
  604. break;
  605. case CTCHT_ONPREVBUTTON://切换到前一个视图
  606. {
  607. m_nButtonIDDown = CTCID_PREVBUTTON;
  608. m_nPrevState = BNST_PRESSED;
  609. RecalcLayout(RECALC_PREV_PRESSED,m_nItemSelected);
  610. Invalidate(FALSE);
  611. m_dwLastRepeatTime = ::GetTickCount();
  612. SetTimer(1,100,NULL);
  613. }
  614. break;
  615. case CTCHT_ONNEXTBUTTON://切换到下一个视图
  616. {
  617. m_nButtonIDDown = CTCID_NEXTBUTTON;
  618. m_nNextState = BNST_PRESSED;
  619. RecalcLayout(RECALC_NEXT_PRESSED,m_nItemSelected);
  620. Invalidate(FALSE);
  621. m_dwLastRepeatTime = ::GetTickCount();
  622. SetTimer(1,100,NULL);
  623. }
  624. break;
  625. case CTCHT_ONLASTBUTTON://切换到最后一个视图
  626. {
  627. m_nButtonIDDown = CTCID_LASTBUTTON;
  628. m_nLastState = BNST_PRESSED;
  629. RecalcLayout(RECALC_LAST_PRESSED,m_nItemSelected);
  630. Invalidate(FALSE);
  631. m_dwLastRepeatTime = ::GetTickCount();
  632. SetTimer(1,100,NULL);
  633. }
  634. break;
  635. default:
  636. {
  637. DWORD dwStyle = GetStyle();
  638. if(((dwStyle&CTCS_DRAGMOVE) && !(nFlags&MK_CONTROL) && m_hCursorMove) || 
  639. ((dwStyle&CTCS_DRAGCOPY) && (nFlags&MK_CONTROL) && m_hCursorCopy))
  640. {
  641. m_nButtonIDDown = nHitTest;
  642. m_nItemDragDest = nHitTest;
  643. SetTimer(2,300,NULL);
  644. }
  645. else
  646. m_nButtonIDDown = CTCID_NOBUTTON;
  647. if((GetStyle()&CTCS_MULTIHIGHLIGHT) && (nFlags&MK_CONTROL))
  648. HighlightItem(nHitTest,TRUE,nFlags&MK_CONTROL);
  649. else
  650. {
  651. BOOL bNotify = nHitTest!=m_nItemSelected;
  652. SetCurSel(nHitTest,TRUE,nFlags&MK_CONTROL);
  653. if(bNotify)
  654. NotifyParent(CTCN_SELCHANGE,m_nItemSelected,point);
  655. }
  656. for(int i=0; i<m_aItems.GetSize();i++)
  657. {
  658. if(m_aItems[i]->m_fHighlightChanged)
  659. NotifyParent(CTCN_HIGHLIGHTCHANGE,i,point);
  660. }
  661. }
  662. break;
  663. }
  664. return nHitTest;
  665. }
  666. //处理按钮消息,并将相应的按钮消息发送到父窗口,以便对TAB窗口的切换作出响应
  667. BOOL CCustomTabCtrl::NotifyParent(UINT code, int nItem, CPoint pt)
  668. {
  669. CTC_NMHDR nmh;
  670. memset(&nmh,0,sizeof(CTC_NMHDR));
  671. nmh.hdr.hwndFrom = GetSafeHwnd();
  672. nmh.hdr.idFrom = GetDlgCtrlID();
  673. nmh.hdr.code = code;
  674. nmh.nItem = nItem;
  675. nmh.ptHitTest = pt;
  676. if(nItem>=0)
  677. {
  678. _tcscpy(nmh.pszText,m_aItems[nItem]->m_sText);
  679. nmh.lParam = m_aItems[nItem]->m_lParam;
  680. nmh.rItem = m_aItems[nItem]->m_rectText;
  681. nmh.fSelected = m_aItems[nItem]->m_fSelected;
  682. nmh.fHighlighted = m_aItems[nItem]->m_fHighlighted;
  683. if(code==CTCN_SELCHANGE)
  684. {
  685.   
  686.   if(m_oldwnd)
  687.   {
  688.   SwitchWindows(DYNAMIC_DOWNCAST( CView, nmh.lParam));
  689.   m_oldwnd=nmh.lParam;
  690. }
  691. }
  692. }
  693. //在这里选中的窗口发送消息,作出相应的处理
  694. //在这里,对应多个窗口,将选中的窗口设定为活动或禁止
  695. //CString inf;
  696. // inf.Format("显示当前窗口的索引号为:%d",nItem);
  697. // CDC* pDC=GetParent()->GetDC();
  698. // pDC->FillRect(&m_rClient,&CBrush(RGB(255,224,224)));
  699. // pDC->SetBkMode(TRANSPARENT);
  700. // pDC->DrawText(inf,&m_rClient,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  701. // ReleaseDC(pDC);
  702. //////////////////////////////
  703. return (BOOL)GetParent()->SendMessage(WM_NOTIFY,GetDlgCtrlID(),(LPARAM)&nmh);
  704. }
  705. void CCustomTabCtrl::OnLButtonUp(UINT nFlags, CPoint point)
  706. {
  707. if(m_nPrevState || m_nNextState || m_nFirstState || m_nLastState)
  708. {
  709. m_nPrevState = BNST_NORMAL;
  710. m_nNextState = BNST_NORMAL;
  711. m_nFirstState = BNST_NORMAL;
  712. m_nLastState = BNST_NORMAL;
  713. Invalidate(FALSE);
  714. KillTimer(1);
  715. }
  716. if(m_nButtonIDDown>=0)
  717. {
  718. if((GetCursor()==m_hCursorCopy) && (GetKeyState(VK_CONTROL)&0x8000))
  719. CopyItem(m_nButtonIDDown,m_nItemDragDest, TRUE);
  720. else if((GetCursor()==m_hCursorMove) && !(GetKeyState(VK_CONTROL)&0x8000))
  721. MoveItem(m_nButtonIDDown,m_nItemDragDest, TRUE);
  722. }
  723. m_nButtonIDDown = CTCID_NOBUTTON;
  724. ReleaseCapture();
  725. }
  726. void CCustomTabCtrl::OnMouseMove(UINT nFlags, CPoint point)
  727. {
  728. TRACKMOUSEEVENT trackmouseevent;
  729. trackmouseevent.cbSize = sizeof(trackmouseevent);
  730. trackmouseevent.dwFlags = TME_LEAVE;
  731. trackmouseevent.hwndTrack = GetSafeHwnd();
  732. trackmouseevent.dwHoverTime = 0;
  733. _TrackMouseEvent(&trackmouseevent);
  734. CRect rCl;
  735. GetClientRect(&rCl);
  736. int nBtns = 2;
  737. if(GetStyle()&CTCS_FOURBUTTONS)
  738. nBtns = 4;
  739. int nA = rCl.Height()-3;
  740. CRect rFirst,rPrev,rNext,rLast;
  741. if(nBtns==2)
  742. {
  743. rPrev.SetRect(0,0,nA+1,rCl.Height());
  744. rNext.SetRect(nA+1,0,2*nA+3,rCl.Height());
  745. }
  746. else
  747. {
  748. rFirst.SetRect(0,0,nA+1,rCl.Height());
  749. rPrev.SetRect(nA+1,0,2*nA+1,rCl.Height());
  750. rNext.SetRect(2*nA+1,0,3*nA+2,rCl.Height());
  751. rLast.SetRect(3*nA+2,0,4*nA+3,rCl.Height());
  752. }
  753. if(nBtns==4 && m_nFirstState)
  754. {
  755. if(rFirst.PtInRect(point))
  756. {
  757. if(m_nButtonIDDown==CTCID_FIRSTBUTTON)
  758. m_nFirstState = BNST_PRESSED;
  759. else if(m_nButtonIDDown==CTCID_NOBUTTON && !(nFlags&MK_LBUTTON))
  760. m_nFirstState = BNST_HOT;
  761. else
  762. m_nFirstState = BNST_NORMAL;
  763. }
  764. else
  765. m_nFirstState = BNST_NORMAL;
  766. Invalidate(FALSE);
  767. }
  768. if(m_nPrevState)
  769. {
  770. if(rPrev.PtInRect(point))
  771. {
  772. if(m_nButtonIDDown==CTCID_PREVBUTTON)
  773. m_nPrevState = BNST_PRESSED;
  774. else if(m_nButtonIDDown==CTCID_NOBUTTON && !(nFlags&MK_LBUTTON))
  775. m_nPrevState = BNST_HOT;
  776. else
  777. m_nPrevState = BNST_NORMAL;
  778. }
  779. else
  780. m_nPrevState = BNST_NORMAL;
  781. Invalidate(FALSE);
  782. }
  783. if(m_nNextState)
  784. {
  785. if(rNext.PtInRect(point))
  786. {
  787. if(m_nButtonIDDown==CTCID_NEXTBUTTON)
  788. m_nNextState = BNST_PRESSED;
  789. else if(m_nButtonIDDown==CTCID_NOBUTTON && !(nFlags&MK_LBUTTON))
  790. m_nNextState = BNST_HOT;
  791. else
  792. m_nNextState = BNST_NORMAL;
  793. }
  794. else
  795. m_nNextState = BNST_NORMAL;
  796. Invalidate(FALSE);
  797. }
  798. if(nBtns==4 && m_nLastState)
  799. {
  800. if(rLast.PtInRect(point))
  801. {
  802. if(m_nButtonIDDown==CTCID_LASTBUTTON)
  803. m_nLastState = BNST_PRESSED;
  804. else if(m_nButtonIDDown==CTCID_NOBUTTON && !(nFlags&MK_LBUTTON))
  805. m_nLastState = BNST_HOT;
  806. else
  807. m_nLastState = BNST_NORMAL;
  808. }
  809. else
  810. m_nLastState = BNST_NORMAL;
  811. Invalidate(FALSE);
  812. }
  813. if(m_nButtonIDDown>=0)
  814. {
  815. if(m_nItemDragDest>=(int)m_aItems.GetSize())
  816. m_nItemDragDest = (int)m_aItems.GetSize()-1;
  817. int x1 = m_aItems[m_nItemDragDest]->m_rectText.left - rCl.Height()/4;
  818. int x2 = m_aItems[m_nItemDragDest]->m_rectText.right + rCl.Height()/4;
  819. if(point.x>=rCl.right)
  820. {
  821. m_nItemDragDest++;
  822. if(m_nItemDragDest>=m_aItems.GetSize())
  823. RecalcLayout(RECALC_NEXT_PRESSED,(int)m_aItems.GetSize()-1);
  824. else
  825. RecalcLayout(RECALC_NEXT_PRESSED,m_nItemDragDest);
  826. Invalidate(FALSE);
  827. }
  828. else if(point.x>=x2)
  829. {
  830. m_nItemDragDest++;
  831. if(m_nItemDragDest>=(int)m_aItems.GetSize())
  832. RecalcLayout(RECALC_ITEM_SELECTED,(int)m_aItems.GetSize()-1);
  833. else
  834. RecalcLayout(RECALC_ITEM_SELECTED,m_nItemDragDest);
  835. Invalidate(FALSE);
  836. }
  837. else if(point.x<x1)
  838. {
  839. if(m_nItemDragDest>0)
  840. m_nItemDragDest--;
  841. RecalcLayout(RECALC_ITEM_SELECTED,m_nItemDragDest);
  842. Invalidate(FALSE);
  843. }
  844. }
  845. }
  846. LONG CCustomTabCtrl::OnMouseLeave(WPARAM wParam, LPARAM lParam) 
  847. {
  848. if(m_nPrevState || m_nNextState)
  849. {
  850. m_nPrevState = BNST_NORMAL;
  851. m_nNextState = BNST_NORMAL;
  852. m_nFirstState = BNST_NORMAL;
  853. m_nLastState = BNST_NORMAL;
  854. Invalidate(FALSE);
  855. KillTimer(1);
  856. }
  857. return 0;
  858. }
  859. /*void CCustomTabCtrl::OnUpdateEdit() 
  860. {
  861. if(m_ctrlEdit.m_hWnd)
  862. {
  863. m_ctrlEdit.GetWindowText(m_aItems[m_nItemSelected]->m_sText);
  864. RecalcLayout(RECALC_EDIT_RESIZED,m_nItemSelected);
  865. Invalidate(FALSE);
  866. }
  867. }*/
  868. LONG CCustomTabCtrl::OnThemeChanged(WPARAM wParam, LPARAM lParam) 
  869. {
  870. ::DeleteObject(m_hBmpBkLeftSpin);
  871. m_hBmpBkLeftSpin = NULL;
  872. ::DeleteObject(m_hBmpBkRightSpin);
  873. m_hBmpBkRightSpin = NULL;
  874. HBITMAP hBmpGlyph = NULL;
  875. CDC dcGlyph;
  876. dcGlyph.CreateCompatibleDC(NULL);
  877. CBitmap* pOldBmpGlyph = NULL;
  878. try
  879. {
  880. CThemeUtil tm;
  881. if(!tm.OpenThemeData(m_hWnd, L"SPIN"))
  882. AfxThrowUserException();
  883. {
  884. // left spin background
  885. int nBkType;
  886. if(!tm.GetThemeEnumValue(SPNP_DOWNHORZ,0,TMT_BGTYPE,&nBkType))
  887. AfxThrowUserException();
  888. if(nBkType!=BT_IMAGEFILE)
  889. AfxThrowUserException();
  890. int nImageCount;
  891. if(!tm.GetThemeInt(SPNP_DOWNHORZ,0,TMT_IMAGECOUNT,&nImageCount))
  892. AfxThrowUserException();
  893. if(nImageCount!=4)
  894. AfxThrowUserException();
  895. WCHAR szSpinBkLeftBitmapFilename[MAX_PATH];
  896. if(!tm.GetThemeFilename(SPNP_DOWNHORZ,0,TMT_IMAGEFILE,szSpinBkLeftBitmapFilename,MAX_PATH))
  897. AfxThrowUserException();
  898. if(!(m_hBmpBkLeftSpin = tm.LoadBitmap(szSpinBkLeftBitmapFilename)))
  899. AfxThrowUserException();
  900. int nLeftImageLayout;
  901. if(!tm.GetThemeEnumValue(SPNP_DOWNHORZ,0,TMT_IMAGELAYOUT,&nLeftImageLayout))
  902. AfxThrowUserException();
  903. if(nLeftImageLayout==IL_VERTICAL)
  904. m_fIsLeftImageHorLayout = FALSE;
  905. else
  906. m_fIsLeftImageHorLayout = TRUE;
  907. if(!tm.GetThemeMargins(SPNP_DOWNHORZ,0,TMT_SIZINGMARGINS,&m_mrgnLeft))
  908. AfxThrowUserException();
  909. }
  910. {
  911. // right spin background
  912. int nBkType;
  913. if(!tm.GetThemeEnumValue(SPNP_UPHORZ,0,TMT_BGTYPE,&nBkType))
  914. AfxThrowUserException();
  915. if(nBkType!=BT_IMAGEFILE)
  916. AfxThrowUserException();
  917. int nImageCount;
  918. if(!tm.GetThemeInt(SPNP_UPHORZ,0,TMT_IMAGECOUNT,&nImageCount))
  919. AfxThrowUserException();
  920. if(nImageCount!=4)
  921. AfxThrowUserException();
  922. WCHAR szSpinBkRightBitmapFilename[MAX_PATH];
  923. if(!tm.GetThemeFilename(SPNP_UPHORZ,0,TMT_IMAGEFILE,szSpinBkRightBitmapFilename,MAX_PATH))
  924. AfxThrowUserException();
  925. if(!(m_hBmpBkRightSpin = tm.LoadBitmap(szSpinBkRightBitmapFilename)))
  926. AfxThrowUserException();
  927. int nRightImageLayout;
  928. if(!tm.GetThemeEnumValue(SPNP_UPHORZ,0,TMT_IMAGELAYOUT,&nRightImageLayout))
  929. AfxThrowUserException();
  930. if(nRightImageLayout==IL_VERTICAL)
  931. m_fIsRightImageHorLayout = FALSE;
  932. else
  933. m_fIsRightImageHorLayout = TRUE;
  934. if(!tm.GetThemeMargins(SPNP_UPHORZ,0,TMT_SIZINGMARGINS,&m_mrgnRight))
  935. AfxThrowUserException();
  936. }
  937. {
  938. // glyph color
  939. int nGlyphType;
  940. if(!tm.GetThemeEnumValue(SPNP_DOWNHORZ,0,TMT_GLYPHTYPE,&nGlyphType))
  941. AfxThrowUserException();
  942. if(nGlyphType==GT_IMAGEGLYPH)
  943. {
  944. COLORREF rgbTransGlyph = RGB(255,0,255);
  945. if(!tm.GetThemeColor(SPNP_DOWNHORZ,0,TMT_GLYPHTRANSPARENTCOLOR,&rgbTransGlyph))
  946. AfxThrowUserException();
  947. WCHAR szSpinGlyphIconFilename[MAX_PATH];
  948. if(!tm.GetThemeFilename(SPNP_DOWNHORZ,0,TMT_GLYPHIMAGEFILE,szSpinGlyphIconFilename,MAX_PATH))
  949. AfxThrowUserException();
  950. if(!(hBmpGlyph = tm.LoadBitmap(szSpinGlyphIconFilename)))
  951. AfxThrowUserException();
  952. CBitmap* pBmp = CBitmap::FromHandle(hBmpGlyph);
  953. if(pBmp==NULL)
  954. AfxThrowUserException();
  955. pOldBmpGlyph = dcGlyph.SelectObject(pBmp);
  956. BITMAP bm;
  957. pBmp->GetBitmap(&bm);
  958. m_rgbGlyph[0] = rgbTransGlyph;
  959. m_rgbGlyph[1] = rgbTransGlyph;
  960. m_rgbGlyph[2] = rgbTransGlyph;
  961. m_rgbGlyph[3] = rgbTransGlyph;
  962. if(m_fIsLeftImageHorLayout)
  963. {
  964. for(int i=0;i<bm.bmWidth;i++)
  965. {
  966. if(i<bm.bmWidth/4 && m_rgbGlyph[0]==rgbTransGlyph)
  967. {
  968. for(int j=0;j<bm.bmHeight;j++)
  969. {
  970. if((m_rgbGlyph[0]=dcGlyph.GetPixel(i,j))!=rgbTransGlyph)
  971. break;
  972. }
  973. if(i==bm.bmWidth/4-1 && m_rgbGlyph[0]==rgbTransGlyph)
  974. AfxThrowUserException();
  975. }
  976. else if(i>=bm.bmWidth/4 && i<bm.bmWidth/2 && m_rgbGlyph[1]==rgbTransGlyph)
  977. {
  978. for(int j=0;j<bm.bmHeight;j++)
  979. {
  980. if((m_rgbGlyph[1]=dcGlyph.GetPixel(i,j))!=rgbTransGlyph)
  981. break;
  982. }
  983. if(i==bm.bmWidth/2-1 && m_rgbGlyph[1]==rgbTransGlyph)
  984. AfxThrowUserException();
  985. }
  986. else if(i>=bm.bmWidth/2 && i<3*bm.bmWidth/4 && m_rgbGlyph[2]==rgbTransGlyph)
  987. {
  988. for(int j=0;j<bm.bmHeight;j++)
  989. {
  990. if((m_rgbGlyph[2]=dcGlyph.GetPixel(i,j))!=rgbTransGlyph)
  991. break;
  992. }
  993. if(i==3*bm.bmWidth/4-1 && m_rgbGlyph[2]==rgbTransGlyph)
  994. AfxThrowUserException();
  995. }
  996. else if(i>=3*bm.bmWidth/4 && i<bm.bmWidth && m_rgbGlyph[3]==rgbTransGlyph)
  997. {
  998. for(int j=0;j<bm.bmHeight;j++)
  999. {
  1000. if((m_rgbGlyph[3]=dcGlyph.GetPixel(i,j))!=rgbTransGlyph)
  1001. break;
  1002. }
  1003. if(i==bm.bmWidth-1 && m_rgbGlyph[3]==rgbTransGlyph)
  1004. AfxThrowUserException();
  1005. }
  1006. }
  1007. }
  1008. else
  1009. {
  1010. for(int i=0;i<bm.bmHeight;i++)
  1011. {
  1012. if(i<bm.bmHeight/4 && m_rgbGlyph[0]==rgbTransGlyph)
  1013. {
  1014. for(int j=0;j<bm.bmWidth;j++)
  1015. {
  1016. if((m_rgbGlyph[0] = dcGlyph.GetPixel(j,i))!=rgbTransGlyph)
  1017. break;
  1018. }
  1019. if(i==bm.bmHeight/4-1 && m_rgbGlyph[0]==rgbTransGlyph)
  1020. AfxThrowUserException();
  1021. }
  1022. else if(i>=bm.bmHeight/4 && i<bm.bmHeight/2 && m_rgbGlyph[1]==rgbTransGlyph)
  1023. {
  1024. for(int j=0;j<bm.bmWidth;j++)
  1025. {
  1026. if((m_rgbGlyph[1]=dcGlyph.GetPixel(j,i))!=rgbTransGlyph)
  1027. break;
  1028. }
  1029. if(i==bm.bmHeight/2-1 && m_rgbGlyph[1]==rgbTransGlyph)
  1030. AfxThrowUserException();
  1031. }
  1032. else if(i>=bm.bmHeight/2 && i<3*bm.bmHeight/4 && m_rgbGlyph[2]==rgbTransGlyph)
  1033. {
  1034. for(int j=0;j<bm.bmWidth;j++)
  1035. {
  1036. if((m_rgbGlyph[2] = dcGlyph.GetPixel(j,i))!=rgbTransGlyph)
  1037. break;
  1038. }
  1039. if(i==3*bm.bmHeight/4-1 && m_rgbGlyph[2]==rgbTransGlyph)
  1040. AfxThrowUserException();
  1041. }
  1042. else if(i>=3*bm.bmHeight/4 && i<bm.bmHeight && m_rgbGlyph[3]==rgbTransGlyph)
  1043. {
  1044. for(int j=0;j<bm.bmWidth;j++)
  1045. {
  1046. if((m_rgbGlyph[3]=dcGlyph.GetPixel(j,i))!=rgbTransGlyph)
  1047. break;
  1048. }
  1049. if(i==bm.bmHeight-1 && m_rgbGlyph[3]==rgbTransGlyph)
  1050. AfxThrowUserException();
  1051. }
  1052. }
  1053. }
  1054. dcGlyph.SelectObject(pOldBmpGlyph);
  1055. pOldBmpGlyph = NULL;
  1056. ::DeleteObject(hBmpGlyph);
  1057. hBmpGlyph = NULL;
  1058. }
  1059. else if(nGlyphType==GT_FONTGLYPH)
  1060. {
  1061. if(!tm.GetThemeColor(SPNP_UPHORZ,UPHZS_NORMAL,TMT_GLYPHTEXTCOLOR,&m_rgbGlyph[0]))
  1062. AfxThrowUserException();
  1063. if(!tm.GetThemeColor(SPNP_UPHORZ,UPHZS_HOT,TMT_GLYPHTEXTCOLOR,&m_rgbGlyph[1]))
  1064. AfxThrowUserException();
  1065. if(!tm.GetThemeColor(SPNP_UPHORZ,UPHZS_PRESSED,TMT_GLYPHTEXTCOLOR,&m_rgbGlyph[2]))
  1066. AfxThrowUserException();
  1067. }
  1068. else
  1069. AfxThrowUserException();
  1070. }
  1071. }
  1072. catch(CUserException* e)
  1073. {
  1074. e->Delete();
  1075. ::DeleteObject(m_hBmpBkLeftSpin);
  1076. m_hBmpBkLeftSpin = NULL;
  1077. ::DeleteObject(m_hBmpBkRightSpin);
  1078. m_hBmpBkRightSpin = NULL;
  1079. if(pOldBmpGlyph)
  1080. dcGlyph.SelectObject(pOldBmpGlyph);
  1081. ::DeleteObject(hBmpGlyph);
  1082. hBmpGlyph = NULL;
  1083. }
  1084. return 0;
  1085. }
  1086. void CCustomTabCtrl::OnTimer(UINT nIDEvent) 
  1087. {
  1088. CWnd::OnTimer(nIDEvent);
  1089. if(nIDEvent==1)
  1090. {
  1091. if(m_nFirstState==BNST_PRESSED && ::GetTickCount()-m_dwLastRepeatTime>=REPEAT_TIMEOUT)
  1092. {
  1093. m_nFirstState = BNST_PRESSED;
  1094. RecalcLayout(RECALC_FIRST_PRESSED,m_nItemSelected);
  1095. Invalidate(FALSE);
  1096. m_dwLastRepeatTime = ::GetTickCount();
  1097. return;
  1098. }
  1099. if(m_nPrevState==BNST_PRESSED && ::GetTickCount()-m_dwLastRepeatTime>=REPEAT_TIMEOUT)
  1100. {
  1101. m_nPrevState = BNST_PRESSED;
  1102. RecalcLayout(RECALC_PREV_PRESSED,m_nItemSelected);
  1103. Invalidate(FALSE);
  1104. m_dwLastRepeatTime = ::GetTickCount();
  1105. return;
  1106. }
  1107. if(m_nNextState==BNST_PRESSED && ::GetTickCount()-m_dwLastRepeatTime>=REPEAT_TIMEOUT)
  1108. {
  1109. m_nNextState = BNST_PRESSED;
  1110. RecalcLayout(RECALC_NEXT_PRESSED,m_nItemSelected);
  1111. Invalidate(FALSE);
  1112. m_dwLastRepeatTime = ::GetTickCount();
  1113. return;
  1114. }
  1115. if(m_nLastState==BNST_PRESSED && ::GetTickCount()-m_dwLastRepeatTime>=REPEAT_TIMEOUT)
  1116. {
  1117. m_nLastState = BNST_PRESSED;
  1118. RecalcLayout(RECALC_LAST_PRESSED,m_nItemSelected);
  1119. Invalidate(FALSE);
  1120. m_dwLastRepeatTime = ::GetTickCount();
  1121. return;
  1122. }
  1123. }
  1124. else if(nIDEvent==2)
  1125. {
  1126. KillTimer(2);
  1127. if(m_nButtonIDDown>=0)
  1128. {
  1129. SetTimer(2,10,NULL);
  1130. DWORD dwStyle = GetStyle();
  1131. if((dwStyle&CTCS_DRAGCOPY) && (GetKeyState(VK_CONTROL)&0x8000))
  1132. SetCursor(m_hCursorCopy);
  1133. else if((dwStyle&CTCS_DRAGMOVE) && !(GetKeyState(VK_CONTROL)&0x8000))
  1134. SetCursor(m_hCursorMove);
  1135. else
  1136. {
  1137. m_nButtonIDDown = CTCID_NOBUTTON;
  1138. ReleaseCapture();
  1139. }
  1140. Invalidate(FALSE);
  1141. }
  1142. }
  1143. }
  1144. void CCustomTabCtrl::SetControlFont(const LOGFONT& lf, BOOL fRedraw)
  1145. {
  1146. if(m_Font.m_hObject)
  1147. {
  1148. DeleteObject(m_Font);
  1149. m_Font.m_hObject = NULL;
  1150. }
  1151. if(m_FontSelected.m_hObject)
  1152. {
  1153. DeleteObject(m_FontSelected);
  1154. m_FontSelected.m_hObject = NULL;
  1155. }
  1156. if(!m_Font.CreateFontIndirect(&lf))
  1157. m_Font.CreateFontIndirect(&lf_default);
  1158. LOGFONT lfSel;
  1159. m_Font.GetLogFont(&lfSel);
  1160. lfSel.lfWeight = FW_BOLD;
  1161. m_FontSelected.CreateFontIndirect(&lfSel);
  1162. if(fRedraw)
  1163. {
  1164. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1165. Invalidate();
  1166. }
  1167. }
  1168. int CCustomTabCtrl::InsertItem(int nItem, CString sText,CWnd* childwnd)///*PARAM*/lParam)
  1169. {
  1170. if(nItem<0 || nItem>m_aItems.GetSize())
  1171. return CTCERR_INDEXOUTOFRANGE;
  1172. if(sText.GetLength()>MAX_LABEL_TEXT-1)
  1173. return CTCERR_TEXTTOOLONG;
  1174.    if(childwnd)
  1175.      childwnd->MoveWindow(0,0,0,0);
  1176. CCustomTabCtrlItem* pItem = new CCustomTabCtrlItem(sText,childwnd);//lParam);
  1177. if(pItem==NULL)
  1178. return CTCERR_OUTOFMEMORY;
  1179. try
  1180. {
  1181. m_aItems.InsertAt(nItem,pItem);
  1182. }
  1183. catch(CMemoryException* e)
  1184. {
  1185. e->Delete();
  1186. delete pItem;
  1187. return CTCERR_OUTOFMEMORY;
  1188. }
  1189. if(m_nItemSelected>=nItem)
  1190. m_nItemSelected++;
  1191. if(m_ctrlToolTip.m_hWnd)
  1192. {
  1193. for(INT_PTR i=m_aItems.GetSize()-1; i>nItem; i--)
  1194. {
  1195. CString s;
  1196. m_ctrlToolTip.GetText(s,this,i);
  1197. m_ctrlToolTip.DelTool(this,i);
  1198. m_ctrlToolTip.AddTool(this,s,CRect(0,0,0,0),i+1);
  1199. }
  1200. m_ctrlToolTip.DelTool(this,nItem+1);
  1201. }
  1202. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1203. Invalidate(FALSE);
  1204.    return nItem;
  1205. }
  1206. CWnd* CCustomTabCtrl::InsertItem(int nItem,CString sText,CRuntimeClass* pViewClass)
  1207. {
  1208. if(nItem<0 || nItem>m_aItems.GetSize())
  1209. return NULL;//CTCERR_INDEXOUTOFRANGE;
  1210. if(sText.GetLength()>MAX_LABEL_TEXT-1)
  1211. return NULL;//CTCERR_TEXTTOOLONG;
  1212. if(!pViewClass) return NULL;
  1213. CWnd* pWnd = NULL;
  1214. TRY
  1215. {
  1216. // Create the object.
  1217. pWnd = DYNAMIC_DOWNCAST(CWnd, pViewClass->CreateObject());
  1218. if (!pWnd) AfxThrowMemoryException();
  1219. }
  1220. CATCH_ALL(e)
  1221. {
  1222. AfxMessageBox("建立视图时内存越界!" );
  1223. // Note: DELETE_EXCEPTION(e) not required
  1224. return NULL;//FALSE;
  1225. }
  1226. END_CATCH_ALL
  1227. if(!pWnd) AfxMessageBox(_T("the window is null!"));
  1228. ASSERT_KINDOF(CWnd, pWnd);
  1229. ASSERT(pWnd->m_hWnd == NULL); // not yet created.
  1230.     if(m_nItemSelected>=nItem)
  1231. m_nItemSelected++;
  1232. // Create with the right size and position
  1233. if (!pWnd->Create(NULL, NULL, WS_CHILD|WS_VISIBLE|WS_BORDER,
  1234. CRect(0,0,0,0),GetParent(),nItem))//m_rClient
  1235. {
  1236. AfxMessageBox("fail!");
  1237. // pWnd will be cleaned up by PostNcDestroy
  1238. return NULL;
  1239. }
  1240. pWnd->ShowWindow(SW_SHOW);
  1241. CCustomTabCtrlItem* pItem = new CCustomTabCtrlItem(sText,pWnd);//lParam);
  1242. pItem->m_wType=WND_TYPE_HTMLVIEW;
  1243. if(pItem==NULL)
  1244. {
  1245.    AfxMessageBox("建立TAB控件项失败!");
  1246. return NULL;//CTCERR_OUTOFMEMORY;
  1247. }
  1248. try
  1249. {
  1250. m_aItems.InsertAt(nItem,pItem);
  1251. }
  1252. catch(CMemoryException* e)
  1253. {
  1254. e->Delete();
  1255. delete pItem;
  1256. return NULL;//CTCERR_OUTOFMEMORY;
  1257. }
  1258. if(m_nItemSelected>=nItem)
  1259. m_nItemSelected++;
  1260. if(m_ctrlToolTip.m_hWnd)
  1261. {
  1262. for(INT_PTR i=m_aItems.GetSize()-1; i>nItem; i--)
  1263. {
  1264. CString s;
  1265. m_ctrlToolTip.GetText(s,this,i);
  1266. m_ctrlToolTip.DelTool(this,i);
  1267. m_ctrlToolTip.AddTool(this,s,CRect(0,0,0,0),i+1);
  1268. }
  1269. m_ctrlToolTip.DelTool(this,nItem+1);
  1270. }
  1271. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1272. Invalidate(FALSE);
  1273. ModifyStyle(0,CTCS_TOOLTIPS,0);
  1274. CString infstr;
  1275. infstr.Format("窗口序列:%d,按下右键删除!",nItem);
  1276. SetItemTooltipText(nItem,infstr);
  1277. return pWnd;
  1278. }
  1279. //移除一项
  1280. int CCustomTabCtrl::MoveItem(int nItemSrc, int nItemDst)
  1281. {
  1282. return MoveItem(nItemSrc, nItemDst, FALSE);
  1283. }
  1284. int CCustomTabCtrl::MoveItem(int nItemSrc, int nItemDst, BOOL fMouseSel)
  1285. {
  1286. if(nItemSrc<0||nItemSrc>=m_aItems.GetSize())
  1287. return CTCERR_INDEXOUTOFRANGE;
  1288. if(nItemDst<0||nItemDst>m_aItems.GetSize())
  1289. return CTCERR_INDEXOUTOFRANGE;
  1290. if(nItemSrc==nItemDst || nItemSrc==nItemDst-1)
  1291. return nItemSrc;
  1292. CCustomTabCtrlItem *pItem = m_aItems[nItemSrc];
  1293. // remove item from old place
  1294. CString sOldTooltip;
  1295. if(m_ctrlToolTip.m_hWnd)
  1296. {
  1297. m_ctrlToolTip.GetText(sOldTooltip,this,nItemSrc+1);
  1298. for(int i=nItemSrc+1; i< m_aItems.GetSize(); i++)
  1299. {
  1300. CString s;
  1301. m_ctrlToolTip.GetText(s,this,i+1);
  1302. m_ctrlToolTip.DelTool(this,i);
  1303. m_ctrlToolTip.AddTool(this,s,CRect(0,0,0,0),i);
  1304. }
  1305. }
  1306. m_aItems.RemoveAt(nItemSrc);
  1307. // insert item in new place
  1308. if(nItemDst>nItemSrc)
  1309. nItemDst--;
  1310. try
  1311. {
  1312. m_aItems.InsertAt(nItemDst,pItem);
  1313. }
  1314. catch(CMemoryException* e)
  1315. {
  1316. e->Delete();
  1317. delete pItem;
  1318. if(fMouseSel)
  1319. NotifyParent(CTCN_ITEMMOVE,nItemSrc,CPoint(0,0));
  1320. return CTCERR_OUTOFMEMORY;
  1321. }
  1322. if(m_ctrlToolTip.m_hWnd)
  1323. {
  1324. for(int i=(int)m_aItems.GetSize()-1; i>nItemDst; i--)
  1325. {
  1326. CString s;
  1327. m_ctrlToolTip.GetText(s,this,i);
  1328. m_ctrlToolTip.DelTool(this,i+1);
  1329. m_ctrlToolTip.AddTool(this,s,CRect(0,0,0,0),i+1);
  1330. }
  1331. m_ctrlToolTip.DelTool(this,nItemDst+1);
  1332. m_ctrlToolTip.AddTool(this,sOldTooltip,CRect(0,0,0,0),nItemDst+1);
  1333. }
  1334. m_nItemSelected = nItemDst;
  1335. RecalcLayout(RECALC_ITEM_SELECTED,m_nItemSelected);
  1336. Invalidate(FALSE);
  1337. if(fMouseSel)
  1338. NotifyParent(CTCN_ITEMMOVE,m_nItemSelected,CPoint(0,0));
  1339. return nItemDst;
  1340. }
  1341. int CCustomTabCtrl::CopyItem(int nItemSrc, int nItemDst)
  1342. {
  1343. return CopyItem(nItemSrc, nItemDst, FALSE);
  1344. }
  1345. int CCustomTabCtrl::CopyItem(int nItemSrc, int nItemDst, BOOL fMouseSel)
  1346. {
  1347. if(nItemSrc<0||nItemSrc>=m_aItems.GetSize())
  1348. return CTCERR_INDEXOUTOFRANGE;
  1349. if(nItemDst<0||nItemDst>m_aItems.GetSize())
  1350. return CTCERR_INDEXOUTOFRANGE;
  1351. CString sDst;
  1352. try
  1353. {
  1354. BOOL bAppendFlag=TRUE;
  1355. int n = m_aItems[nItemSrc]->m_sText.GetLength();
  1356. if(n>=4)
  1357. {
  1358. if(m_aItems[nItemSrc]->m_sText[n-1]==_T(')') && 
  1359. m_aItems[nItemSrc]->m_sText[n-2]>_T('1') &&
  1360. m_aItems[nItemSrc]->m_sText[n-2]<=_T('9') &&
  1361. m_aItems[nItemSrc]->m_sText[n-3]==_T('('))
  1362. {
  1363. n = m_aItems[nItemSrc]->m_sText.GetLength()-3;
  1364. bAppendFlag = FALSE;
  1365. }
  1366. else if(m_aItems[nItemSrc]->m_sText[n-1]==_T(')') && 
  1367. m_aItems[nItemSrc]->m_sText[n-2]>=_T('0') &&
  1368. m_aItems[nItemSrc]->m_sText[n-2]<=_T('9') &&
  1369. m_aItems[nItemSrc]->m_sText[n-3]>=_T('1') &&
  1370. m_aItems[nItemSrc]->m_sText[n-3]<=_T('9') &&
  1371. m_aItems[nItemSrc]->m_sText[n-4]==_T('('))
  1372. {
  1373. n = m_aItems[nItemSrc]->m_sText.GetLength()-4;
  1374. bAppendFlag = FALSE;
  1375. }
  1376. }
  1377. int ndx = 1;
  1378. while(1)
  1379. {
  1380. ndx++;
  1381. if(bAppendFlag)
  1382. sDst.Format(_T("%s (%d)"),(LPCTSTR)m_aItems[nItemSrc]->m_sText,ndx);
  1383. else
  1384. sDst.Format(_T("%s(%d)"),(LPCTSTR)m_aItems[nItemSrc]->m_sText.Left(n),ndx);
  1385. for(int i=0;i<m_aItems.GetSize();i++)
  1386. {
  1387. if(m_aItems[i]->m_sText==sDst)
  1388. break;
  1389. }
  1390. if(i==m_aItems.GetSize())
  1391. break;
  1392. }
  1393. }
  1394. catch(CMemoryException* e)
  1395. {
  1396. e->Delete();
  1397. if(fMouseSel)
  1398. NotifyParent(CTCN_OUTOFMEMORY,nItemSrc,CPoint(0,0));
  1399. return CTCERR_OUTOFMEMORY;
  1400. }
  1401. int nRetItem = InsertItem(nItemDst,sDst,m_aItems[nItemSrc]->m_lParam);
  1402. if(nRetItem>=0)
  1403. {
  1404. SetCurSel(nRetItem);
  1405. if(fMouseSel)
  1406. NotifyParent(CTCN_ITEMCOPY,nRetItem,CPoint(0,0));
  1407. }
  1408. else if(fMouseSel && nRetItem==CTCERR_OUTOFMEMORY)
  1409. NotifyParent(CTCN_OUTOFMEMORY,nRetItem,CPoint(0,0));
  1410. return nRetItem;
  1411. }
  1412. int CCustomTabCtrl::DeleteItem(int nItem)
  1413. {
  1414. if(nItem<0 || nItem>=m_aItems.GetSize())
  1415. return CTCERR_INDEXOUTOFRANGE;
  1416.    try
  1417. {
  1418. if(m_ctrlToolTip.m_hWnd)
  1419. {
  1420. for(int i=nItem+1; i< m_aItems.GetSize(); i++)
  1421. {
  1422. CString s;
  1423. m_ctrlToolTip.GetText(s,this,i+1);
  1424. m_ctrlToolTip.DelTool(this,i);
  1425. m_ctrlToolTip.AddTool(this,s,CRect(0,0,0,0),i);
  1426. }
  1427. }
  1428. }
  1429. catch(CMemoryException* e)
  1430. {
  1431. e->Delete();
  1432. return CTCERR_OUTOFMEMORY;
  1433. }
  1434. if(m_aItems.GetSize()==1)
  1435.    m_nItemSelected = -1;
  1436. else if(m_nItemSelected==nItem)
  1437.   {
  1438. if(m_nItemSelected==m_aItems.GetSize()-1) // last item
  1439. {
  1440.   m_nItemSelected--;
  1441.   m_aItems[m_nItemSelected]->m_fSelected = TRUE;
  1442. }
  1443. else
  1444.   m_aItems[m_nItemSelected+1]->m_fSelected = TRUE;
  1445.   }
  1446.   else if(m_nItemSelected>nItem)
  1447.  m_nItemSelected--;
  1448.   //if(m_nItemSelected>=0)
  1449. //   SetCurSel(m_nItemSelected);
  1450. //else
  1451. CCustomTabCtrlItem* pItem =(CCustomTabCtrlItem*)m_aItems.GetAt(nItem);
  1452. pItem->m_lParam->SendMessage(WM_QUIT);
  1453. delete pItem->m_lParam;
  1454.     delete m_aItems[nItem];
  1455. m_aItems.RemoveAt(nItem);
  1456. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1457. Invalidate(FALSE);
  1458. m_oldwnd=NULL;
  1459. if(m_nItemSelected>=0)
  1460. {
  1461.    SwitchWindows(DYNAMIC_DOWNCAST( CView, m_aItems[m_nItemSelected]->m_lParam));
  1462.    m_oldwnd=m_aItems[m_nItemSelected]->m_lParam;
  1463. }
  1464. //if(m_aItems.GetSize()==1)
  1465. //   SetCurSel(0);
  1466. return CTCERR_NOERROR;
  1467. }
  1468. void CCustomTabCtrl::DeleteAllItems()
  1469. {
  1470. if(m_ctrlToolTip.m_hWnd)
  1471. {
  1472. for(int i=0; i< m_aItems.GetSize(); i++)
  1473. {
  1474. CCustomTabCtrlItem* pItem =(CCustomTabCtrlItem*)m_aItems.GetAt(i);
  1475. delete pItem->m_lParam;
  1476. delete m_aItems[i];
  1477. m_ctrlToolTip.DelTool(this,i+1);
  1478. }
  1479. }
  1480. else
  1481. {
  1482. for(int i=0; i< m_aItems.GetSize(); i++)
  1483. {
  1484. CCustomTabCtrlItem* pItem =(CCustomTabCtrlItem*)m_aItems.GetAt(i);
  1485. delete pItem->m_lParam;
  1486. delete m_aItems[i];
  1487. }
  1488. }
  1489. m_aItems.RemoveAll();
  1490. m_nItemSelected = -1;
  1491. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1492. Invalidate(FALSE);
  1493. }
  1494. int CCustomTabCtrl::SetCurSel(int nItem)
  1495. {
  1496. return SetCurSel(nItem,FALSE,FALSE);
  1497. }
  1498. int CCustomTabCtrl::HighlightItem(int nItem, BOOL fHighlight)
  1499. {
  1500. if(!(GetStyle()&CTCS_MULTIHIGHLIGHT))
  1501. return CTCERR_NOMULTIHIGHLIGHTSTYLE;
  1502. if(nItem<0 || nItem>=m_aItems.GetSize())
  1503. return CTCERR_INDEXOUTOFRANGE;
  1504. if(m_nItemSelected==-1 && !fHighlight)
  1505. return CTCERR_NOERROR;
  1506. if(m_nItemSelected==-1)
  1507. {
  1508. SetCurSel(nItem);
  1509. return CTCERR_NOERROR;
  1510. }
  1511. if(fHighlight==m_aItems[nItem]->m_fHighlighted || nItem==m_nItemSelected)
  1512. return CTCERR_NOERROR;
  1513. m_aItems[nItem]->m_fHighlighted = fHighlight;
  1514. return CTCERR_NOERROR;
  1515. }
  1516. int CCustomTabCtrl::GetItemText(int nItem, CString& sText)
  1517. {
  1518. if(nItem<0 || nItem>=m_aItems.GetSize())
  1519. return CTCERR_INDEXOUTOFRANGE;
  1520. sText = m_aItems[nItem]->m_sText;
  1521. return CTCERR_NOERROR;
  1522. }
  1523. int CCustomTabCtrl::SetItemText(int nItem, CString sText)
  1524. {
  1525. if(nItem<0 || nItem>=m_aItems.GetSize())
  1526. return CTCERR_INDEXOUTOFRANGE;
  1527. m_aItems[nItem]->m_sText = sText;
  1528. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1529. Invalidate(FALSE);
  1530. return CTCERR_NOERROR;
  1531. }
  1532. int CCustomTabCtrl::SetItemTooltipText(int nItem, CString sText)
  1533. {
  1534. if(!(GetStyle()&CTCS_TOOLTIPS))
  1535. return CTCERR_NOTOOLTIPSSTYLE;
  1536. if(nItem>=CTCID_LASTBUTTON && nItem<m_aItems.GetSize())
  1537. {
  1538. if(m_ctrlToolTip.m_hWnd==NULL)
  1539. {
  1540. if(!m_ctrlToolTip.Create(this))
  1541. return CTCERR_CREATETOOLTIPFAILED;
  1542. m_ctrlToolTip.Activate(TRUE);
  1543. }
  1544. if(nItem>=0)
  1545. nItem++;
  1546. m_ctrlToolTip.DelTool(this,nItem);
  1547. m_ctrlToolTip.AddTool(this,sText,CRect(0,0,0,0),nItem);
  1548. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1549. Invalidate(FALSE);
  1550. return CTCERR_NOERROR;
  1551. }
  1552. return CTCERR_INDEXOUTOFRANGE;
  1553. }
  1554. /*int CCustomTabCtrl::GetItemData(int nItem, DWORD& dwData)
  1555. {
  1556. if(nItem<0 || nItem>=m_aItems.GetSize())
  1557. return CTCERR_INDEXOUTOFRANGE;
  1558. dwData = m_aItems[nItem]->m_lParam;
  1559. return CTCERR_NOERROR;
  1560. }*/
  1561. int CCustomTabCtrl::GetItemRect(int nItem, CRect& rect) const
  1562. {
  1563. if(nItem<0 || nItem>=m_aItems.GetSize())
  1564. return CTCERR_INDEXOUTOFRANGE;
  1565. rect = m_aItems[nItem]->m_rectText;
  1566. return CTCERR_NOERROR;
  1567. }
  1568. /*int CCustomTabCtrl::SetItemData(int nItem, DWORD dwData)
  1569. {
  1570. if(nItem<0 || nItem>=m_aItems.GetSize())
  1571. return CTCERR_INDEXOUTOFRANGE;
  1572. m_aItems[nItem]->m_lParam = dwData;
  1573. return CTCERR_NOERROR;
  1574. }*/
  1575. int CCustomTabCtrl::IsItemHighlighted(int nItem)
  1576. {
  1577. if(nItem<0 || nItem>=m_aItems.GetSize())
  1578. return CTCERR_INDEXOUTOFRANGE;
  1579. return (m_aItems[nItem]->m_fHighlighted)?1:0;
  1580. }
  1581. //测试用户按下了哪一个键
  1582. int CCustomTabCtrl::HitTest(CPoint pt)
  1583. {
  1584. CRect rCl;
  1585. GetClientRect(&rCl);
  1586. int nBtns = 2;
  1587. if(GetStyle()&CTCS_FOURBUTTONS)
  1588. nBtns = 4;
  1589. int nA = rCl.Height()-3;
  1590. CRect rFirst,rPrev,rNext,rLast;
  1591. if(nBtns==2)
  1592. {
  1593. rPrev.SetRect(0,0,nA+1,rCl.Height());
  1594. rNext.SetRect(nA+1,0,2*nA+3,rCl.Height());
  1595. }
  1596. else
  1597. {
  1598. rFirst.SetRect(0,0,nA+1,rCl.Height());
  1599. rPrev.SetRect(nA+1,0,2*nA+1,rCl.Height());
  1600. rNext.SetRect(2*nA+1,0,3*nA+2,rCl.Height());
  1601. rLast.SetRect(3*nA+2,0,4*nA+3,rCl.Height());
  1602. }
  1603. if(nBtns==4 && m_nFirstState && rFirst.PtInRect(pt))
  1604. return CTCHT_ONFIRSTBUTTON;
  1605. if(m_nPrevState && rPrev.PtInRect(pt))
  1606. return CTCHT_ONPREVBUTTON;
  1607. if(m_nNextState && rNext.PtInRect(pt))
  1608. return CTCHT_ONNEXTBUTTON;
  1609. if(nBtns==4 && m_nLastState && rLast.PtInRect(pt))
  1610. return CTCHT_ONLASTBUTTON;
  1611. for(int i=0; i<m_aItems.GetSize(); i++)
  1612. {
  1613. if(m_aItems[i]->HitTest(pt))
  1614. return i;
  1615. }
  1616. return CTCHT_NOWHERE;
  1617. }
  1618. int CCustomTabCtrl::HighlightItem(int nItem, BOOL fMouseSel, BOOL fCtrlPressed)
  1619. {
  1620. if(!(GetStyle()&CTCS_MULTIHIGHLIGHT))
  1621. return CTCERR_NOMULTIHIGHLIGHTSTYLE;
  1622. for(int i=0; i<m_aItems.GetSize();i++)
  1623. m_aItems[i]->m_fHighlightChanged = FALSE;
  1624. if(fCtrlPressed)
  1625. {
  1626. if(nItem!=m_nItemSelected)
  1627. {
  1628. m_aItems[nItem]->m_fHighlighted = !m_aItems[nItem]->m_fHighlighted;
  1629. if(fMouseSel)
  1630. m_aItems[nItem]->m_fHighlightChanged = TRUE;
  1631. }
  1632. }
  1633. else if(!m_aItems[nItem]->m_fHighlighted)
  1634. {
  1635. m_aItems[nItem]->m_fHighlighted = TRUE;
  1636. m_aItems[nItem]->m_fHighlightChanged = TRUE;
  1637. for(int i=0;i<m_aItems.GetSize();i++)
  1638. {
  1639. if(i!=m_nItemSelected)
  1640. {
  1641. if(m_aItems[i]->m_fHighlighted)
  1642. {
  1643. m_aItems[i]->m_fHighlighted = FALSE;
  1644. if(fMouseSel)
  1645. m_aItems[i]->m_fHighlightChanged = TRUE;
  1646. }
  1647. }
  1648. }
  1649. }
  1650. if(fMouseSel)
  1651. RecalcLayout(RECALC_ITEM_SELECTED,nItem);
  1652. Invalidate(FALSE);
  1653. return CTCERR_NOERROR;
  1654. }
  1655. int CCustomTabCtrl::SetCurSel(int nItem, BOOL fMouseSel, BOOL fCtrlPressed)
  1656. {
  1657. if(nItem<0 || nItem>=m_aItems.GetSize())
  1658. return CTCERR_INDEXOUTOFRANGE;
  1659. if(m_nItemSelected!=-1)
  1660. m_aItems[m_nItemSelected]->m_fSelected = FALSE;
  1661. m_nItemSelected = nItem;
  1662. if(m_nItemSelected!=-1)
  1663. m_aItems[m_nItemSelected]->m_fSelected = TRUE;
  1664. if(fMouseSel)
  1665. RecalcLayout(RECALC_ITEM_SELECTED,m_nItemSelected);
  1666. else
  1667. {
  1668. m_nItemNdxOffset = nItem;
  1669. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  1670. }
  1671. Invalidate(FALSE);
  1672. HighlightItem(nItem, fMouseSel, fCtrlPressed);
  1673. if(m_aItems[nItem]->m_lParam!=m_oldwnd || m_oldwnd!=NULL)
  1674. {
  1675.   SwitchWindows(DYNAMIC_DOWNCAST( CView, m_aItems[nItem]->m_lParam));
  1676.       m_oldwnd=m_aItems[nItem]->m_lParam;
  1677.   if(m_aItems[nItem]->m_wType==WND_TYPE_HTMLVIEW && !m_aItems[nItem]->m_OpenURL )
  1678.   {
  1679.   ((CIEView*)m_oldwnd)->Navigate(m_aItems[nItem]->m_sText);
  1680.   m_aItems[nItem]->m_OpenURL=TRUE;
  1681.   }
  1682. }
  1683. return CTCERR_NOERROR;
  1684. }
  1685. //重新调整窗口状态
  1686. void CCustomTabCtrl::RecalcLayout(int nRecalcType, int nItem)
  1687. {
  1688. CRect rCl;
  1689. GetClientRect(&rCl);
  1690. {
  1691. int nBtns = 2;
  1692. if(GetStyle()&CTCS_FOURBUTTONS)
  1693. nBtns = 4;
  1694. int nWidth = RecalcRectangles();
  1695. if((GetStyle()&CTCS_AUTOHIDEBUTTONS) && (m_aItems.GetSize()<2 || nWidth <= rCl.Width()))
  1696. {
  1697. m_nFirstState = BNST_INVISIBLE;
  1698. m_nPrevState = BNST_INVISIBLE;
  1699. m_nNextState = BNST_INVISIBLE;
  1700. m_nLastState = BNST_INVISIBLE;
  1701. m_nItemNdxOffset = 0;
  1702. RecalcOffset(0);
  1703. //if(nRecalcType==RECALC_EDIT_RESIZED)
  1704. // RecalcEditResized(0,nItem);
  1705. if(m_ctrlToolTip.m_hWnd)
  1706. {
  1707. m_ctrlToolTip.SetToolRect(this,CTCID_FIRSTBUTTON,CRect(0,0,0,0));
  1708. m_ctrlToolTip.SetToolRect(this,CTCID_PREVBUTTON,CRect(0,0,0,0));
  1709. m_ctrlToolTip.SetToolRect(this,CTCID_NEXTBUTTON,CRect(0,0,0,0));
  1710. m_ctrlToolTip.SetToolRect(this,CTCID_LASTBUTTON,CRect(0,0,0,0));
  1711. }
  1712. return;
  1713. }
  1714. if(m_ctrlToolTip.m_hWnd)
  1715. {
  1716. int nA = rCl.Height()-3;
  1717. if(nBtns == 2)
  1718. {
  1719. m_ctrlToolTip.SetToolRect(this,CTCID_FIRSTBUTTON,CRect(0,0,0,0));
  1720. m_ctrlToolTip.SetToolRect(this,CTCID_PREVBUTTON,CRect(0,0,nA+1,rCl.Height()));
  1721. m_ctrlToolTip.SetToolRect(this,CTCID_NEXTBUTTON,CRect(nA+1,0,2*nA+3,rCl.Height()));
  1722. m_ctrlToolTip.SetToolRect(this,CTCID_LASTBUTTON,CRect(0,0,0,0));
  1723. }
  1724. else
  1725. {
  1726. m_ctrlToolTip.SetToolRect(this,CTCID_FIRSTBUTTON,CRect(0,0,nA+1,rCl.Height()));
  1727. m_ctrlToolTip.SetToolRect(this,CTCID_PREVBUTTON,CRect(nA+1,0,2*nA+3,rCl.Height()));
  1728. m_ctrlToolTip.SetToolRect(this,CTCID_NEXTBUTTON,CRect(2*nA+1,0,3*nA+2,rCl.Height()));
  1729. m_ctrlToolTip.SetToolRect(this,CTCID_LASTBUTTON,CRect(3*nA+2,0,4*nA+3,rCl.Height()));
  1730. }
  1731. }
  1732. int nBnWidth = nBtns*(rCl.Height()-3)+3;
  1733. if(m_nFirstState==BNST_INVISIBLE)
  1734. m_nFirstState = BNST_NORMAL;
  1735. if(m_nPrevState==BNST_INVISIBLE)
  1736. m_nPrevState = BNST_NORMAL;
  1737. if(m_nNextState == BNST_INVISIBLE)
  1738. m_nNextState = BNST_NORMAL;
  1739. if(m_nLastState == BNST_INVISIBLE)
  1740. m_nLastState = BNST_NORMAL;
  1741. if(m_aItems.GetSize()==0)
  1742. return;
  1743. switch(nRecalcType)
  1744. {
  1745. case RECALC_FIRST_PRESSED:
  1746. {
  1747. m_nItemNdxOffset=0;
  1748. RecalcRectangles();
  1749. RecalcOffset(nBnWidth);
  1750. }
  1751. break;
  1752. case RECALC_PREV_PRESSED:
  1753. {
  1754. RecalcOffset(nBnWidth);
  1755. if(m_nItemNdxOffset>0)
  1756. {
  1757. m_nItemNdxOffset--;
  1758. RecalcRectangles();
  1759. RecalcOffset(nBnWidth);
  1760. }
  1761. }
  1762. break;
  1763. case RECALC_NEXT_PRESSED:
  1764. {
  1765. RecalcOffset(nBnWidth);
  1766. if(m_aItems[m_aItems.GetSize()-1]->m_rect.right>rCl.Width() && m_nItemNdxOffset!=m_aItems.GetSize()-1)
  1767. {
  1768. m_nItemNdxOffset++;
  1769. RecalcRectangles();
  1770. RecalcOffset(nBnWidth);
  1771. }
  1772. }
  1773. break;
  1774. case RECALC_ITEM_SELECTED:
  1775. {
  1776. RecalcOffset(nBnWidth);
  1777. if(m_aItems[nItem]->m_bShape==TAB_SHAPE2 || m_aItems[nItem]->m_bShape==TAB_SHAPE3)
  1778. {
  1779. m_nItemNdxOffset--;
  1780. RecalcRectangles();
  1781. RecalcOffset(nBnWidth);
  1782. }
  1783. else
  1784. {
  1785. while(m_nItemNdxOffset<nItem && 
  1786. m_aItems[nItem]->m_bShape==TAB_SHAPE4 && 
  1787. m_aItems[nItem]->m_rect.right>rCl.Width() && 
  1788. m_aItems[nItem]->m_rect.left>nBnWidth)
  1789. {
  1790. m_nItemNdxOffset++;
  1791. RecalcRectangles();
  1792. RecalcOffset(nBnWidth);
  1793. }
  1794. }
  1795. }
  1796. break;
  1797. // case RECALC_EDIT_RESIZED:
  1798. // {
  1799. // RecalcOffset(nBnWidth);
  1800. // RecalcEditResized(nBnWidth,nItem);
  1801. // }
  1802. // break;
  1803. case RECALC_LAST_PRESSED:
  1804. {
  1805. m_nItemNdxOffset=(int)m_aItems.GetSize()-1;
  1806. }
  1807. default: // window resized
  1808. {
  1809. BOOL bNdxOffsetChanged = FALSE;
  1810. RecalcOffset(nBnWidth);
  1811. while(m_nItemNdxOffset>=0 && m_aItems[m_aItems.GetSize()-1]->m_rect.right<rCl.Width())
  1812. {
  1813. m_nItemNdxOffset--;
  1814. if(m_nItemNdxOffset>=0)
  1815. {
  1816. RecalcRectangles();
  1817. RecalcOffset(nBnWidth);
  1818. }
  1819. bNdxOffsetChanged = TRUE;
  1820. }
  1821. if(bNdxOffsetChanged)
  1822. {
  1823. m_nItemNdxOffset++;
  1824. RecalcRectangles();
  1825. RecalcOffset(nBnWidth);
  1826. }
  1827. }
  1828. break;
  1829. }
  1830. }
  1831. }
  1832. /*void CCustomTabCtrl::RecalcEditResized(int nOffset, int nItem)
  1833. {
  1834. CRect rCl;
  1835. GetClientRect(rCl);
  1836. do
  1837. {
  1838. CRect r;
  1839. CDC* pDC = GetDC();
  1840. CFont* pOldFont = pDC->SelectObject(&m_FontSelected);
  1841. int h = pDC->DrawText(m_aItems[nItem]->m_sText+"X", r, DT_CALCRECT);
  1842. pDC->SelectObject(pOldFont);
  1843. ReleaseDC(pDC);
  1844. r = m_aItems[nItem]->m_rectText;
  1845. if(r.Height()>h)
  1846. {
  1847. r.top += (r.Height()-h)/2;
  1848. r.bottom -= (r.Height()-h)/2;
  1849. }
  1850. r.left += 2;
  1851. if(r.right>rCl.right && m_nItemSelected>m_nItemNdxOffset)
  1852. {
  1853. m_nItemNdxOffset++;
  1854. RecalcRectangles();
  1855. RecalcOffset(nOffset);
  1856. }
  1857. else
  1858. {
  1859. if(r.right>rCl.right)
  1860. r.right = rCl.right;
  1861. m_ctrlEdit.MoveWindow(r);
  1862. int n = m_aItems[nItem]->m_sText.GetLength();
  1863. int nStart, nEnd;
  1864. m_ctrlEdit.GetSel(nStart,nEnd);
  1865. if(nStart==nEnd && nStart==n)
  1866. {
  1867. m_ctrlEdit.SetSel(0,0);
  1868. m_ctrlEdit.SetSel(n,n);
  1869. }
  1870. return;
  1871. }
  1872. while(1);
  1873. }*/
  1874. void CCustomTabCtrl::RecalcOffset(int nOffset)
  1875. {
  1876. CRect rCl;
  1877. GetClientRect(&rCl);
  1878. int nBtns = 2;
  1879. if(GetStyle()&CTCS_FOURBUTTONS)
  1880. nBtns = 4;
  1881. int nBnWidth = nBtns*(rCl.Height()-3)+3;
  1882. for(int i = 0; i<m_aItems.GetSize(); i++)
  1883. {
  1884. if(i<m_nItemNdxOffset-1)
  1885. {
  1886. m_aItems[i]->m_bShape = TAB_SHAPE1;
  1887. nOffset -= m_aItems[i]->m_rect.Width()-rCl.Height()/2;
  1888. m_aItems[i]->m_rectText.SetRectEmpty();
  1889. }
  1890. else if(i==m_nItemNdxOffset-1)
  1891. {
  1892. if(i==m_nItemSelected)
  1893. m_aItems[i]->m_bShape = TAB_SHAPE2;
  1894. else
  1895. m_aItems[i]->m_bShape = TAB_SHAPE3;
  1896. nOffset -= m_aItems[i]->m_rect.Width()-rCl.Height()/2;
  1897. m_aItems[i]->m_rect.SetRect(0,1,rCl.Height()/2,rCl.Height()-1);
  1898. m_aItems[i]->m_rect.OffsetRect(nBnWidth,0);
  1899. m_aItems[i]->m_rectText.SetRectEmpty();
  1900. }
  1901. else
  1902. {
  1903. if(i==m_nItemSelected)
  1904. m_aItems[i]->m_bShape = TAB_SHAPE4;
  1905. else if(i==m_aItems.GetSize()-1) // last item
  1906. m_aItems[i]->m_bShape = TAB_SHAPE4;
  1907. else
  1908. m_aItems[i]->m_bShape = TAB_SHAPE5;
  1909. m_aItems[i]->m_rect.OffsetRect(nOffset,0);
  1910. m_aItems[i]->m_rectText.OffsetRect(nOffset,0);
  1911. }
  1912. m_aItems[i]->ComputeRgn();
  1913. if(m_ctrlToolTip.m_hWnd)
  1914. m_ctrlToolTip.SetToolRect(this,i+1,m_aItems[i]->m_rectText);
  1915. }
  1916. }
  1917. int CCustomTabCtrl::RecalcRectangles()
  1918. {
  1919. CRect rCl;
  1920. GetClientRect(&rCl);
  1921. int nWidth = 0;
  1922. {
  1923. // calculate width
  1924. int nOffset = 0;
  1925. CRect rcText;
  1926. CDC* pDC = GetDC();
  1927. CFont* pOldFont = pDC->SelectObject(&m_FontSelected);
  1928. if(GetStyle()&CTCS_FIXEDWIDTH)
  1929. {
  1930. int nMaxWidth=0;
  1931. for(int i=0; i<m_aItems.GetSize(); i++)
  1932. {
  1933. int w=0;
  1934. int h = pDC->DrawText(m_aItems[i]->m_sText, rcText, DT_CALCRECT);
  1935. if(h>0)
  1936. w = rcText.Width();
  1937. if(w>nMaxWidth)
  1938. nMaxWidth = w;
  1939. }
  1940. for(i=0; i<m_aItems.GetSize(); i++)
  1941. {
  1942. m_aItems[i]->m_rect = CRect(0,1,nMaxWidth+rCl.Height()+4,rCl.Height()-1);
  1943. m_aItems[i]->m_rect += CPoint(nOffset,0);
  1944. m_aItems[i]->m_rectText = CRect(rCl.Height()/2,1,nMaxWidth+rCl.Height()/2+4,rCl.Height()-1);
  1945. m_aItems[i]->m_rectText += CPoint(nOffset,0);
  1946. nOffset += m_aItems[i]->m_rect.Width()-rCl.Height()/2;
  1947. nWidth = m_aItems[i]->m_rect.right;
  1948. }
  1949. }
  1950. else
  1951. {
  1952. for(int i= 0; i<m_aItems.GetSize(); i++)
  1953. {
  1954. int w=0;
  1955. int h = pDC->DrawText(m_aItems[i]->m_sText, rcText, DT_CALCRECT);
  1956. if(h>0)
  1957. w = rcText.Width();
  1958. m_aItems[i]->m_rect = CRect(0,1,w+rCl.Height()+4,rCl.Height()-1);
  1959. m_aItems[i]->m_rect += CPoint(nOffset,0);
  1960. m_aItems[i]->m_rectText = CRect(rCl.Height()/2,1,w+rCl.Height()/2+4,rCl.Height()-1);
  1961. m_aItems[i]->m_rectText += CPoint(nOffset,0);
  1962. nOffset += m_aItems[i]->m_rect.Width()-rCl.Height()/2;
  1963. nWidth = m_aItems[i]->m_rect.right;
  1964. }
  1965. }
  1966. pDC->SelectObject(pOldFont);
  1967. ReleaseDC(pDC);
  1968. }
  1969. return nWidth;
  1970. }
  1971. BOOL CCustomTabCtrl::PreTranslateMessage(MSG* pMsg)
  1972. {
  1973. if(GetStyle()&CTCS_TOOLTIPS && m_ctrlToolTip.m_hWnd && 
  1974. (pMsg->message==WM_LBUTTONDOWN || pMsg->message==WM_LBUTTONUP || pMsg->message==WM_MOUSEMOVE))
  1975. m_ctrlToolTip.RelayEvent(pMsg);
  1976. return CWnd::PreTranslateMessage(pMsg);
  1977. }
  1978. void CCustomTabCtrl::DrawBkLeftSpin(CDC& dc, CRect& r, int nImageNdx)
  1979. {
  1980. CDC dcMem;
  1981. dcMem.CreateCompatibleDC(&dc);
  1982. CBitmap* pBmp = CBitmap::FromHandle(m_hBmpBkLeftSpin);
  1983. BITMAP bm;
  1984. pBmp->GetBitmap(&bm);
  1985. CBitmap* pOldBmp = dcMem.SelectObject(pBmp);
  1986. if(m_fIsLeftImageHorLayout)
  1987. {
  1988. // left-top
  1989. dc.BitBlt(r.left,
  1990. r.top,
  1991. m_mrgnLeft.cxLeftWidth,
  1992. m_mrgnLeft.cyTopHeight,
  1993. &dcMem,
  1994. nImageNdx*bm.bmWidth/4,
  1995. 0,
  1996. SRCCOPY);
  1997. // right-top
  1998. dc.BitBlt(r.right-m_mrgnLeft.cxRightWidth,
  1999. r.top,
  2000. m_mrgnLeft.cxRightWidth,
  2001. m_mrgnLeft.cyTopHeight,
  2002. &dcMem,
  2003. (nImageNdx+1)*bm.bmWidth/4-m_mrgnLeft.cxRightWidth,
  2004. 0,
  2005. SRCCOPY);
  2006. // left-bottom
  2007. dc.BitBlt(r.left,
  2008. r.bottom-m_mrgnLeft.cyBottomHeight,
  2009. m_mrgnLeft.cxLeftWidth,
  2010. m_mrgnLeft.cyBottomHeight,
  2011. &dcMem,
  2012. nImageNdx*bm.bmWidth/4,
  2013. bm.bmHeight-m_mrgnLeft.cyBottomHeight,
  2014. SRCCOPY);
  2015. // right-bottom
  2016. dc.BitBlt(r.right-m_mrgnLeft.cxRightWidth,
  2017. r.bottom-m_mrgnLeft.cyBottomHeight,
  2018. m_mrgnLeft.cxRightWidth,
  2019. m_mrgnLeft.cyBottomHeight,
  2020. &dcMem,
  2021. (nImageNdx+1)*bm.bmWidth/4-m_mrgnLeft.cxRightWidth,
  2022. bm.bmHeight-m_mrgnLeft.cyBottomHeight,
  2023. SRCCOPY);
  2024. // middle-top
  2025. dc.StretchBlt(r.left+m_mrgnLeft.cxLeftWidth,
  2026. r.top,
  2027. r.Width()-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2028. m_mrgnLeft.cyTopHeight,
  2029. &dcMem,
  2030. nImageNdx*bm.bmWidth/4+m_mrgnLeft.cxLeftWidth,
  2031. 0,
  2032. bm.bmWidth/4-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2033. m_mrgnLeft.cyTopHeight,
  2034. SRCCOPY);
  2035. // middle-bottom
  2036. dc.StretchBlt(r.left+m_mrgnLeft.cxLeftWidth,
  2037. r.bottom-m_mrgnLeft.cyBottomHeight,
  2038. r.Width()-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2039. m_mrgnLeft.cyBottomHeight,
  2040. &dcMem,
  2041. nImageNdx*bm.bmWidth/4+m_mrgnLeft.cxLeftWidth,
  2042. bm.bmHeight-m_mrgnLeft.cyBottomHeight,
  2043. bm.bmWidth/4-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2044. m_mrgnLeft.cyBottomHeight,
  2045. SRCCOPY);
  2046. // middle-left
  2047. dc.StretchBlt(r.left,
  2048. r.top+m_mrgnLeft.cyTopHeight,
  2049. m_mrgnLeft.cxLeftWidth,
  2050. r.Height()-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2051. &dcMem,
  2052. nImageNdx*bm.bmWidth/4,
  2053. m_mrgnLeft.cyTopHeight,
  2054. m_mrgnLeft.cxLeftWidth,
  2055. bm.bmHeight-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2056. SRCCOPY);
  2057. // middle-right
  2058. dc.StretchBlt(r.right-m_mrgnLeft.cxRightWidth,
  2059. r.top+m_mrgnLeft.cyTopHeight,
  2060. m_mrgnLeft.cxRightWidth,
  2061. r.Height()-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2062. &dcMem,
  2063. (nImageNdx+1)*bm.bmWidth/4-m_mrgnLeft.cxRightWidth,
  2064. m_mrgnLeft.cyTopHeight,
  2065. m_mrgnLeft.cxRightWidth,
  2066. bm.bmHeight-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2067. SRCCOPY);
  2068. // middle
  2069. dc.StretchBlt(
  2070. r.left+m_mrgnLeft.cxLeftWidth,
  2071. r.top+m_mrgnLeft.cyTopHeight,
  2072. r.Width()-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2073. r.Height()-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2074. &dcMem,
  2075. nImageNdx*bm.bmWidth/4 + m_mrgnLeft.cxLeftWidth,
  2076. m_mrgnLeft.cyTopHeight,
  2077. bm.bmWidth/4-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2078. bm.bmHeight-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2079. SRCCOPY);
  2080. }
  2081. else
  2082. {
  2083. // left-top
  2084. dc.BitBlt(r.left,
  2085. r.top,
  2086. m_mrgnLeft.cxLeftWidth,
  2087. m_mrgnLeft.cyTopHeight,
  2088. &dcMem,
  2089. 0,
  2090. nImageNdx*bm.bmHeight/4,
  2091. SRCCOPY);
  2092. // right-top
  2093. dc.BitBlt(r.right-m_mrgnLeft.cxRightWidth,
  2094. r.top,
  2095. m_mrgnLeft.cxRightWidth,
  2096. m_mrgnLeft.cyTopHeight,
  2097. &dcMem,
  2098. bm.bmWidth-m_mrgnLeft.cxRightWidth,
  2099. nImageNdx*bm.bmHeight/4,
  2100. SRCCOPY);
  2101. // left-bottom
  2102. dc.BitBlt(r.left,
  2103. r.bottom-m_mrgnLeft.cyBottomHeight,
  2104. m_mrgnLeft.cxLeftWidth,
  2105. m_mrgnLeft.cyBottomHeight,
  2106. &dcMem,
  2107. 0,
  2108. (nImageNdx+1)*bm.bmHeight/4-m_mrgnLeft.cyBottomHeight,
  2109. SRCCOPY);
  2110. // right-bottom
  2111. dc.BitBlt(r.right-m_mrgnLeft.cxRightWidth,
  2112. r.bottom-m_mrgnLeft.cyBottomHeight,
  2113. m_mrgnLeft.cxRightWidth,
  2114. m_mrgnLeft.cyBottomHeight,
  2115. &dcMem,
  2116. bm.bmWidth-m_mrgnLeft.cxRightWidth,
  2117. (nImageNdx+1)*bm.bmHeight/4-m_mrgnLeft.cyBottomHeight,
  2118. SRCCOPY);
  2119. // middle-top
  2120. dc.StretchBlt(r.left+m_mrgnLeft.cxLeftWidth,
  2121. r.top,
  2122. r.Width()-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2123. m_mrgnLeft.cyTopHeight,
  2124. &dcMem,
  2125. m_mrgnLeft.cxLeftWidth,
  2126. nImageNdx*bm.bmHeight/4,
  2127. bm.bmWidth-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2128. m_mrgnLeft.cyTopHeight,
  2129. SRCCOPY);
  2130. // middle-bottom
  2131. dc.StretchBlt(r.left+m_mrgnLeft.cxLeftWidth,
  2132. r.bottom-m_mrgnLeft.cyBottomHeight,
  2133. r.Width()-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2134. m_mrgnLeft.cyBottomHeight,
  2135. &dcMem,
  2136. m_mrgnLeft.cxLeftWidth,
  2137. (nImageNdx+1)*bm.bmHeight/4-m_mrgnLeft.cyBottomHeight,
  2138. bm.bmWidth-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2139. m_mrgnLeft.cyBottomHeight,
  2140. SRCCOPY);
  2141. // middle-left
  2142. dc.StretchBlt(r.left,
  2143. r.top+m_mrgnLeft.cyTopHeight,
  2144. m_mrgnLeft.cxLeftWidth,
  2145. r.Height()-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2146. &dcMem,
  2147. 0,
  2148. nImageNdx*bm.bmHeight/4+m_mrgnLeft.cyTopHeight,
  2149. m_mrgnLeft.cxLeftWidth,
  2150. bm.bmHeight/4-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2151. SRCCOPY);
  2152. // middle-right
  2153. dc.StretchBlt(r.right-m_mrgnLeft.cxRightWidth,
  2154. r.top+m_mrgnLeft.cyTopHeight,
  2155. m_mrgnLeft.cxRightWidth,
  2156. r.Height()-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2157. &dcMem,
  2158. bm.bmWidth-m_mrgnLeft.cxRightWidth,
  2159. nImageNdx*bm.bmHeight/4+m_mrgnLeft.cyTopHeight,
  2160. m_mrgnLeft.cxRightWidth,
  2161. bm.bmHeight/4-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2162. SRCCOPY);
  2163. // middle
  2164. dc.StretchBlt(
  2165. r.left+m_mrgnLeft.cxLeftWidth,
  2166. r.top+m_mrgnLeft.cyTopHeight,
  2167. r.Width()-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2168. r.Height()-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2169. &dcMem,
  2170. m_mrgnLeft.cxLeftWidth,
  2171. nImageNdx*bm.bmHeight/4+m_mrgnLeft.cyTopHeight,
  2172. bm.bmWidth-m_mrgnLeft.cxLeftWidth-m_mrgnLeft.cxRightWidth,
  2173. bm.bmHeight/4-m_mrgnLeft.cyTopHeight-m_mrgnLeft.cyBottomHeight,
  2174. SRCCOPY);
  2175. }
  2176. dcMem.SelectObject(pOldBmp);
  2177. }
  2178. void CCustomTabCtrl::DrawBkRightSpin(CDC& dc, CRect& r, int nImageNdx)
  2179. {
  2180. CDC dcMem;
  2181. dcMem.CreateCompatibleDC(&dc);
  2182. CBitmap* pBmp = CBitmap::FromHandle(m_hBmpBkRightSpin);
  2183. BITMAP bm;
  2184. pBmp->GetBitmap(&bm);
  2185. CBitmap* pOldBmp = dcMem.SelectObject(pBmp);
  2186. if(m_fIsRightImageHorLayout)
  2187. {
  2188. // left-top
  2189. dc.BitBlt(r.left,
  2190. r.top,
  2191. m_mrgnRight.cxLeftWidth,
  2192. m_mrgnRight.cyTopHeight,
  2193. &dcMem,
  2194. nImageNdx*bm.bmWidth/4,
  2195. 0,
  2196. SRCCOPY);
  2197. // right-top
  2198. dc.BitBlt(r.right-m_mrgnRight.cxRightWidth,
  2199. r.top,
  2200. m_mrgnRight.cxRightWidth,
  2201. m_mrgnRight.cyTopHeight,
  2202. &dcMem,
  2203. (nImageNdx+1)*bm.bmWidth/4-m_mrgnRight.cxRightWidth,
  2204. 0,
  2205. SRCCOPY);
  2206. // left-bottom
  2207. dc.BitBlt(r.left,
  2208. r.bottom-m_mrgnRight.cyBottomHeight,
  2209. m_mrgnRight.cxLeftWidth,
  2210. m_mrgnRight.cyBottomHeight,
  2211. &dcMem,
  2212. nImageNdx*bm.bmWidth/4,
  2213. bm.bmHeight-m_mrgnRight.cyBottomHeight,
  2214. SRCCOPY);
  2215. // right-bottom
  2216. dc.BitBlt(r.right-m_mrgnRight.cxRightWidth,
  2217. r.bottom-m_mrgnRight.cyBottomHeight,
  2218. m_mrgnRight.cxRightWidth,
  2219. m_mrgnRight.cyBottomHeight,
  2220. &dcMem,
  2221. (nImageNdx+1)*bm.bmWidth/4-m_mrgnRight.cxRightWidth,
  2222. bm.bmHeight-m_mrgnRight.cyBottomHeight,
  2223. SRCCOPY);
  2224. // middle-top
  2225. dc.StretchBlt(r.left+m_mrgnRight.cxLeftWidth,
  2226. r.top,
  2227. r.Width()-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2228. m_mrgnRight.cyTopHeight,
  2229. &dcMem,
  2230. nImageNdx*bm.bmWidth/4+m_mrgnRight.cxLeftWidth,
  2231. 0,
  2232. bm.bmWidth/4-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2233. m_mrgnRight.cyTopHeight,
  2234. SRCCOPY);
  2235. // middle-bottom
  2236. dc.StretchBlt(r.left+m_mrgnRight.cxLeftWidth,
  2237. r.bottom-m_mrgnRight.cyBottomHeight,
  2238. r.Width()-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2239. m_mrgnRight.cyBottomHeight,
  2240. &dcMem,
  2241. nImageNdx*bm.bmWidth/4+m_mrgnRight.cxLeftWidth,
  2242. bm.bmHeight-m_mrgnRight.cyBottomHeight,
  2243. bm.bmWidth/4-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2244. m_mrgnRight.cyBottomHeight,
  2245. SRCCOPY);
  2246. // middle-left
  2247. dc.StretchBlt(r.left,
  2248. r.top+m_mrgnRight.cyTopHeight,
  2249. m_mrgnRight.cxLeftWidth,
  2250. r.Height()-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2251. &dcMem,
  2252. nImageNdx*bm.bmWidth/4,
  2253. m_mrgnRight.cyTopHeight,
  2254. m_mrgnRight.cxLeftWidth,
  2255. bm.bmHeight-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2256. SRCCOPY);
  2257. // middle-right
  2258. dc.StretchBlt(r.right-m_mrgnRight.cxRightWidth,
  2259. r.top+m_mrgnRight.cyTopHeight,
  2260. m_mrgnRight.cxRightWidth,
  2261. r.Height()-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2262. &dcMem,
  2263. (nImageNdx+1)*bm.bmWidth/4-m_mrgnRight.cxRightWidth,
  2264. m_mrgnRight.cyTopHeight,
  2265. m_mrgnRight.cxRightWidth,
  2266. bm.bmHeight-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2267. SRCCOPY);
  2268. // middle
  2269. dc.StretchBlt(
  2270. r.left+m_mrgnRight.cxLeftWidth,
  2271. r.top+m_mrgnRight.cyTopHeight,
  2272. r.Width()-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2273. r.Height()-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2274. &dcMem,
  2275. nImageNdx*bm.bmWidth/4 + m_mrgnRight.cxLeftWidth,
  2276. m_mrgnRight.cyTopHeight,
  2277. bm.bmWidth/4-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2278. bm.bmHeight-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2279. SRCCOPY);
  2280. }
  2281. else
  2282. {
  2283. // left-top
  2284. dc.BitBlt(r.left,
  2285. r.top,
  2286. m_mrgnRight.cxLeftWidth,
  2287. m_mrgnRight.cyTopHeight,
  2288. &dcMem,
  2289. 0,
  2290. nImageNdx*bm.bmHeight/4,
  2291. SRCCOPY);
  2292. // right-top
  2293. dc.BitBlt(r.right-m_mrgnRight.cxRightWidth,
  2294. r.top,
  2295. m_mrgnRight.cxRightWidth,
  2296. m_mrgnRight.cyTopHeight,
  2297. &dcMem,
  2298. bm.bmWidth-m_mrgnRight.cxRightWidth,
  2299. nImageNdx*bm.bmHeight/4,
  2300. SRCCOPY);
  2301. // left-bottom
  2302. dc.BitBlt(r.left,
  2303. r.bottom-m_mrgnRight.cyBottomHeight,
  2304. m_mrgnRight.cxLeftWidth,
  2305. m_mrgnRight.cyBottomHeight,
  2306. &dcMem,
  2307. 0,
  2308. (nImageNdx+1)*bm.bmHeight/4-m_mrgnRight.cyBottomHeight,
  2309. SRCCOPY);
  2310. // right-bottom
  2311. dc.BitBlt(r.right-m_mrgnRight.cxRightWidth,
  2312. r.bottom-m_mrgnRight.cyBottomHeight,
  2313. m_mrgnRight.cxRightWidth,
  2314. m_mrgnRight.cyBottomHeight,
  2315. &dcMem,
  2316. bm.bmWidth-m_mrgnRight.cxRightWidth,
  2317. (nImageNdx+1)*bm.bmHeight/4-m_mrgnRight.cyBottomHeight,
  2318. SRCCOPY);
  2319. // middle-top
  2320. dc.StretchBlt(r.left+m_mrgnRight.cxLeftWidth,
  2321. r.top,
  2322. r.Width()-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2323. m_mrgnRight.cyTopHeight,
  2324. &dcMem,
  2325. m_mrgnRight.cxLeftWidth,
  2326. nImageNdx*bm.bmHeight/4,
  2327. bm.bmWidth-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2328. m_mrgnRight.cyTopHeight,
  2329. SRCCOPY);
  2330. // middle-bottom
  2331. dc.StretchBlt(r.left+m_mrgnRight.cxLeftWidth,
  2332. r.bottom-m_mrgnRight.cyBottomHeight,
  2333. r.Width()-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2334. m_mrgnRight.cyBottomHeight,
  2335. &dcMem,
  2336. m_mrgnRight.cxLeftWidth,
  2337. (nImageNdx+1)*bm.bmHeight/4-m_mrgnRight.cyBottomHeight,
  2338. bm.bmWidth-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2339. m_mrgnRight.cyBottomHeight,
  2340. SRCCOPY);
  2341. // middle-left
  2342. dc.StretchBlt(r.left,
  2343. r.top+m_mrgnRight.cyTopHeight,
  2344. m_mrgnRight.cxLeftWidth,
  2345. r.Height()-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2346. &dcMem,
  2347. 0,
  2348. nImageNdx*bm.bmHeight/4+m_mrgnRight.cyTopHeight,
  2349. m_mrgnRight.cxLeftWidth,
  2350. bm.bmHeight/4-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2351. SRCCOPY);
  2352. // middle-right
  2353. dc.StretchBlt(r.right-m_mrgnRight.cxRightWidth,
  2354. r.top+m_mrgnRight.cyTopHeight,
  2355. m_mrgnRight.cxRightWidth,
  2356. r.Height()-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2357. &dcMem,
  2358. bm.bmWidth-m_mrgnRight.cxRightWidth,
  2359. nImageNdx*bm.bmHeight/4+m_mrgnRight.cyTopHeight,
  2360. m_mrgnRight.cxRightWidth,
  2361. bm.bmHeight/4-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2362. SRCCOPY);
  2363. // middle
  2364. dc.StretchBlt(
  2365. r.left+m_mrgnRight.cxLeftWidth,
  2366. r.top+m_mrgnRight.cyTopHeight,
  2367. r.Width()-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2368. r.Height()-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2369. &dcMem,
  2370. m_mrgnRight.cxLeftWidth,
  2371. nImageNdx*bm.bmHeight/4+m_mrgnRight.cyTopHeight,
  2372. bm.bmWidth-m_mrgnRight.cxLeftWidth-m_mrgnRight.cxRightWidth,
  2373. bm.bmHeight/4-m_mrgnRight.cyTopHeight-m_mrgnRight.cyBottomHeight,
  2374. SRCCOPY);
  2375. }
  2376. dcMem.SelectObject(pOldBmp);
  2377. }
  2378. //绘制左端按钮上的箭头标志符号
  2379. void CCustomTabCtrl::DrawGlyph(CDC& dc, CPoint& pt, int nImageNdx, int nColorNdx)
  2380. {
  2381. CDC dcMem, dcMemMono;
  2382. dcMem.CreateCompatibleDC(&dc);
  2383. dcMemMono.CreateCompatibleDC(&dc);
  2384. CBitmap* pOldBmpGlyphMono = dcMemMono.SelectObject(&m_bmpGlyphsMono);
  2385. CBitmap bmpGlyphColor;
  2386. bmpGlyphColor.CreateCompatibleBitmap(&dc,8,7);
  2387. CBitmap* pOldBmpGlyphColor = dcMem.SelectObject(&bmpGlyphColor);
  2388. COLORREF rgbOldTextGlyph =  dcMem.SetTextColor(m_rgbGlyph[nColorNdx]);
  2389. dcMem.BitBlt(0, 0, 8, 7, &dcMemMono, nImageNdx*8, 0, SRCCOPY);
  2390. dcMem.SetTextColor(rgbOldTextGlyph);
  2391. COLORREF rgbOldBk = dc.SetBkColor(RGB(255,255,255));
  2392. COLORREF rgbOldText = dc.SetTextColor(RGB(0,0,0));
  2393. dc.BitBlt(pt.x, pt.y, 8, 7, &dcMem, 0, 0, SRCINVERT);
  2394. dc.BitBlt(pt.x, pt.y, 8, 7, &dcMemMono, nImageNdx*8, 0, SRCAND);
  2395. dc.BitBlt(pt.x, pt.y, 8, 7, &dcMem, 0, 0, SRCINVERT);
  2396. dcMem.SelectObject(pOldBmpGlyphColor);
  2397. dcMemMono.SelectObject(pOldBmpGlyphMono);
  2398. dc.SetBkColor(rgbOldBk);
  2399. dc.SetTextColor(rgbOldText);
  2400. }
  2401. BOOL CCustomTabCtrl::ModifyStyle(DWORD dwRemove, DWORD dwAdd, UINT nFlags)
  2402. {
  2403. if(dwRemove&CTCS_TOOLTIPS)
  2404. m_ctrlToolTip.DestroyWindow();
  2405. if(dwRemove&CTCS_MULTIHIGHLIGHT)
  2406. {
  2407. for(int i=0;i<m_aItems.GetSize();i++)
  2408. m_aItems[i]->m_fHighlighted = FALSE;
  2409. }
  2410. if(dwAdd&CTCS_MULTIHIGHLIGHT)
  2411. {
  2412. for(int i=0;i<m_aItems.GetSize();i++)
  2413. {
  2414. if(i==m_nItemSelected)
  2415. m_aItems[i]->m_fHighlighted = TRUE;
  2416. }
  2417. }
  2418. CWnd::ModifyStyle(dwRemove,dwAdd,nFlags);
  2419. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  2420. Invalidate(FALSE);
  2421. return TRUE;
  2422. }
  2423. void CCustomTabCtrl::PreSubclassWindow() 
  2424. {
  2425. OnThemeChanged(0,0);
  2426. CWnd::ModifyStyle(0,WS_CLIPCHILDREN);
  2427. RecalcLayout(RECALC_RESIZED,m_nItemSelected);
  2428. CWnd::PreSubclassWindow();
  2429. }
  2430. void CCustomTabCtrl::SetDragCursors(HCURSOR hCursorMove, HCURSOR hCursorCopy)
  2431. {
  2432. ::DestroyCursor(m_hCursorMove);
  2433. m_hCursorMove = NULL;
  2434. ::DestroyCursor(m_hCursorCopy);
  2435. m_hCursorCopy = NULL;
  2436. m_hCursorMove = CopyCursor(hCursorMove);
  2437. m_hCursorCopy = CopyCursor(hCursorCopy);
  2438. }
  2439. // 切换显示的窗口
  2440. //在这里选中的窗口发送消息,作出相应的处理
  2441. //在这里,对应多个窗口,将选中的窗口设定为活动或禁止
  2442. void CCustomTabCtrl::SwitchWindows(CWnd* curwnd)
  2443. {
  2444. if(curwnd==NULL) return;
  2445. if(m_oldwnd!=NULL)
  2446.   m_oldwnd->MoveWindow(0,0,0,0);
  2447.   m_oldwnd->EnableWindow(FALSE);
  2448.   m_oldwnd->ShowWindow(SW_HIDE);
  2449.  
  2450. }
  2451. if(curwnd!=NULL)
  2452. {
  2453. curwnd->MoveWindow(&m_rClient);
  2454. curwnd->EnableWindow();
  2455. curwnd->ShowWindow(SW_SHOW);
  2456. }
  2457. /*else
  2458. {
  2459.       CString inf;
  2460.   CDC* pDC=GetParent()->GetDC();
  2461.   pDC->FillRect(&m_rClient,&CBrush(RGB(255,224,224)));
  2462.   pDC->SetBkMode(TRANSPARENT);
  2463.   pDC->DrawText(_T("当前显示的窗口尚未建立"),&m_rClient,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  2464.   ReleaseDC(pDC);
  2465. }*/
  2466. }
  2467. //当父窗口大小发生变化时,若为了使它的大小也发生相应的变化
  2468. //则调用本窗函数,以改变目前窗口的大小
  2469. void  CCustomTabCtrl::ResetWindowSize(CRect& rect)
  2470. {
  2471. if(m_rClient==rect) return;
  2472. m_rClient=rect;
  2473. if(m_rClient.Height()>m_hSwitch)
  2474. {
  2475.    m_rClient.bottom=m_rClient.bottom-m_hSwitch-DEF_STOWND_LENGTH;
  2476. }
  2477. CRect switchrect;
  2478. switchrect.SetRect(rect.left,rect.bottom-m_hSwitch,rect.right,rect.bottom);
  2479. MoveWindow(&switchrect);
  2480. if(m_oldwnd!=NULL)
  2481.    m_oldwnd->MoveWindow(&m_rClient);
  2482. }
  2483. //在有时,不必要使切换窗口的大小和显示窗口部分的宽度一致,用此函数实现
  2484. //重新定义切换窗口的大小
  2485. void  CCustomTabCtrl::ResetSwitchWidth(int width)
  2486. {
  2487.      CRect switchrect;
  2488.  switchrect.SetRect(m_rClient.left,m_rClient.bottom+DEF_STOWND_LENGTH,
  2489.         m_rClient.left+width,m_rClient.bottom+DEF_STOWND_LENGTH+m_hSwitch);
  2490.      MoveWindow(&switchrect);
  2491. //m_oldwnd->MoveWindow(&m_rClient);
  2492. }
  2493. //当按下右键时,则删除当年的页面
  2494. void CCustomTabCtrl::OnRButtonDown(UINT nFlags, CPoint point)
  2495. {
  2496. int nHitTest = HitTest(point);
  2497. DeleteItem(nHitTest);
  2498. CWnd::OnRButtonDown(nFlags, point);
  2499. }