SkinButton.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. /************************************************************************
  2. * 程序名: 精仿QQ主界面
  3. * 制作人: 李克平, 2011年04月11日
  4. * 版本号: 1.0
  5. ************************************************************************/
  6. // SkinBtn.cpp : 实现文件
  7. //
  8. #include "stdafx.h"
  9. #include "QQ.h"
  10. #include "SkinButton.h"
  11. // CSkinButton
  12. IMPLEMENT_DYNAMIC(CSkinButton, CButton)
  13. CSkinButton::CSkinButton()
  14. {
  15. m_state = NORMAL;
  16. m_pFont=new CFont();
  17. m_pFont->CreatePointFont(90,_T("Arial"));
  18. m_fg = RGB(0, 0, 0);
  19. m_bg = RGB(255, 255, 255);
  20. m_crBack = RGB(255,0,255);
  21. m_bMouseOver = false;
  22. m_bEnabled = true;
  23. m_bDCStored = false;
  24. m_textPos = CPoint(21,0);
  25. m_iconRect = CRect(0,0,16,16);
  26. m_bmpIconButton.LoadImage("Skin\\DefaultTheme\\IconButton.bmp");
  27. }
  28. CSkinButton::~CSkinButton()
  29. {
  30. delete m_pFont;
  31. m_memDC.DeleteDC();
  32. }
  33. BEGIN_MESSAGE_MAP(CSkinButton, CButton)
  34. ON_WM_MOUSEMOVE()
  35. ON_WM_TIMER()
  36. ON_WM_ERASEBKGND()
  37. ON_WM_SETCURSOR()
  38. ON_WM_ENABLE()
  39. ON_WM_LBUTTONUP()
  40. END_MESSAGE_MAP()
  41. void CSkinButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
  42. {
  43. //// TODO: 添加您的代码以绘制指定项
  44. //CDC* pDC = CDC::FromHandle(lpDIS->hDC);
  45. UINT state = lpDIS->itemState;
  46. //CRect rect;
  47. //rect.CopyRect(&lpDIS->rcItem);
  48. m_state = NORMAL;
  49. if (state & ODS_FOCUS)
  50. {
  51. if (state & ODS_SELECTED)
  52. {
  53. m_state = DOWN;
  54. }
  55. else
  56. {
  57. if(m_bMouseOver)
  58. m_state = HOVER;
  59. }
  60. }
  61. else
  62. {
  63. m_state = NORMAL;
  64. }
  65. if (state & ODS_DISABLED)
  66. {
  67. m_state = DISABLE;
  68. m_bEnabled = false;
  69. }
  70. DrawButton();
  71. }
  72. void CSkinButton::DrawButton()
  73. {
  74. CClientDC dc(this);
  75. CRect rect;
  76. GetClientRect(&rect);
  77. CDC memDC;
  78. memDC.CreateCompatibleDC(&dc);
  79. CBitmap Screen;
  80. Screen.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
  81. memDC.SelectObject(&Screen);
  82. Screen.DeleteObject();
  83. //画背景
  84. memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &m_memDC, 0, 0, SRCCOPY);
  85. CString strText;
  86. GetWindowText(strText);
  87. memDC.SetBkMode(TRANSPARENT);
  88. memDC.SelectObject(m_pFont);
  89. switch(m_state)
  90. {
  91. case NORMAL:
  92. //memDC.TextOutW(m_textPos.x,m_textPos.y,str);
  93. if(m_bmpNormal.m_hObject != 0)
  94. m_bmpNormal.TransparentBlt(memDC,rect,m_crBack);
  95. //m_imgNormal.TransparentBlt(memDC, rect.left, rect.top,
  96. // m_imgNormal.GetWidth(), m_imgNormal.GetHeight(), RGB(255,0,255));
  97. if(!m_hMouseOutIcon.IsNull())
  98. {
  99. m_hMouseOutIcon.TransparentBlt(memDC, m_iconRect.left+2,m_iconRect.top+2,
  100. m_iconRect.Width(), m_iconRect.Height(), RGB(0,0,0));
  101. memDC.SetTextColor(GetFGColor());
  102. memDC.TextOut(m_textPos.x+2,m_textPos.y+2,strText);
  103. }
  104. //DrawButtonText(&dc, rect, str, GetFGColor());
  105. break;
  106. case HOVER:
  107. //DrawFilledRect(&memDC, rect, RGB(255,255,0));
  108. if(m_bmpHover.m_hObject != 0)
  109. m_bmpHover.TransparentBlt(memDC,rect,m_crBack);
  110. if(!m_hMouseInIcon.IsNull())
  111. {
  112. if(m_bmpIconButton.m_hObject != 0)
  113. {
  114. CEnBitmap bmpHover;
  115. m_bmpIconButton.DrawImage(bmpHover,1,1,2,1);
  116. bmpHover.ExtendDraw(&memDC,rect,10,10,TRUE);
  117. }
  118. m_hMouseInIcon.TransparentBlt(memDC, m_iconRect.left+2,m_iconRect.top+2,
  119. m_iconRect.Width(), m_iconRect.Height(), RGB(0,0,0));
  120. memDC.SetTextColor(GetBGColor());
  121. memDC.TextOut(m_textPos.x+2,m_textPos.y+2,strText);
  122. }
  123. //DrawButtonText(&dc, rect, str, GetFGColor());
  124. break;
  125. case DOWN:
  126. //DrawFilledRect(&memDC, rect, RGB(0,0,255));
  127. if(m_bmpDown.m_hObject != 0)
  128. m_bmpDown.TransparentBlt(memDC,rect,m_crBack);
  129. if(!m_hMouseOutIcon.IsNull())
  130. {
  131. if(m_bmpIconButton.m_hObject != 0)
  132. {
  133. CEnBitmap bmpDown;
  134. m_bmpIconButton.DrawImage(bmpDown,2,1,2,1);
  135. bmpDown.ExtendDraw(&memDC,rect,10,10,TRUE);
  136. }
  137. m_hMouseOutIcon.TransparentBlt(memDC, m_iconRect.left+3,m_iconRect.top+3,
  138. m_iconRect.Width(), m_iconRect.Height(), RGB(0,0,0));
  139. memDC.SetTextColor(GetBGColor());
  140. memDC.TextOut(m_textPos.x+3,m_textPos.y+3,strText);
  141. }
  142. //DrawButtonText(&dc, rect, str, GetFGColor());
  143. break;
  144. case DISABLE:
  145. if(m_bmpDisable.m_hObject != 0)
  146. m_bmpDisable.TransparentBlt(memDC,rect,m_crBack);
  147. if(!m_hMouseOutIcon.IsNull())
  148. {
  149. m_hMouseOutIcon.TransparentBlt(memDC, m_iconRect.left+2,m_iconRect.top+2,
  150. m_iconRect.Width(), m_iconRect.Height(), RGB(0,0,0));
  151. memDC.SetTextColor(GetFGColor());
  152. memDC.TextOut(m_textPos.x+2,m_textPos.y+2,strText);
  153. }
  154. //DrawButtonText(&dc, rect, str, RGB(128, 128, 128));
  155. break;
  156. default:
  157. break;
  158. }
  159. dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
  160. }
  161. void CSkinButton::DrawFilledRect(CDC *DC, CRect R, COLORREF color)
  162. {
  163. CBrush B;
  164. B.CreateSolidBrush(color);
  165. DC->FillRect(R, &B);
  166. }
  167. void CSkinButton::DrawButtonText(CDC *DC, CRect R, CString str, COLORREF TextColor)
  168. {
  169. COLORREF prevColor = DC->SetTextColor(TextColor);
  170. DC->SetBkMode(TRANSPARENT);
  171. DC->SelectObject(m_pFont);
  172. if(m_hMouseOutIcon.IsNull()&&m_hMouseInIcon.IsNull())
  173. {
  174. //int iconwidth=::GetSystemMetrics(SM_CXICON);
  175. R.right=R.right-m_textPos.x;
  176. DC->DrawText( str, str.GetLength(), R, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
  177. }
  178. else
  179. {
  180. DC->DrawText( str, str.GetLength(), R, DT_RIGHT|DT_VCENTER|DT_SINGLELINE);
  181. }
  182. DC->SetTextColor(prevColor);
  183. }
  184. void CSkinButton::OnMouseMove(UINT nFlags, CPoint point)
  185. {
  186. // TODO: 在此添加消息处理程序代码和/或调用默认值
  187. //if (nFlags & MK_LBUTTON && m_bMouseOver == FALSE)
  188. // return;
  189. if(!m_bMouseOver&&m_bEnabled)
  190. {
  191. m_bMouseOver=true;
  192. m_state = HOVER;
  193. CPoint point;
  194. CRect rect;
  195. GetWindowRect(&rect);
  196. GetCursorPos(&point);
  197. if (!rect.PtInRect(point) && m_bMouseOver&&m_bEnabled)
  198. {
  199. SetTimer(1,10,NULL);
  200. return;
  201. }
  202. DrawButton();
  203. SetTimer(1,10,NULL);
  204. }
  205. CButton::OnMouseMove(nFlags, point);
  206. }
  207. void CSkinButton::OnTimer(UINT_PTR nIDEvent)
  208. {
  209. // TODO: 在此添加消息处理程序代码和/或调用默认值
  210. CPoint point;
  211. CRect rect;
  212. GetWindowRect(&rect);
  213. GetCursorPos(&point);
  214. if (!rect.PtInRect(point) && m_bMouseOver&&m_bEnabled)
  215. {
  216. KillTimer (1);
  217. m_bMouseOver=false;
  218. m_state = NORMAL;
  219. DrawButton();
  220. }
  221. CButton::OnTimer(nIDEvent);
  222. }
  223. void CSkinButton::PreSubclassWindow()
  224. {
  225. // TODO: 在此添加专用代码和/或调用基类
  226. SetOwnerDraw(true);
  227. CButton::PreSubclassWindow();
  228. }
  229. void CSkinButton::SetOwnerDraw(bool IsDraw)
  230. {
  231. if(IsDraw)
  232. {
  233. ModifyStyle(NULL, BS_OWNERDRAW);
  234. Invalidate();
  235. }
  236. else
  237. {
  238. ModifyStyle(BS_OWNERDRAW, NULL);
  239. Invalidate();
  240. }
  241. }
  242. void CSkinButton::SetStatusBmp()
  243. {
  244. if(m_bmpButton.m_hObject != 0)
  245. {
  246. if(m_bmpNormal.m_hObject != NULL) m_bmpNormal.DeleteObject();
  247. if(m_bmpHover.m_hObject != NULL) m_bmpHover.DeleteObject();
  248. if(m_bmpDown.m_hObject != NULL) m_bmpDown.DeleteObject();
  249. if(m_bmpDisable.m_hObject != NULL) m_bmpDisable.DeleteObject();
  250. m_bmpButton.DrawImage(m_bmpNormal,1,1,4,1);
  251. m_bmpButton.DrawImage(m_bmpHover,2,1,4,1);
  252. m_bmpButton.DrawImage(m_bmpDown,3,1,4,1);
  253. m_bmpButton.DrawImage(m_bmpDisable,4,1,4,1);
  254. m_bmpButton.DeleteObject();
  255. }
  256. }
  257. //设置区域和大小
  258. void CSkinButton::ResetButtonSize(BOOL bResetSize)
  259. {
  260. SetWindowRgn(m_bmpNormal.BitmapToRegion(m_crBack), TRUE );
  261. SetWindowPos(NULL,0,0,m_bmpNormal.Width(),m_bmpNormal.Height(),SWP_NOMOVE);
  262. }
  263. void CSkinButton::LoadImage(LPCTSTR szImagePath, COLORREF crBack, BOOL bResetSize)
  264. {
  265. if(m_bmpButton.m_hObject != NULL)
  266. m_bmpButton.DeleteObject();
  267. m_bmpButton.LoadImage(szImagePath,RGB(255,0,255));
  268. m_crBack = crBack;
  269. SetStatusBmp();
  270. ResetButtonSize(bResetSize);
  271. }
  272. void CSkinButton::loadHoverBGBmp(LPCTSTR szImagePath)
  273. {
  274. m_bmpIconButton.LoadImage(szImagePath,RGB(255,0,255));
  275. }
  276. BOOL CSkinButton::LoadBitmap(UINT uIDRes,COLORREF crBack, BOOL bResetSize)
  277. {
  278. if(m_bmpButton.LoadBitmap(uIDRes))
  279. {
  280. m_bmpButton.DrawImage(m_bmpNormal,1,1,4,1);
  281. m_crBack = crBack;
  282. SetStatusBmp();
  283. ResetButtonSize(bResetSize);
  284. return TRUE;
  285. }
  286. return FALSE;
  287. }
  288. void CSkinButton::SetImage(CString strNormal, CString strHover, CString strDown, CString strDisable)
  289. {
  290. m_bmpNormal.LoadImage(strNormal);
  291. m_bmpHover.LoadImage(strHover);
  292. m_bmpDown.LoadImage(strDown);
  293. m_bmpDisable.LoadImage(strDisable);
  294. }
  295. void CSkinButton::SetImage(UINT nNormalID, UINT nHoverID, UINT nDownID, UINT nDisableID)
  296. {
  297. m_bmpNormal.LoadBitmap(nNormalID);
  298. m_bmpNormal.LoadBitmap(nHoverID);
  299. m_bmpNormal.LoadBitmap(nDownID);
  300. m_bmpNormal.LoadBitmap(nDisableID);
  301. }
  302. BOOL CSkinButton::OnEraseBkgnd(CDC* pDC)
  303. {
  304. // TODO: 在此添加消息处理程序代码和/或调用默认值
  305. //保存按钮背景
  306. if(!m_bDCStored)
  307. {
  308. CRect rect;
  309. GetClientRect(&rect);
  310. m_memDC.CreateCompatibleDC (pDC);
  311. CBitmap btScreen;
  312. btScreen.CreateCompatibleBitmap (pDC,rect.Width(),rect.Height());
  313. m_memDC.SelectObject (&btScreen);
  314. m_memDC.BitBlt (0,0,rect.Width(),rect.Height(),pDC,0,0,SRCCOPY);
  315. m_bDCStored=true;
  316. CRgn rgn;
  317. rgn.CreateRectRgn (0, 0, rect.Width(), rect.Height());
  318. SetWindowRgn (rgn, TRUE);
  319. btScreen.DeleteObject();
  320. }
  321. return TRUE;// CButton::OnEraseBkgnd(pDC);//
  322. }
  323. BOOL CSkinButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  324. {
  325. // TODO: 在此添加消息处理程序代码和/或调用默认值
  326. ::SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR_HAND));
  327. return TRUE;
  328. //return CButton::OnSetCursor(pWnd, nHitTest, message);
  329. }
  330. void CSkinButton::SetIcon(CString strMouseOut,CString strMouseIn)
  331. {
  332. m_hMouseOutIcon.Load(strMouseOut);
  333. m_hMouseInIcon.Load(strMouseIn);
  334. SetWindowPos(NULL,0,0,20,20,SWP_NOMOVE);
  335. }
  336. void CSkinButton::SetColor(COLORREF fgcolor,COLORREF bgcolor)
  337. {
  338. m_fg = fgcolor;
  339. m_bg = bgcolor;
  340. DrawButton();
  341. }
  342. void CSkinButton::SetTextPos(CPoint point)
  343. {
  344. m_textPos = point;
  345. DrawButton();
  346. }
  347. CRect CSkinButton::GetRectInParent()
  348. {
  349. CRect rcWindowParent;
  350. GetParent()->GetWindowRect(rcWindowParent);//client
  351. CRect rcWindow;
  352. GetWindowRect(&rcWindow);
  353. CRect rect;
  354. rect.left = rcWindow.left-rcWindowParent.left;
  355. rect.top = rcWindow.top-rcWindowParent.top;
  356. rect.right = rcWindow.right-rcWindowParent.left;
  357. rect.bottom = rcWindow.bottom-rcWindowParent.top;
  358. return rect;
  359. }
  360. void CSkinButton::OnEnable(BOOL bEnable)
  361. {
  362. CButton::OnEnable(bEnable);
  363. // TODO: 在此处添加消息处理程序代码
  364. if(bEnable)
  365. m_bEnabled = true;
  366. else
  367. m_bEnabled = false;
  368. }