MyButton.cpp
上传用户:jzscgs158
上传日期:2022-05-25
资源大小:8709k
文件大小:14k
源码类别:

百货/超市行业

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "math.h"
  3. #include "MyButton.h"
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CMyButton
  11. CMyButton::CMyButton()
  12. {
  13. m_clrText=RGB(0,0,0);
  14. m_clrBack=RGB(161,192,245);
  15. m_clrLeft=RGB(97,244,78);
  16. m_clrRight=RGB(52,148,39);
  17. m_clrFlatBack=GetSysColor(COLOR_3DFACE);
  18. m_blnMouseOn=FALSE;
  19. intStyle=0;
  20. intAlgin=0;
  21. intButtonFace=0;
  22. m_BackBrush.CreateSolidBrush(m_clrFlatBack);
  23. m_bIsDefault = FALSE;
  24. m_nTypeStyle=SS_TYPEMASK;
  25. }
  26. CMyButton::~CMyButton()
  27. {
  28. m_rgn.DeleteObject();
  29. DestroyXIcon();
  30. m_BackBrush.DeleteObject();
  31. }
  32. BEGIN_MESSAGE_MAP(CMyButton, CButton)
  33. //{{AFX_MSG_MAP(CMyButton)
  34. ON_WM_MOUSEMOVE()
  35. ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
  36. ON_WM_GETDLGCODE()
  37. ON_WM_SYSCOLORCHANGE()
  38. ON_WM_CTLCOLOR_REFLECT()
  39. ON_MESSAGE(BM_SETSTYLE, OnSetStyle)
  40. //}}AFX_MSG_MAP
  41. END_MESSAGE_MAP()
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CMyButton message handlers
  44. void CMyButton::PreSubclassWindow() 
  45. {
  46. CButton::PreSubclassWindow();
  47. UINT nBS;
  48. nBS = GetButtonStyle();
  49. m_nTypeStyle = nBS & SS_TYPEMASK;
  50. if (m_nTypeStyle == BS_DEFPUSHBUTTON)
  51. {
  52. m_bIsDefault = TRUE;
  53. m_nTypeStyle = BS_PUSHBUTTON;
  54. }
  55. ModifyStyle(SS_TYPEMASK, BS_OWNERDRAW, SWP_FRAMECHANGED);
  56. CRect rect;
  57. GetClientRect(rect);
  58. m_rgn.DeleteObject(); 
  59. SetWindowRgn(NULL, FALSE);
  60. if(intButtonFace==1)
  61. m_rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,10,10);
  62. if(intButtonFace==0)
  63. m_rgn.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
  64. if(intButtonFace==2)
  65. m_rgn.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom);
  66. SetWindowRgn(m_rgn, TRUE);
  67. ClientToScreen(rect);
  68. CWnd* pParent = GetParent();
  69. if (pParent) pParent->ScreenToClient(rect);
  70. MoveWindow(rect.left, rect.top, rect.Width(), rect.Height(), TRUE);
  71. }
  72. void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
  73. {
  74. ASSERT(lpDrawItemStruct != NULL);
  75. CDC* pDC   = CDC::FromHandle(lpDrawItemStruct->hDC);
  76. CRect rect = lpDrawItemStruct->rcItem;
  77. UINT state = lpDrawItemStruct->itemState;
  78. UINT nStyle = GetStyle();
  79. CRgn rgn1,rgn2;
  80. int r1,g1,b1;
  81. if(intButtonFace==1)
  82. {
  83. rgn1.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,10,10);
  84. rgn2.CreateRoundRectRgn(rect.left+1,rect.top+1,rect.right-1,rect.bottom-1,10,10);
  85. }
  86. if(intButtonFace==0)
  87. {
  88. rgn1.CreateRectRgn(rect.left,rect.top,rect.right,rect.bottom);
  89. rgn2.CreateRectRgn(rect.left+1,rect.top+1,rect.right-1,rect.bottom-1);
  90. }
  91. if(intButtonFace==2)
  92. {
  93. rgn1.CreateEllipticRgn(rect.left,rect.top,rect.right,rect.bottom);
  94. rgn2.CreateEllipticRgn(rect.left+1,rect.top+1,rect.right-1,rect.bottom-1);
  95. }
  96. pDC->SelectClipRgn(&rgn1);
  97. int nSavedDC = pDC->SaveDC();
  98. CBrush brush1,brush2;
  99. if(!(nStyle&BS_NOTIFY))
  100. {
  101. if ((state & ODS_FOCUS)||(state & ODS_SELECTED))
  102. {
  103. if(intStyle!=2)
  104. {
  105. r1=GetRValue(m_clrBack);
  106. g1=GetGValue(m_clrBack);
  107. b1=GetBValue(m_clrBack);
  108. for(int i=rect.Height()/2;i>0;i--)
  109. {
  110. r1=(r1+10)>255?255:(r1+10);
  111. g1=(g1+10)>255?255:(g1+10);
  112. b1=(b1+10)>255?255:(b1+10);
  113. CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
  114. CPen *old = pDC->SelectObject(&pen);
  115. pDC->MoveTo(rect.left,rect.top+i);
  116. pDC->LineTo(rect.right,rect.top+i);
  117. pDC->MoveTo(rect.left,rect.bottom-i);
  118. pDC->LineTo(rect.right,rect.bottom-i);
  119. pDC->SelectObject(old);
  120. }
  121. }
  122. else
  123. {
  124. pDC->FillSolidRect(rect,m_clrBack);
  125. }
  126. r1=GetRValue(m_clrRight);
  127. g1=GetGValue(m_clrRight);
  128. b1=GetBValue(m_clrRight);
  129. r1=(r1+30)>255?255:(r1+30);
  130. g1=(g1+30)>255?255:(g1+30);
  131. b1=(b1+30)>255?255:(b1+30);
  132. brush2.CreateSolidBrush(m_clrRight);
  133. brush1.CreateSolidBrush(RGB(r1,g1,b1));
  134. pDC->FrameRgn(&rgn1,&brush1,1,1);
  135. pDC->FrameRgn(&rgn2,&brush2,1,1);
  136. }
  137. else if(m_blnMouseOn)
  138. {
  139. if(intStyle!=2)
  140. {
  141. r1=GetRValue(m_clrBack);
  142. g1=GetGValue(m_clrBack);
  143. b1=GetBValue(m_clrBack);
  144. for(int i=rect.Height()/2;i>0;i--)
  145. {
  146. r1=(r1+10)>255?255:(r1+10);
  147. g1=(g1+10)>255?255:(g1+10);
  148. b1=(b1+10)>255?255:(b1+10);
  149. CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
  150. CPen *old = pDC->SelectObject(&pen);
  151. pDC->MoveTo(rect.left,rect.top+i);
  152. pDC->LineTo(rect.right,rect.top+i);
  153. pDC->MoveTo(rect.left,rect.bottom-i);
  154. pDC->LineTo(rect.right,rect.bottom-i);
  155. pDC->SelectObject(old);
  156. }
  157. }
  158. else
  159. {
  160. pDC->FillSolidRect(rect,m_clrBack);
  161. }
  162. r1=GetRValue(m_clrLeft);
  163. g1=GetGValue(m_clrLeft);
  164. b1=GetBValue(m_clrLeft);
  165. r1=(r1+30)>255?255:(r1+30);
  166. g1=(g1+30)>255?255:(g1+30);
  167. b1=(b1+30)>255?255:(b1+30);
  168. brush2.CreateSolidBrush(m_clrLeft);
  169. brush1.CreateSolidBrush(RGB(r1,g1,b1));
  170. pDC->FrameRgn(&rgn1,&brush1,1,1);
  171. pDC->FrameRgn(&rgn2,&brush2,1,1);
  172. }
  173. else 
  174. {
  175. if(nStyle&BS_FLAT)
  176. {
  177. CBrush bs;
  178. bs.CreateSolidBrush(m_clrFlatBack);
  179. CRect rcBack;
  180. GetClientRect(rcBack);
  181. pDC->FillRect(rcBack,&m_BackBrush);
  182. }
  183. else
  184. {
  185. if(intStyle!=2)
  186. {
  187. r1=GetRValue(m_clrBack);
  188. g1=GetGValue(m_clrBack);
  189. b1=GetBValue(m_clrBack);
  190. for(int i=rect.Height()/2;i>0;i--)
  191. {
  192. r1=(r1+13)>255?255:(r1+13);
  193. g1=(g1+13)>255?255:(g1+13);
  194. b1=(b1+13)>255?255:(b1+13);
  195. CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
  196. CPen *old = pDC->SelectObject(&pen);
  197. pDC->MoveTo(rect.left,rect.top+i);
  198. pDC->LineTo(rect.right,rect.top+i);
  199. pDC->MoveTo(rect.left,rect.bottom-i);
  200. pDC->LineTo(rect.right,rect.bottom-i);
  201. pDC->SelectObject(old);
  202. }
  203. }
  204. else
  205. {
  206. pDC->FillSolidRect(rect,m_clrBack);
  207. }
  208. r1=GetRValue(m_clrBack);
  209. g1=GetGValue(m_clrBack);
  210. b1=GetBValue(m_clrBack);
  211. r1=(r1+30)>255?255:(r1+30);
  212. g1=(g1+30)>255?255:(g1+30);
  213. b1=(b1+30)>255?255:(b1+30);
  214. brush2.CreateSolidBrush(m_clrBack);
  215. brush1.CreateSolidBrush(RGB(r1,g1,b1));
  216. pDC->FrameRgn(&rgn1,&brush1,1,1);
  217. pDC->FrameRgn(&rgn2,&brush2,1,1);
  218. }
  219. }
  220. }
  221. else
  222. {
  223. pDC->FillSolidRect(rect,m_clrBack);
  224. }
  225. //输出文字
  226. CFont *ft=GetFont();
  227. LOGFONT logft;
  228. ft->GetLogFont(&logft);
  229. CRect rcIcon(rect);
  230. if(intStyle==1)
  231. {
  232. switch(intAlgin)
  233. {
  234. case 1: //文字在下端
  235. rcIcon.bottom=rect.bottom-abs(logft.lfHeight);
  236. if(rcIcon.bottom<0) rcIcon.bottom=0;
  237. DrawIconX(pDC,rcIcon);
  238. rect.top=rcIcon.bottom-(rcIcon.Height()-dwIconHeight)/2;
  239. break;
  240. case 2://文字在上
  241. rcIcon.top=abs(logft.lfHeight)+rect.top;
  242. DrawIconX(pDC,rcIcon);
  243. rect.bottom=rcIcon.top+(rcIcon.Height()-dwIconHeight)/2;
  244. break;
  245. case 3://文字在左
  246. GetXiconInf();
  247. rcIcon.left=(long)(rect.Width()*0.9+rect.left-dwIconWidth-5);
  248. rcIcon.right=(long)(rect.Width()*0.9+rect.left);
  249. DrawIconX(pDC,rcIcon);
  250. rect.right=rcIcon.left;
  251. break;
  252. case 0://文字在右
  253. default:
  254. DrawIconX(pDC,rcIcon);
  255. rect.left=(long)(dwIconWidth+rect.left+rect.Width()*0.1);
  256. break;
  257. }
  258. }
  259. if(intStyle==0)
  260. {
  261. switch(intAlgin)
  262. {
  263. case 1: //文字在下端
  264. rect.top=rect.bottom-abs(logft.lfHeight)-10;
  265. break;
  266. case 2://文字在上
  267. rect.bottom=abs(logft.lfHeight)+10+rect.top;
  268. break;
  269. case 3://文字在左
  270. case 0://文字在右
  271. default:
  272. break;
  273. }
  274. }
  275. if(intStyle==2)
  276. {
  277. pDC->FrameRgn(&rgn1,&brush1,1,1);
  278. pDC->FrameRgn(&rgn2,&brush2,1,1);
  279. switch(intAlgin)
  280. {
  281. case 1: //文字在下端
  282. rcIcon.bottom=rect.bottom-abs(logft.lfHeight);
  283. if(rcIcon.bottom<0) rcIcon.bottom=0;
  284. DrawImgX(pDC,rcIcon);
  285. rect.top=rcIcon.bottom-(rcIcon.Height()-m_imgSize.cy)/2;
  286. break;
  287. case 2://文字在上
  288. rcIcon.top=abs(logft.lfHeight)+rect.top;
  289. DrawImgX(pDC,rcIcon);
  290. rect.bottom=rcIcon.top+(rcIcon.Height()-m_imgSize.cy)/2;
  291. break;
  292. case 3://文字在左
  293. rcIcon.left=(long)(rect.Width()*0.9+rect.left-m_imgSize.cx-5);
  294. rcIcon.right=(long)(rect.Width()*0.9+rect.left);
  295. DrawImgX(pDC,rcIcon);
  296. rect.right=rcIcon.left;
  297. break;
  298. case 0://文字在右
  299. default:
  300. DrawImgX(pDC,rcIcon);
  301. rect.left=(long)(m_imgSize.cx+rect.left+rect.Width()*0.1);
  302. break;
  303. }
  304. }
  305. CPoint m_ptCentre=rect.CenterPoint();
  306. CString strText;
  307. GetWindowText(strText);
  308. if (!strText.IsEmpty())
  309. {
  310. pDC->SetTextColor(m_clrText);
  311. CSize Extent = pDC->GetTextExtent(strText);
  312. CPoint pt;
  313. if(intAlgin==1 || intAlgin==2)
  314. {
  315. pt.x = m_ptCentre.x - Extent.cx/2;
  316. pt.y=m_ptCentre.y - Extent.cy/2;
  317. }
  318. if(intAlgin==0)
  319. {
  320. pt.x=rect.left+15;
  321. pt.y=m_ptCentre.y - Extent.cy/2;
  322. }
  323. if(intAlgin==3)
  324. {
  325. pt.x=rect.right-Extent.cy-10;
  326. pt.y=m_ptCentre.y - Extent.cy/2;
  327. }
  328. if (state & ODS_SELECTED) pt.Offset(1,1);
  329. pDC->SetBkMode(TRANSPARENT);
  330. if ((state & ODS_DISABLED)&!(nStyle&BS_NOTIFY))
  331. pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
  332. else if(nStyle&BS_NOTIFY)
  333. {
  334. pDC->FillRect(rect,&m_BackBrush);
  335. if((state & ODS_FOCUS)||(state & ODS_SELECTED))
  336. {
  337. pDC->SetTextColor(m_clrRight);
  338. pDC->TextOut(pt.x+2, pt.y+2, strText);
  339. }
  340. else if(m_blnMouseOn)
  341. {
  342. pDC->SetTextColor(m_clrLeft);
  343. pDC->TextOut(pt.x+2, pt.y+2, strText);
  344. }
  345. else
  346. {
  347. pDC->TextOut(pt.x, pt.y, strText);
  348. }
  349. }
  350. else
  351. {
  352. pDC->TextOut(pt.x, pt.y, strText);
  353. }
  354. }
  355. pDC->SelectClipRgn(NULL);
  356. pDC->RestoreDC(nSavedDC);
  357. rgn1.DeleteObject();
  358. rgn2.DeleteObject();
  359. }
  360. void CMyButton::SetMaskColor(COLORREF colLeft,COLORREF colRight)
  361. {
  362. m_clrRight=colRight;
  363. m_clrLeft=colLeft;
  364. this->Invalidate(TRUE);
  365. }
  366. void CMyButton::SetBackColor(COLORREF color)
  367. {
  368. m_clrBack=color;
  369. this->Invalidate(TRUE);
  370. }
  371. void CMyButton::SetBackImage(UINT nIDResource)
  372. {
  373. CBitmap bmp;
  374. intStyle=3;
  375. bmp.LoadBitmap(nIDResource);
  376. m_BackBrush.DeleteObject();
  377. m_BackBrush.CreatePatternBrush(&bmp);
  378. }
  379. void CMyButton::SetButtonFace(int intStyle)
  380. {
  381. intButtonFace=intStyle;
  382. this->Invalidate();
  383. }
  384. void CMyButton::SetFlatBack(COLORREF colFlat)
  385. {
  386. m_clrFlatBack=colFlat;
  387. m_BackBrush.DeleteObject();
  388. m_BackBrush.CreateSolidBrush(colFlat);
  389. this->Invalidate(TRUE);
  390. }
  391. void CMyButton::SetTextColor(COLORREF color)
  392. {
  393. m_clrText=color;
  394. this->Invalidate(TRUE);
  395. }
  396. void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
  397. {
  398. CWnd* wndUnderMouse = NULL;
  399. CWnd* wndActive = this;
  400. TRACKMOUSEEVENT csTME;
  401. CButton::OnMouseMove(nFlags, point);
  402. ClientToScreen(&point);
  403. wndUnderMouse = WindowFromPoint(point);
  404. // If the mouse enter the button with the left button pressed then do nothing
  405. if (nFlags & MK_LBUTTON) return;
  406. // If our button is not flat then do nothing
  407. wndActive = GetActiveWindow();
  408. if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive)
  409. {
  410. if (!m_blnMouseOn)
  411. {
  412. m_blnMouseOn = TRUE;
  413. Invalidate();
  414. csTME.cbSize = sizeof(csTME);
  415. csTME.dwFlags = TME_LEAVE;
  416. csTME.hwndTrack = m_hWnd;
  417. ::_TrackMouseEvent(&csTME);
  418. }
  419. else
  420. {
  421. m_blnMouseOn=FALSE;
  422. Invalidate();
  423. }
  424. }
  425. LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
  426. {
  427. m_blnMouseOn=FALSE;
  428. Invalidate();
  429. return 0;
  430. }
  431. void CMyButton::SetXIcon(UINT nIDResource)
  432. {
  433. intStyle=1;
  434. Xicon=AfxGetApp()->LoadIcon(nIDResource);
  435. this->Invalidate();
  436. }
  437. void CMyButton::DrawIconX(CDC *pDC,CRect rcItem)
  438. {
  439. GetXiconInf();
  440. int intTop=(rcItem.Height()-dwIconHeight)/2;
  441. if(intTop<0) intTop=0;
  442. intTop=rcItem.top+intTop;
  443. if(intAlgin==0)
  444. {
  445. int intLeft=rcItem.left+(int)(rcItem.Width()*0.1);
  446. pDC->DrawIcon(intLeft,intTop,Xicon);
  447. }
  448. else
  449. {
  450. int intLeft=(rcItem.Width()-dwIconWidth)/2;
  451. if(intLeft<0) intLeft=0;
  452. intLeft=intLeft+rcItem.left;
  453. pDC->DrawIcon(intLeft,intTop,Xicon);
  454. }
  455. }
  456. void CMyButton::DrawImgX(CDC *pDC,CRect rcItem)
  457. {
  458. int cx,cy;
  459. if(intAlgin==0)
  460. {
  461. cx=rcItem.left+(int)(rcItem.Width()*0.1);
  462. cy=(rcItem.Height()-m_imgSize.cy)/2+rcItem.top;
  463. }
  464. else
  465. {
  466. cx=(rcItem.Width()-m_imgSize.cx)/2+rcItem.left;
  467. cy=(rcItem.Height()-m_imgSize.cy)/2+rcItem.top;
  468. }
  469. CPoint pt(cx,cy);
  470. m_imgList.Draw(pDC,0,pt,ILD_NORMAL);
  471. }
  472. void CMyButton::DestroyXIcon()
  473. {
  474. if(Xicon) ::DestroyIcon(Xicon);
  475. }
  476. void CMyButton::GetXiconInf()
  477. {
  478. BOOL bRetValue;
  479. ICONINFO ii;
  480. if (Xicon)
  481. {
  482. ::ZeroMemory(&ii, sizeof(ICONINFO));
  483. bRetValue = ::GetIconInfo(Xicon, &ii);
  484. if (bRetValue == FALSE)
  485. {
  486. DestroyXIcon();
  487. } // if
  488. dwIconWidth = (DWORD)(ii.xHotspot * 2);
  489. dwIconHeight= (DWORD)(ii.yHotspot * 2);
  490. ::DeleteObject(ii.hbmMask);
  491. ::DeleteObject(ii.hbmColor);
  492. }
  493. }
  494. void CMyButton::SetXAlign(int Align)
  495. {
  496. intAlgin=Align;
  497. this->Invalidate();
  498. }
  499. void CMyButton::SetXStyle(int Style)
  500. {
  501. intStyle=Style;
  502. this->Invalidate();
  503. }
  504. void CMyButton::SetForeImage(UINT nIDResource,CSize sz)
  505. {
  506. intStyle=2;
  507. m_imgSize=sz;
  508. HBITMAP hbm=(HBITMAP)::LoadImage(AfxGetInstanceHandle(),
  509.                              MAKEINTRESOURCE(nIDResource),
  510.  IMAGE_BITMAP,
  511.  0,0,
  512. LR_CREATEDIBSECTION |LR_LOADMAP3DCOLORS);
  513. CBitmap bm;
  514. bm.Attach(hbm);
  515. m_imgList.Create(sz.cx,sz.cy,ILC_COLOR16,0,0);
  516. m_imgList.Add(&bm,(CBitmap*)NULL);
  517. }
  518. UINT CMyButton::OnGetDlgCode() 
  519. {
  520. UINT nCode = CButton::OnGetDlgCode();
  521. nCode |= (m_bIsDefault ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON);
  522. return nCode;
  523. }
  524. void CMyButton::OnSysColorChange() 
  525. {
  526. CButton::OnSysColorChange();
  527. }
  528. HBRUSH CMyButton::CtlColor(CDC* pDC, UINT nCtlColor) 
  529. {
  530. return (HBRUSH)::GetStockObject(NULL_BRUSH); 
  531. }
  532. LRESULT CMyButton::OnSetStyle(WPARAM wParam, LPARAM lParam)
  533. {
  534. UINT nNewType = (wParam & SS_TYPEMASK);
  535. if (nNewType == BS_DEFPUSHBUTTON)
  536. {
  537. m_bIsDefault = TRUE;
  538. }
  539. else if (nNewType == BS_PUSHBUTTON)
  540. {
  541. m_bIsDefault = FALSE;
  542. return DefWindowProc(BM_SETSTYLE,
  543. (wParam & ~SS_TYPEMASK) | BS_OWNERDRAW, lParam);
  544. }