// PushButton.cpp : 实现文件 // #include "stdafx.h" #include "PushButton.h" #include "CacheDC.h" // CPushButton IMPLEMENT_DYNAMIC(CPushButton, CButton) CPushButton::CPushButton() : m_strPathIcon(_T("")) , m_bSelected(FALSE) { m_bkColor = RGB(65, 188, 131); // 文本按钮的背景颜色 m_pImage = nullptr; // 位图按钮的背景图片 m_bHover = m_bPress = m_bFocus = m_bMouseTracking = FALSE; // 初始化鼠标的相关状态 m_bEnable = TRUE; m_nRounded = 3; // 圆角的大小 m_dwStyle = WS_VISIBLE | WS_CHILD | BS_CENTER | BS_VCENTER; // 按钮样式 m_bFillet = TRUE; m_image = nullptr; // 初始化字体 m_font.CreatePointFont(110 ,L"微软雅黑"); } CPushButton::~CPushButton() { if(m_pImage != nullptr) delete m_pImage; if(m_image != nullptr) delete m_image; } BEGIN_MESSAGE_MAP(CPushButton, CButton) ON_WM_PAINT() ON_WM_SETCURSOR() ON_WM_MOUSEMOVE() ON_WM_MOUSEHOVER() ON_WM_MOUSELEAVE() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_ERASEBKGND() END_MESSAGE_MAP() // CPushButton 消息处理程序 BOOL CPushButton::Create(CWnd* pParentWnd, UINT nID, CRect& rect, DWORD btnType, LPCTSTR lpszCaption ,COLORREF bkColor/* = RGB(65,188,131)*/ ,COLORREF fontColor/* = RGB(255,255,255)*/ ,COLORREF bordercolor/* = NULL*/) { // TODO: 在此添加专用代码和/或调用基类 m_btn_type = btnType; m_bkColor = bkColor; m_fontcolor = fontColor; if(bordercolor == NULL) m_bordercolor = m_bkColor; if (m_btn_type&BUTTON_TYPE_IMAGE) m_pImage = new CImageEx(lpszCaption); if (m_btn_type&BUTTON_TYPE_SUPTAB) m_dwStyle |= WS_TABSTOP; m_lpszText = lpszCaption; if (m_btn_type&BUTTON_TYPE_IMAGE) { lpszCaption = L""; m_lpszText= L""; } if (m_btn_type&BUTTON_TYPE_IMAGE2 && m_strPathIcon != "") { m_image = new CImageEx(m_strPathIcon); } BOOL ret = CButton::Create(lpszCaption, m_dwStyle, rect, pParentWnd, nID); if (m_btn_type&BUTTON_TYPE_TEXT && m_bFillet) { // 裁剪成圆角按钮 CRgn rgnClient; rgnClient.CreateRoundRectRgn(0,0,rect.Width(),rect.Height(),m_nRounded,m_nRounded); SetWindowRgn(rgnClient,TRUE); } return ret; } BOOL CPushButton::Create(CWnd* pParentWnd, UINT nID, CPoint& point, CSize& size, DWORD btnType, LPCTSTR lpszCaption ,COLORREF bkColor/* = RGB(65,188,131)*/ ,COLORREF fontColor/* = RGB(65,188,131)*/ ,COLORREF bordercolor/* = NULL*/) { return Create(pParentWnd,nID,CRect(point.x, point.y, point.x + size.cx, point.y + size.cy),btnType,lpszCaption,bkColor,fontColor,bordercolor); } void CPushButton::OnPaint() { CPaintDC dc(this); CRect rcClient; GetClientRect(rcClient); CCacheDC pCacheDC(&dc,rcClient); if(m_btn_type&BUTTON_TYPE_TEXT) DrawTextButton(pCacheDC,rcClient); else if(m_btn_type&BUTTON_TYPE_ICON) DrawIconButton(pCacheDC,rcClient); else if (m_btn_type&BUTTON_TYPE_IMAGE) DrawBitmapButton(pCacheDC,rcClient); else if (m_btn_type&BUTTON_TYPE_IMAGE2) DrawIconButton2(pCacheDC,rcClient); } void CPushButton::DrawTextButton(CDC* pDC, CRect& rcClient) { ////////////////////////////////////////////////////////////////////////// // 设置按钮背景颜色 // 获取背景颜色值 BYTE bkRed = GetRValue(m_bkColor); BYTE bkGreen = GetGValue(m_bkColor); BYTE bkBlue = GetBValue(m_bkColor); // 获取文本颜色 BYTE fontRed = GetRValue(m_fontcolor); BYTE fontGreen = GetGValue(m_fontcolor); BYTE fontBlue = GetBValue(m_fontcolor); // 获取边框颜色 BYTE borderRed = GetRValue(m_bordercolor); BYTE borderGreen = GetGValue(m_bordercolor); BYTE borderBlue = GetBValue(m_bordercolor); COLORREF fontColor, bkColor, borderColor; if(!m_bEnable) { fontColor = RGB(150,150,150); bkColor = RGB(200,200,200); borderColor = RGB(200,200,200); } else if(m_bHover) { fontColor = RGB(fontRed, fontGreen, fontBlue); if(m_bPress) { bkColor = RGB(bkRed-10, bkGreen-10, bkBlue-10); borderColor = RGB(borderRed - 10, borderGreen - 10, borderBlue - 10); } else { bkColor = RGB(bkRed+10, bkGreen+10, bkBlue+10); borderColor = RGB(borderRed + 10, borderGreen + 10, borderBlue + 10); } } else { bkColor = RGB(bkRed,bkGreen,bkBlue); fontColor = RGB(fontRed,fontGreen,fontBlue); borderColor = RGB(borderRed,borderGreen,borderBlue); } if(m_bFillet) { // 画圆角背景 CRgn rgnClient; rgnClient.CreateRoundRectRgn(0,0,rcClient.Width(),rcClient.Height(),m_nRounded,m_nRounded); pDC->FillRgn(&rgnClient,&CBrush(bkColor)); pDC->FrameRgn(&rgnClient,&CBrush(borderColor),1,1); } else { pDC->FillSolidRect(rcClient,bkColor); pDC->FrameRect(rcClient,&CBrush(borderColor)); } ////////////////////////////////////////////////////////////////////////// // 画文本 // 修改文本显示区域(实现按下的效果) if(m_bPress) { rcClient.left += 2; rcClient.top += 2; } pDC->SelectObject(m_font); pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(fontColor); // 获取按钮文本 CString sText; GetWindowText(sText); pDC->DrawText(sText,rcClient,DT_VCENTER|DT_CENTER|DT_SINGLELINE|DT_END_ELLIPSIS); } void CPushButton::DrawIconButton2(CDC* pDC, CRect& rcClient) { INT nWidth = rcClient.Width(); INT nLeft = 0; if(m_bSelected) { nLeft = m_bSelected ? nWidth * -1 : m_bHover ? nWidth * 1 * -1: 0; } else { nLeft = m_bSelected ? nWidth * 2 * -1 : m_bHover ? nWidth * 1 * -1: 0; } m_image->DrawImage(pDC,nLeft,rcClient.top); } void CPushButton::DrawIconButton(CDC* pDC, CRect& rcClient) { ////////////////////////////////////////////////////////////////////////// // 设置按钮背景颜色 // 获取背景颜色值 BYTE bkRed = GetRValue(m_bkColor); BYTE bkGreen = GetGValue(m_bkColor); BYTE bkBlue = GetBValue(m_bkColor); // 获取文本颜色 BYTE fontRed = GetRValue(m_fontcolor); BYTE fontGreen = GetGValue(m_fontcolor); BYTE fontBlue = GetBValue(m_fontcolor); // 获取边框颜色 BYTE borderRed = GetRValue(m_bordercolor); BYTE borderGreen = GetGValue(m_bordercolor); BYTE borderBlue = GetBValue(m_bordercolor); COLORREF fontColor, bkColor, borderColor; if(!m_bEnable) { fontColor = RGB(50,50,50); bkColor = RGB(200,200,200); borderColor = RGB(200,200,200); } else if(m_bHover) { fontColor = RGB(fontRed, fontGreen, fontBlue); if(m_bPress) { bkColor = RGB(bkRed-10, bkGreen-10, bkBlue-10); borderColor = RGB(borderRed - 10, borderGreen - 10, borderBlue - 10); } else { bkColor = RGB(bkRed+10, bkGreen+10, bkBlue+10); borderColor = RGB(borderRed + 10, borderGreen + 10, borderBlue + 10); } } else { bkColor = RGB(bkRed,bkGreen,bkBlue); fontColor = RGB(fontRed,fontGreen,fontBlue); borderColor = RGB(borderRed,borderGreen,borderBlue); } if(m_bFillet) { // 画圆角背景 CRgn rgnClient; rgnClient.CreateRoundRectRgn(0,0,rcClient.Width(),rcClient.Height(),m_nRounded,m_nRounded); pDC->FillRgn(&rgnClient,&CBrush(bkColor)); pDC->FrameRgn(&rgnClient,&CBrush(borderColor),1,1); } else { pDC->FillSolidRect(rcClient,bkColor); pDC->FrameRect(rcClient,&CBrush(borderColor)); } if(m_bSelected) { CRgn rgnClient; rgnClient.CreateRoundRectRgn(0,0,rcClient.Width(),rcClient.Height(),m_nRounded,m_nRounded); pDC->FillRgn(&rgnClient,&CBrush(RGB(19,94,64))); pDC->FrameRgn(&rgnClient,&CBrush(borderColor),1,1); } else { CRgn rgnClient; rgnClient.CreateRoundRectRgn(0,0,rcClient.Width(),rcClient.Height(),m_nRounded,m_nRounded); pDC->FillRgn(&rgnClient,&CBrush(RGB(25,174,104))); pDC->FrameRgn(&rgnClient,&CBrush(borderColor),1,1); } Graphics graphics( pDC->m_hDC); Image image(m_strPathIcon, FALSE); graphics.DrawImage(&image,rcClient.left,rcClient.top); ////////////////////////////////////////////////////////////////////////// // 画文本 // 修改文本显示区域(实现按下的效果) if(m_bPress) { rcClient.left += 2; rcClient.top += 2; } pDC->SelectObject(m_font); pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(fontColor); // 获取按钮文本 CString sText; GetWindowText(sText); if(pDC->GetTextExtent(sText).cx < rcClient.Width()) { pDC->DrawText(sText,rcClient,DT_CENTER|DT_BOTTOM|DT_SINGLELINE|DT_END_ELLIPSIS); } else { CFont font; font.CreatePointFont(80,L"微软雅黑"); CFont *font1; font1 = pDC->SelectObject(&font); pDC->DrawText(sText,rcClient,DT_CENTER|DT_BOTTOM|DT_SINGLELINE|DT_END_ELLIPSIS); pDC->SelectObject(font1); // 复原画笔 font.DeleteObject(); } } void CPushButton::DrawBitmapButton(CDC* pDC, CRect& rcClient) { // 绘画背景图案 if(m_bHover) { m_pImage->DrawImage(pDC,rcClient.Width() * (m_bPress ? 2 : 1) * -1, 0); } else { m_pImage->DrawImage(pDC,0,0); } } BOOL CPushButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) { // TODO: 在此添加消息处理程序代码和/或调用默认值 ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_HAND)); //return CButton::OnSetCursor(pWnd, nHitTest, message); return TRUE; } void CPushButton::OnMouseMove(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (!m_bMouseTracking){ TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwFlags = TME_LEAVE | TME_HOVER; tme.dwHoverTime = 1; m_bMouseTracking = _TrackMouseEvent(&tme); } //CButton::OnMouseMove(nFlags, point); } void CPushButton::OnMouseHover(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_bHover = m_bMouseTracking = TRUE; Invalidate(); //CButton::OnMouseHover(nFlags, point); } void CPushButton::OnMouseLeave() { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_bHover = m_bMouseTracking = FALSE; Invalidate(); //CButton::OnMouseLeave(); } void CPushButton::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_bPress = TRUE; this->SetFocus(); Invalidate(); SetCapture(); //CButton::OnLButtonDown(nFlags, point); } static DWORD g_tick_count =0; void CPushButton::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 m_bPress = FALSE; Invalidate(); ReleaseCapture(); CRect rcClient; GetClientRect(rcClient); if(rcClient.PtInRect(point)) { if (g_tick_count - GetTickCount()> 250 || g_tick_count == 0){ this->GetParent()->PostMessage(WM_BUTTON_CLICKED,(WPARAM)this->GetDlgCtrlID(),0); g_tick_count = GetTickCount(); } } } void CPushButton::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 // 取消按钮的双击事件 //CButton::OnLButtonDblClk(nFlags, point); } void CPushButton::PreSubclassWindow() { // TODO: 在此添加专用代码和/或调用基类 CButton::PreSubclassWindow(); } BOOL CPushButton::PreTranslateMessage(MSG* pMsg) { // TODO: 在此添加专用代码和/或调用基类 if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN) { this->GetParent()->PostMessage(WM_BUTTON_CLICKED,(WPARAM)this->GetDlgCtrlID(),0); return TRUE; } return CButton::PreTranslateMessage(pMsg); } void CPushButton::EnableWindow(BOOL bEnable/* = TRUE*/) { m_bEnable = bEnable; // 禁用前,先绘制禁用时的样式(禁用后,就无效了) if(!bEnable) Invalidate(); CButton::EnableWindow(bEnable); // 启用后,在绘制一次,不然会以系统默认状态显示 if(bEnable) Invalidate(); } void CPushButton::SetWindowText(LPCTSTR lpszString) { m_lpszText = lpszString; Invalidate(FALSE); } void CPushButton::GetWindowText(CString& rString) { rString = m_lpszText; } // 当画图板中某个功能被选择时,用于设置其背景色为绿色;当失去功能时,显示为白色 void CPushButton::setBkColor(BOOL bSelected) { m_bSelected = bSelected; Invalidate(false); } void CPushButton::SetBkColor(COLORREF bk) { m_bkColor=bk; Invalidate(TRUE); }