#include "stdafx.h" #include "SkinButton.h" // CSkinButton #define IDC_CURSOR_HAND 132 IMPLEMENT_DYNAMIC(CSkinButton, CButton) CSkinButton::CSkinButton() { m_state = NORMAL; m_pFont = new CFont(); m_pFont->CreatePointFont(90, _T("Arial")); m_fg = RGB(0, 0, 0); m_bg = RGB(255, 255, 255); m_crBack = RGB(255, 0, 255); m_bMouseOver = false; m_bEnabled = true; m_bDCStored = false; m_bShowOwnerText = FALSE; m_textPos = CPoint(0, 0); m_iconRect = CRect(0, 0, 16, 16); m_bmpIconButton.LoadImage(_T("Skin\\IconButton.bmp")); } CSkinButton::~CSkinButton() { delete m_pFont; m_memDC.DeleteDC(); } BEGIN_MESSAGE_MAP(CSkinButton, CButton) ON_WM_MOUSEMOVE() ON_WM_TIMER() ON_WM_ERASEBKGND() ON_WM_SETCURSOR() ON_WM_ENABLE() ON_WM_LBUTTONUP() END_MESSAGE_MAP() void CSkinButton::DrawItem(LPDRAWITEMSTRUCT lpDIS) { //CDC* pDC = CDC::FromHandle(lpDIS->hDC); UINT state = lpDIS->itemState; //CRect rect; //rect.CopyRect(&lpDIS->rcItem); m_state = NORMAL; if (state & ODS_FOCUS) { if (state & ODS_SELECTED) { m_state = DOWN; } else { if (m_bMouseOver) m_state = HOVER; } } else { m_state = NORMAL; } if (state & ODS_DISABLED) { m_state = DISABLE; m_bEnabled = false; } DrawButton(); } void CSkinButton::DrawButton() { CClientDC dc(this); CRect rect; GetClientRect(&rect); CDC memDC; memDC.CreateCompatibleDC(&dc); CBitmap Screen; Screen.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height()); memDC.SelectObject(&Screen); Screen.DeleteObject(); //画背景; memDC.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &m_memDC, 0, 0, SRCCOPY); CString strText; GetWindowText(strText); memDC.SetBkMode(TRANSPARENT); memDC.SelectObject(m_pFont); switch (m_state) { case NORMAL: { //memDC.TextOutW(m_textPos.x,m_textPos.y,str); if (m_bmpNormal.m_hObject != 0) m_bmpNormal.TransparentBlt(memDC, rect, m_crBack); if (!m_hMouseOutIcon.IsNull()) { m_hMouseOutIcon.TransparentBlt(memDC, m_iconRect.left + 2, m_iconRect.top + 2, m_iconRect.Width(), m_iconRect.Height(), RGB(0, 0, 0)); memDC.SetTextColor(GetFGColor()); memDC.TextOut(m_textPos.x + 2, m_textPos.y + 2, strText); _tprintf(_T("Normal-Icon:%d,%d\n"), m_textPos.x + 2, m_textPos.y + 2); } else if (m_bShowOwnerText) { DrawButtonText(&memDC, rect, strText, GetFGColor()); _tprintf(_T("Normal-UnIcon:%d,%d,%d,%d\n"), rect.left, rect.top, rect.right, rect.bottom); } } break; case HOVER: { //DrawFilledRect(&memDC, rect, RGB(255,255,0)); if (m_bmpHover.m_hObject != 0) m_bmpHover.TransparentBlt(memDC, rect, m_crBack); if (!m_hMouseInIcon.IsNull()) { if (m_bmpIconButton.m_hObject != 0) { CEnBitmap bmpHover; m_bmpIconButton.DrawImage(bmpHover, 1, 1, 2, 1); bmpHover.ExtendDraw(&memDC, rect, 10, 10, TRUE); } m_hMouseInIcon.TransparentBlt(memDC, m_iconRect.left + 2, m_iconRect.top + 2, m_iconRect.Width(), m_iconRect.Height(), RGB(0, 0, 0)); memDC.SetTextColor(GetBGColor()); memDC.TextOut(m_textPos.x + 2, m_textPos.y + 2, strText); _tprintf(_T("Hover-Icon:%d,%d\n"), m_textPos.x + 2, m_textPos.y + 2); } else if (m_bShowOwnerText) { rect.OffsetRect(-1, -1); DrawButtonText(&memDC, rect, strText, GetFGColor()); _tprintf(_T("Hover-UnIcon:%d,%d,%d,%d\n"), rect.left, rect.top, rect.right, rect.bottom); rect.OffsetRect(1, 1); } } break; case DOWN: { //DrawFilledRect(&memDC, rect, RGB(0,0,255)); if (m_bmpDown.m_hObject != 0) m_bmpDown.TransparentBlt(memDC, rect, m_crBack); if (!m_hMouseOutIcon.IsNull()) { if (m_bmpIconButton.m_hObject != 0) { CEnBitmap bmpDown; m_bmpIconButton.DrawImage(bmpDown, 2, 1, 2, 1); bmpDown.ExtendDraw(&memDC, rect, 10, 10, TRUE); } m_hMouseOutIcon.TransparentBlt(memDC, m_iconRect.left + 3, m_iconRect.top + 3, m_iconRect.Width(), m_iconRect.Height(), RGB(0, 0, 0)); memDC.SetTextColor(GetBGColor()); memDC.TextOut(m_textPos.x + 3, m_textPos.y + 3, strText); _tprintf(_T("Down-Icon:%d,%d\n"), m_textPos.x + 2, m_textPos.y + 2); } else if (m_bShowOwnerText) { rect.OffsetRect(1, 1); DrawButtonText(&memDC, rect, strText, GetFGColor()); _tprintf(_T("Down-UnIcon:%d,%d,%d,%d\n"), rect.left, rect.top, rect.right, rect.bottom); rect.OffsetRect(-1, -1); } } break; case DISABLE: { if (m_bmpDisable.m_hObject != 0) m_bmpDisable.TransparentBlt(memDC, rect, m_crBack); if (!m_hMouseOutIcon.IsNull()) { m_hMouseOutIcon.TransparentBlt(memDC, m_iconRect.left + 2, m_iconRect.top + 2, m_iconRect.Width(), m_iconRect.Height(), RGB(0, 0, 0)); memDC.SetTextColor(GetFGColor()); memDC.TextOut(m_textPos.x + 2, m_textPos.y + 2, strText); } else if (m_bShowOwnerText) DrawButtonText(&memDC, rect, strText, RGB(128, 128, 128)); } break; default: break; } dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY); ::DeleteDC(memDC); } void CSkinButton::DrawFilledRect(CDC *DC, CRect R, COLORREF color) { CBrush B; B.CreateSolidBrush(color); DC->FillRect(R, &B); } void CSkinButton::DrawButtonText(CDC *DC, CRect R, CString str, COLORREF TextColor) { COLORREF prevColor = DC->SetTextColor(TextColor); DC->SetBkMode(TRANSPARENT); DC->SelectObject(m_pFont); if (m_hMouseOutIcon.IsNull() && m_hMouseInIcon.IsNull()) { //int iconwidth=::GetSystemMetrics(SM_CXICON); R.right = R.right - m_textPos.x; _tprintf(_T("DrawText:%d\n"), m_textPos.x); DC->DrawText(str, str.GetLength(), R, DT_CENTER | DT_VCENTER | DT_SINGLELINE); } else { DC->DrawText(str, str.GetLength(), R, DT_RIGHT | DT_VCENTER | DT_SINGLELINE); } DC->SetTextColor(prevColor); } void CSkinButton::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 //if (nFlags & MK_LBUTTON && m_bMouseOver == FALSE) // return; if (!m_bMouseOver&&m_bEnabled) { m_bMouseOver = true; m_state = HOVER; CPoint point; CRect rect; GetWindowRect(&rect); GetCursorPos(&point); if (!rect.PtInRect(point) && m_bMouseOver&&m_bEnabled) { SetTimer(1, 10, NULL); return; } DrawButton(); SetTimer(1, 10, NULL); } CButton::OnMouseMove(nFlags, point); } void CSkinButton::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CPoint point; CRect rect; GetWindowRect(&rect); GetCursorPos(&point); if (!rect.PtInRect(point) && m_bMouseOver&&m_bEnabled) { KillTimer(1); m_bMouseOver = false; m_state = NORMAL; DrawButton(); } CButton::OnTimer(nIDEvent); } void CSkinButton::PreSubclassWindow() { // TODO: 在此添加专用代码和/或调用基类 SetOwnerDraw(true); CButton::PreSubclassWindow(); } void CSkinButton::SetOwnerDraw(bool IsDraw) { if (IsDraw) { ModifyStyle(NULL, BS_OWNERDRAW); Invalidate(); } else { ModifyStyle(BS_OWNERDRAW, NULL); Invalidate(); } } void CSkinButton::SetStatusBmp() { if (m_bmpButton.m_hObject != 0) { if (m_bmpNormal.m_hObject != NULL) m_bmpNormal.DeleteObject(); if (m_bmpHover.m_hObject != NULL) m_bmpHover.DeleteObject(); if (m_bmpDown.m_hObject != NULL) m_bmpDown.DeleteObject(); if (m_bmpDisable.m_hObject != NULL) m_bmpDisable.DeleteObject(); m_bmpButton.DrawImage(m_bmpNormal, 1, 1, 4, 1); m_bmpButton.DrawImage(m_bmpHover, 2, 1, 4, 1); m_bmpButton.DrawImage(m_bmpDown, 3, 1, 4, 1); m_bmpButton.DrawImage(m_bmpDisable, 4, 1, 4, 1); m_bmpButton.DeleteObject(); } } //设置区域和大小 void CSkinButton::ResetButtonSize(BOOL bResetSize) { SetWindowRgn(m_bmpNormal.BitmapToRegion(m_crBack), TRUE); SetWindowPos(NULL, 0, 0, m_bmpNormal.Width(), m_bmpNormal.Height(), SWP_NOMOVE); } void CSkinButton::LoadImage(LPCTSTR szImagePath, COLORREF crBack, BOOL bResetSize) { if (m_bmpButton.m_hObject != NULL) m_bmpButton.DeleteObject(); m_bmpButton.LoadImage(szImagePath, RGB(255, 0, 255)); m_crBack = crBack; SetStatusBmp(); ResetButtonSize(bResetSize); } void CSkinButton::loadHoverBGBmp(LPCTSTR szImagePath) { m_bmpIconButton.LoadImage(szImagePath, RGB(255, 0, 255)); } BOOL CSkinButton::LoadBitmap(UINT uIDRes, COLORREF crBack, BOOL bResetSize) { if (m_bmpButton.LoadBitmap(uIDRes)) { m_bmpButton.DrawImage(m_bmpNormal, 1, 1, 4, 1); m_crBack = crBack; SetStatusBmp(); ResetButtonSize(bResetSize); return TRUE; } return FALSE; } void CSkinButton::SetImage(CString strNormal, CString strHover, CString strDown, CString strDisable) { m_bmpNormal.LoadImage(strNormal); m_bmpHover.LoadImage(strHover); m_bmpDown.LoadImage(strDown); m_bmpDisable.LoadImage(strDisable); } void CSkinButton::SetImage(UINT nNormalID, UINT nHoverID, UINT nDownID, UINT nDisableID) { m_bmpNormal.LoadBitmap(nNormalID); m_bmpHover.LoadBitmap(nHoverID); m_bmpDown.LoadBitmap(nDownID); m_bmpDisable.LoadBitmap(nDisableID); } BOOL CSkinButton::OnEraseBkgnd(CDC* pDC) { // TODO: 在此添加消息处理程序代码和/或调用默认值 //保存按钮背景 if (!m_bDCStored) { CRect rect; GetClientRect(&rect); m_memDC.CreateCompatibleDC(pDC); CBitmap btScreen; btScreen.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()); m_memDC.SelectObject(&btScreen); m_memDC.BitBlt(0, 0, rect.Width(), rect.Height(), pDC, 0, 0, SRCCOPY); m_bDCStored = true; CRgn rgn; rgn.CreateRectRgn(0, 0, rect.Width(), rect.Height()); SetWindowRgn(rgn, TRUE); btScreen.DeleteObject(); } return TRUE;// CButton::OnEraseBkgnd(pDC);// } BOOL CSkinButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: 在此添加消息处理程序代码和/或调用默认值 ::SetCursor(AfxGetApp()->LoadCursor(IDC_CURSOR_HAND)); return TRUE; //return CButton::OnSetCursor(pWnd, nHitTest, message); } void CSkinButton::SetIcon(CString strMouseOut, CString strMouseIn) { m_hMouseOutIcon.Load(strMouseOut); m_hMouseInIcon.Load(strMouseIn); SetWindowPos(NULL, 0, 0, 20, 20, SWP_NOMOVE); } void CSkinButton::SetColor(COLORREF fgcolor, COLORREF bgcolor) { m_fg = fgcolor; m_bg = bgcolor; DrawButton(); } void CSkinButton::SetTextPos(CPoint point) { m_textPos = point; DrawButton(); } CRect CSkinButton::GetRectInParent() { CRect rcWindowParent; GetParent()->GetWindowRect(rcWindowParent);//client CRect rcWindow; GetWindowRect(&rcWindow); CRect rect; rect.left = rcWindow.left - rcWindowParent.left; rect.top = rcWindow.top - rcWindowParent.top; rect.right = rcWindow.right - rcWindowParent.left; rect.bottom = rcWindow.bottom - rcWindowParent.top; return rect; } void CSkinButton::OnEnable(BOOL bEnable) { CButton::OnEnable(bEnable); // TODO: 在此处添加消息处理程序代码 if (bEnable) m_bEnabled = true; else m_bEnabled = false; }