按钮自绘,将按钮区域分成三部分,左边、右边、中间都由贴图绘制,可用于手动进度条按钮,或者左右选择项按钮
cpp代码部分:
// LRSkinButton.cpp : implementation file
//
#include "stdafx.h"
#include "CRedrawButtonDemo.h"
#include "LRSkinButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CLRSkinButton
CLRSkinButton::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_MAP
ON_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 button
if (bIsPressed)
{// 按钮按下状态
/*
HPEN penBtnHiLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));//COLOR_3DLIGHT)); // Bianco
HPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW)); // Grigio scuro
// draw darkline of left-top conner
hOldPen = (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 conner
SelectObject(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 resource
SelectObject(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 gray
HPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW)); // Dark gray
// White line
hOldPen = (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 line
SelectObject(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;
else
m_bDefaultBtn = FALSE;
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
}
/
// CLRSkinButton message handlers
void 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 nothing
if (nFlags & MK_LBUTTON && !m_MouseOnButton)
return;
// If our button is not flat then do nothing
if (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 out
if (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();
}
}