vc 按钮自绘

来源:互联网 发布:华为官网下载软件 编辑:程序博客网 时间:2024/05/22 16:24

按钮自绘,将按钮区域分成三部分,左边、右边、中间都由贴图绘制,可用于手动进度条按钮,或者左右选择项按钮

cpp代码部分:

 

// LRSkinButton.cpp : implementation file//#include "stdafx.h"#include "CRedrawButtonDemo.h"#include "LRSkinButton.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CLRSkinButtonCLRSkinButton::CLRSkinButton(){m_nWidth = 17;m_nHeight = 16;m_bDrawBorder = TRUE;}CLRSkinButton::~CLRSkinButton(){}BEGIN_MESSAGE_MAP(CLRSkinButton, CButton)//{{AFX_MSG_MAP(CLRSkinButton)// NOTE - the ClassWizard will add and remove mapping macros here.//}}AFX_MSG_MAPON_WM_CAPTURECHANGED()ON_WM_MOUSEMOVE()ON_WM_SETCURSOR()ON_WM_KILLFOCUS()END_MESSAGE_MAP()void CLRSkinButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ){//TRACE("DrawItem\n");// TODO:  添加您的代码以绘制指定项CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);HDC hDC = pDC->GetSafeHdc();// 按钮客户区域CRect rectItem(lpDrawItemStruct->rcItem);m_nHeight = rectItem.Height();m_nWidth = 26;CRect rectCenter(rectItem.left+m_nWidth, rectItem.top, rectItem.right-m_nWidth, rectItem.bottom);CRect rectLeft(rectItem.left, rectItem.top, rectItem.left+m_nWidth, rectItem.top+m_nHeight);CRect rectRight(rectItem.right-m_nWidth,rectItem.top,rectItem.right,rectItem.bottom);static int nClrWidth = rectCenter.Width()/10;CRect rectColor(rectCenter.left, rectCenter.top, rectCenter.left, rectCenter.bottom);rectCenter.DeflateRect(0,1,0,1);//pDC->SetBkMode(TRANSPARENT);HPEN hOldPen;UINT action, state;action = lpDrawItemStruct->itemAction;state  = lpDrawItemStruct->itemState;BOOL bIsPressed, bIsFocus, bIsDisabled;bIsPressed = state & ODS_SELECTED;bIsDisabled = state & ODS_DISABLED;bIsFocus = (state & ODS_FOCUS) == ODS_FOCUS; // ::GetFocus() == m_hWnd;::SetBkColor(hDC, RGB(22, 33, 55));// Draw pressed buttonif (bIsPressed){// 按钮按下状态/*HPEN penBtnHiLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));//COLOR_3DLIGHT)); // BiancoHPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));   // Grigio scuro// draw darkline of left-top connerhOldPen = (HPEN)SelectObject(hDC,penBtnShadow);MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);LineTo(hDC,rectItem.left, rectItem.top);LineTo(hDC,rectItem.right, rectItem.top);// draw hilight line of right-bottom connerSelectObject(hDC,penBtnHiLight);MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);LineTo(hDC,rectItem.right-1, rectItem.bottom-1);LineTo(hDC,rectItem.right-1, rectItem.top-1);//release resourceSelectObject(hDC,hOldPen);DeleteObject(penBtnShadow);DeleteObject(penBtnHiLight);*/// 判断点击的是左区域还是右区域POINT pos;GetCursorPos( &pos );ScreenToClient(&pos);if (PtInRect( &rectLeft, pos)){// 左键TRACE(_T("Clicked Left...\n"));nClrWidth -= 5;if (nClrWidth <=0){nClrWidth = 0;}}if (PtInRect( &rectRight, pos)){// 右键TRACE(_T("Clicked Right...\n"));nClrWidth += 5;if (nClrWidth >= rectCenter.Width()){nClrWidth = rectCenter.Width();}}}else // ...else draw non pressed button{ if(!m_bIsFlat || (m_bIsFlat && m_MouseOnButton)) {// 鼠标移动到按钮上面时的状态/*HPEN pen3DLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));//COLOR_3DLIGHT));       // Light grayHPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));   // Dark gray// White linehOldPen = (HPEN)SelectObject(hDC,pen3DLight);MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);LineTo(hDC,rectItem.left, rectItem.top);LineTo(hDC,rectItem.right, rectItem.top);// Dark gray lineSelectObject(hDC,penBtnShadow);MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);LineTo(hDC,rectItem.right-1, rectItem.bottom-1);LineTo(hDC,rectItem.right-1, rectItem.top-1);//SelectObject(hDC,hOldPen);DeleteObject(pen3DLight); DeleteObject(penBtnShadow);*/}else{// FLAT 属性if(m_bDrawBorder){ // 失去焦点的时候绘制按钮边框HPEN penBorder = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));hOldPen = (HPEN)SelectObject(hDC,penBorder);SelectObject(hDC,GetStockObject(NULL_BRUSH));// 绘制按钮边框Rectangle(hDC,rectItem.left, rectItem.top, rectItem.right, rectItem.bottom);SelectObject(hDC, hOldPen);DeleteObject(penBorder);}}    }// if (lpDrawItemStruct->itemData != NULL)// {// 画图标CRect rect(rectCenter);//rect.DeflateRect(0,5,0,0); // 改变矩形范围CDC dcMem;dcMem.CreateCompatibleDC(pDC);// 背景图CBitmap bmp;BITMAP bitmap;bmp.LoadBitmap(m_nBmpBK);bmp.GetBitmap( &bitmap );CBitmap* pOldBmp = dcMem.SelectObject(&bmp);pDC->StretchBlt(rectCenter.left, rectCenter.top, rectCenter.Width(), rectCenter.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);bmp.DeleteObject();// 左按钮图bmp.LoadBitmap( m_nBmpLeft );dcMem.SelectObject( &bmp );bmp.GetBitmap( &bitmap );//pDC->BitBlt(rectLeft.left,rectLeft.top,rectLeft.Width(),rectLeft.Height(),&dcMem,0,0,SRCCOPY);pDC->StretchBlt(rectLeft.left, rectLeft.top, rectLeft.Width(), rectLeft.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);bmp.DeleteObject();// 右按钮图bmp.LoadBitmap( m_nBmpRight );bmp.GetBitmap( &bitmap );dcMem.SelectObject( &bmp );//pDC->BitBlt(rectRight.left,rectRight.top,rectRight.Width(),rectRight.Height(),&dcMem,0,0,SRCCOPY);pDC->StretchBlt(rectRight.left, rectRight.top, rectRight.Width(), rectRight.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);bmp.DeleteObject();dcMem.SelectObject(pOldBmp);// 绘制颜色进度条bmp.LoadBitmap(IDB_BMP_BTNLEFT);//CBrush brush(&bmp);   //RGB(255, 255, 0)CBrush brush(RGB(255, 255, 0));   //rectColor.right = rectColor.left+nClrWidth;pDC->FillRect(rectColor, &brush);// CBrush *pOldBrush = (CBrush*)pDC->SelectObject(&brush);// pDC->Rectangle(&rectColor);// pDC->SelectObject(pOldBrush);bmp.DeleteObject();// 绘制文字rect = rectCenter;//rect.DeflateRect(0,5,0,0);  // 调整矩形大小rect.InflateRect(0,1,0,1);pDC->SetTextColor(RGB(0,0,0));//rect.OffsetRect(2,1); // 平行移动矩形位置//char zsCaption[64] = {0};CString str;GetWindowText( str );COLORREF clr = GetSysColor( COLOR_3DHILIGHT);clr = RGB(55, 155, 55);if (bIsPressed){clr = RGB(155, 55, 55);}else if (bIsFocus /*|| m_MouseOnButton*/){clr = RGB(55, 55, 155);HPEN penBorder = CreatePen(PS_SOLID, 1, RGB(255,0,255));hOldPen = (HPEN)SelectObject(hDC,penBorder);SelectObject(hDC,GetStockObject(NULL_BRUSH));// 绘制按钮边框Rectangle(hDC,rect.left, rect.top, rect.right, rect.bottom);SelectObject(hDC, hOldPen);DeleteObject(penBorder);}pDC->SetBkColor(clr);pDC->SetTextColor( RGB(255, 0, 0) );pDC->DrawText(str, str.GetLength(),rect, DT_CENTER | DT_VCENTER| DT_SINGLELINE);//}}void CLRSkinButton::SetBtnBmps( UINT uBmpBK, UINT uBmpLeft, UINT uBmpRight ){m_nBmpBK = uBmpBK;m_nBmpLeft = uBmpLeft;m_nBmpRight = uBmpRight;}void CLRSkinButton::PreSubclassWindow(){UINT nBS = GetButtonStyle();if(nBS & BS_DEFPUSHBUTTON)m_bDefaultBtn = TRUE;elsem_bDefaultBtn = FALSE;SetButtonStyle(nBS | BS_OWNERDRAW);CButton::PreSubclassWindow();}/////////////////////////////////////////////////////////////////////////////// CLRSkinButton message handlersvoid CLRSkinButton::OnCaptureChanged(CWnd *pWnd) {if(m_MouseOnButton == TRUE){ReleaseCapture();Invalidate();}CButton::OnCaptureChanged(pWnd);}void CLRSkinButton::OnMouseMove(UINT nFlags, CPoint point) {CButton::OnMouseMove(nFlags, point);HWND hParent; // Finestra che contiene il bottone// If the mouse enter the button with the left button pressed then do nothingif (nFlags & MK_LBUTTON && !m_MouseOnButton) return;// If our button is not flat then do nothingif (m_bIsFlat) {hParent = ::GetParent(m_hWnd);if ((::GetCapture() != m_hWnd) &&(hParent != NULL)) {m_MouseOnButton = TRUE;SetCapture();Invalidate();}else{RECT rc;GetClientRect(&rc);if (!PtInRect(&rc,point)){// Redraw only if mouse goes outif (m_MouseOnButton == TRUE){m_MouseOnButton = FALSE;Invalidate();}// If user is NOT pressing left button then release capture!if (!(nFlags & MK_LBUTTON)) ReleaseCapture();}}}}BOOL CLRSkinButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) {if (m_hBtnCursor != NULL){::SetCursor(m_hBtnCursor);return TRUE;}return CButton::OnSetCursor(pWnd, nHitTest, message);}void CLRSkinButton::OnKillFocus(CWnd* pNewWnd) {CButton::OnKillFocus(pNewWnd);if(!m_bIsFlat) {m_MouseOnButton = FALSE;Invalidate();}}