📄 mybutton.cpp
字号:
#include "stdafx.h"
#include "math.h"
#include "MyButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyButton
CMyButton::CMyButton()
{
m_clrText=RGB(0,0,0);
m_clrBack=RGB(161,192,245);
m_clrLeft=RGB(97,244,78);
m_clrRight=RGB(52,148,39);
m_clrFlatBack=GetSysColor(COLOR_3DFACE);
m_blnMouseOn=FALSE;
intStyle=0;
intAlgin=0;
intButtonFace=0;
m_BackBrush.CreateSolidBrush(m_clrFlatBack);
}
CMyButton::~CMyButton()
{
m_rgn.DeleteObject();
DestroyXIcon();
m_BackBrush.DeleteObject();
}
BEGIN_MESSAGE_MAP(CMyButton, CButton)
//{{AFX_MSG_MAP(CMyButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyButton message handlers
void CMyButton::PreSubclassWindow()
{
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);
CRect rect;
GetClientRect(rect);
m_rgn.DeleteObject();
SetWindowRgn(NULL, FALSE);
if(intButtonFace==1)
m_rgn.CreateRoundRectRgn(rect.left,rect.top+3,rect.right,rect.bottom,10,10);
if(intButtonFace==0)
m_rgn.CreateRectRgn(rect.left,rect.top+3,rect.right,rect.bottom);
if(intButtonFace==2)
m_rgn.CreateEllipticRgn(rect.left,rect.top+3,rect.right,rect.bottom);
SetWindowRgn(m_rgn, TRUE);
ClientToScreen(rect);
CWnd* pParent = GetParent();
if (pParent) pParent->ScreenToClient(rect);
MoveWindow(rect.left, rect.top, rect.Width(), rect.Height(), TRUE);
}
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct != NULL);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = lpDrawItemStruct->rcItem;
UINT state = lpDrawItemStruct->itemState;
UINT nStyle = GetStyle();
CRgn rgn1,rgn2;
int r1,g1,b1;
if(intButtonFace==1)
{
rgn1.CreateRoundRectRgn(rect.left,rect.top+3,rect.right,rect.bottom,10,10);
rgn2.CreateRoundRectRgn(rect.left+1,rect.top+4,rect.right-1,rect.bottom-1,10,10);
}
if(intButtonFace==0)
{
rgn1.CreateRectRgn(rect.left,rect.top+3,rect.right,rect.bottom);
rgn2.CreateRectRgn(rect.left+1,rect.top+4,rect.right-1,rect.bottom-1);
}
if(intButtonFace==2)
{
rgn1.CreateEllipticRgn(rect.left,rect.top+3,rect.right,rect.bottom);
rgn2.CreateEllipticRgn(rect.left+1,rect.top+4,rect.right-1,rect.bottom-1);
}
pDC->SelectClipRgn(&rgn1);
int nSavedDC = pDC->SaveDC();
CBrush brush1,brush2;
if(!(nStyle&BS_NOTIFY))
{
if ((state & ODS_FOCUS)||(state & ODS_SELECTED))
{
r1=GetRValue(m_clrBack);
g1=GetGValue(m_clrBack);
b1=GetBValue(m_clrBack);
for(int i=rect.Height()/2;i>0;i--)
{
r1=(r1+10)>255?255:(r1+10);
g1=(g1+10)>255?255:(g1+10);
b1=(b1+10)>255?255:(b1+10);
CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
CPen *old = pDC->SelectObject(&pen);
pDC->MoveTo(rect.left,rect.top+i);
pDC->LineTo(rect.right,rect.top+i);
pDC->MoveTo(rect.left,rect.bottom-i);
pDC->LineTo(rect.right,rect.bottom-i);
pDC->SelectObject(old);
}
r1=GetRValue(m_clrRight);
g1=GetGValue(m_clrRight);
b1=GetBValue(m_clrRight);
r1=(r1+30)>255?255:(r1+30);
g1=(g1+30)>255?255:(g1+30);
b1=(b1+30)>255?255:(b1+30);
brush2.CreateSolidBrush(m_clrRight);
brush1.CreateSolidBrush(RGB(r1,g1,b1));
pDC->FrameRgn(&rgn1,&brush1,1,1);
pDC->FrameRgn(&rgn2,&brush2,1,1);
}
else if(m_blnMouseOn)
{
r1=GetRValue(m_clrBack);
g1=GetGValue(m_clrBack);
b1=GetBValue(m_clrBack);
for(int i=rect.Height()/2;i>0;i--)
{
r1=(r1+10)>255?255:(r1+10);
g1=(g1+10)>255?255:(g1+10);
b1=(b1+10)>255?255:(b1+10);
CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
CPen *old = pDC->SelectObject(&pen);
pDC->MoveTo(rect.left,rect.top+i);
pDC->LineTo(rect.right,rect.top+i);
pDC->MoveTo(rect.left,rect.bottom-i);
pDC->LineTo(rect.right,rect.bottom-i);
pDC->SelectObject(old);
}
r1=GetRValue(m_clrLeft);
g1=GetGValue(m_clrLeft);
b1=GetBValue(m_clrLeft);
r1=(r1+30)>255?255:(r1+30);
g1=(g1+30)>255?255:(g1+30);
b1=(b1+30)>255?255:(b1+30);
brush2.CreateSolidBrush(m_clrLeft);
brush1.CreateSolidBrush(RGB(r1,g1,b1));
pDC->FrameRgn(&rgn1,&brush1,1,1);
pDC->FrameRgn(&rgn2,&brush2,1,1);
}
else
{
if(nStyle&BS_FLAT)
{
CBrush bs;
bs.CreateSolidBrush(m_clrFlatBack);
CRect rcBack;
GetClientRect(rcBack);
pDC->FillRect(rcBack,&m_BackBrush);
}
else
{
r1=GetRValue(m_clrBack);
g1=GetGValue(m_clrBack);
b1=GetBValue(m_clrBack);
for(int i=rect.Height()/2;i>0;i--)
{
r1=(r1+13)>255?255:(r1+13);
g1=(g1+13)>255?255:(g1+13);
b1=(b1+13)>255?255:(b1+13);
CPen pen(PS_SOLID, 1, RGB(r1, g1, b1));
CPen *old = pDC->SelectObject(&pen);
pDC->MoveTo(rect.left,rect.top+i);
pDC->LineTo(rect.right,rect.top+i);
pDC->MoveTo(rect.left,rect.bottom-i);
pDC->LineTo(rect.right,rect.bottom-i);
pDC->SelectObject(old);
}
r1=GetRValue(m_clrBack);
g1=GetGValue(m_clrBack);
b1=GetBValue(m_clrBack);
r1=(r1+30)>255?255:(r1+30);
g1=(g1+30)>255?255:(g1+30);
b1=(b1+30)>255?255:(b1+30);
brush2.CreateSolidBrush(m_clrBack);
brush1.CreateSolidBrush(RGB(r1,g1,b1));
pDC->FrameRgn(&rgn1,&brush1,1,1);
pDC->FrameRgn(&rgn2,&brush2,1,1);
}
}
}
//输出文字
CFont *ft=GetFont();
LOGFONT logft;
ft->GetLogFont(&logft);
CRect rcIcon(rect);
if(intStyle==1)
{
switch(intAlgin)
{
case 1: //文字在下端
rcIcon.bottom=rect.bottom-abs(logft.lfHeight);
if(rcIcon.bottom<0) rcIcon.bottom=0;
DrawIconX(pDC,rcIcon);
rect.top=rcIcon.bottom-(rcIcon.Height()-dwIconHeight)/2;
break;
case 2://文字在上
rcIcon.top=abs(logft.lfHeight)+rect.top;
DrawIconX(pDC,rcIcon);
rect.bottom=rcIcon.top+(rcIcon.Height()-dwIconHeight)/2;
break;
case 3://文字在左
GetXiconInf();
rcIcon.left=rect.Width()*0.9+rect.left-dwIconWidth-5;
rcIcon.right=rect.Width()*0.9+rect.left;
DrawIconX(pDC,rcIcon);
rect.right=rcIcon.left;
break;
case 0://文字在右
default:
DrawIconX(pDC,rcIcon);
rect.left=dwIconWidth+rect.left+rect.Width()*0.1;
break;
}
}
else
{
switch(intAlgin)
{
case 1: //文字在下端
rect.top=rect.bottom-abs(logft.lfHeight)-10;
break;
case 2://文字在上
rect.bottom=abs(logft.lfHeight)+10+rect.top;
break;
case 3://文字在左
case 0://文字在右
default:
break;
}
}
CPoint m_ptCentre=rect.CenterPoint();
CString strText;
GetWindowText(strText);
if (!strText.IsEmpty())
{
pDC->SetTextColor(m_clrText);
CSize Extent = pDC->GetTextExtent(strText);
CPoint pt = CPoint( m_ptCentre.x - Extent.cx/2, m_ptCentre.y - Extent.cy/2 );
if (state & ODS_SELECTED) pt.Offset(1,1);
pDC->SetBkMode(TRANSPARENT);
if ((state & ODS_DISABLED)&!(nStyle&BS_NOTIFY))
pDC->DrawState(pt, Extent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
else if(nStyle&BS_NOTIFY)
{
pDC->FillRect(rect,&m_BackBrush);
if((state & ODS_FOCUS)||(state & ODS_SELECTED))
{
pDC->SetTextColor(m_clrRight);
pDC->TextOut(pt.x+2, pt.y+2, strText);
}
else if(m_blnMouseOn)
{
pDC->SetTextColor(m_clrLeft);
pDC->TextOut(pt.x+2, pt.y+2, strText);
}
else
{
pDC->TextOut(pt.x, pt.y, strText);
}
}
else
{
pDC->TextOut(pt.x, pt.y, strText);
}
}
pDC->SelectClipRgn(NULL);
pDC->RestoreDC(nSavedDC);
rgn1.DeleteObject();
rgn2.DeleteObject();
}
void CMyButton::SetMaskColor(COLORREF colLeft,COLORREF colRight)
{
m_clrRight=colRight;
m_clrLeft=colLeft;
this->Invalidate(TRUE);
}
void CMyButton::SetBackColor(COLORREF color)
{
m_clrBack=color;
this->Invalidate(TRUE);
}
void CMyButton::SetBackImage(UINT nIDResource)
{
CBitmap bmp;
intStyle=3;
bmp.LoadBitmap(nIDResource);
m_BackBrush.DeleteObject();
m_BackBrush.CreatePatternBrush(&bmp);
}
void CMyButton::SetButtonFace(int intStyle)
{
intButtonFace=intStyle;
this->Invalidate();
}
void CMyButton::SetFlatBack(COLORREF colFlat)
{
m_clrFlatBack=colFlat;
m_BackBrush.DeleteObject();
m_BackBrush.CreateSolidBrush(colFlat);
this->Invalidate(TRUE);
}
void CMyButton::SetTextColor(COLORREF color)
{
m_clrText=color;
this->Invalidate(TRUE);
}
void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* wndUnderMouse = NULL;
CWnd* wndActive = this;
TRACKMOUSEEVENT csTME;
CButton::OnMouseMove(nFlags, point);
ClientToScreen(&point);
wndUnderMouse = WindowFromPoint(point);
// If the mouse enter the button with the left button pressed then do nothing
if (nFlags & MK_LBUTTON) return;
// If our button is not flat then do nothing
wndActive = GetActiveWindow();
if (wndUnderMouse && wndUnderMouse->m_hWnd == m_hWnd && wndActive)
{
if (!m_blnMouseOn)
{
m_blnMouseOn = TRUE;
Invalidate();
csTME.cbSize = sizeof(csTME);
csTME.dwFlags = TME_LEAVE;
csTME.hwndTrack = m_hWnd;
::_TrackMouseEvent(&csTME);
}
}
else
{
m_blnMouseOn=FALSE;
Invalidate();
}
}
LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_blnMouseOn=FALSE;
Invalidate();
return 0;
}
void CMyButton::SetXIcon(UINT nIDResource)
{
intStyle=1;
Xicon=AfxGetApp()->LoadIcon(nIDResource);
this->Invalidate();
}
void CMyButton::DrawIconX(CDC *pDC,CRect rcItem)
{
GetXiconInf();
int intTop=(rcItem.Height()-dwIconHeight)/2;
if(intTop<0) intTop=0;
intTop=rcItem.top+intTop;
if(intAlgin==0)
{
int intLeft=rcItem.left+rcItem.Width()*0.1;
pDC->DrawIcon(intLeft,intTop,Xicon);
}
else
{
int intLeft=(rcItem.Width()-dwIconWidth)/2;
if(intLeft<0) intLeft=0;
intLeft=intLeft+rcItem.left;
pDC->DrawIcon(intLeft,intTop,Xicon);
}
}
void CMyButton::DestroyXIcon()
{
if(Xicon) ::DestroyIcon(Xicon);
}
void CMyButton::GetXiconInf()
{
BOOL bRetValue;
ICONINFO ii;
if (Xicon)
{
::ZeroMemory(&ii, sizeof(ICONINFO));
bRetValue = ::GetIconInfo(Xicon, &ii);
if (bRetValue == FALSE)
{
DestroyXIcon();
} // if
dwIconWidth = (DWORD)(ii.xHotspot * 2);
dwIconHeight= (DWORD)(ii.yHotspot * 2);
::DeleteObject(ii.hbmMask);
::DeleteObject(ii.hbmColor);
}
}
void CMyButton::SetXAlign(int Align)
{
intAlgin=Align;
this->Invalidate();
}
void CMyButton::SetXStyle(int Style)
{
intStyle=Style;
this->Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -