📄 myvariousstate.cpp
字号:
#include "stdafx.h"
#include "MyVariousState.h"
MyButton::MyButton()
{
//画边框
m_BoundryPen.CreatePen(PS_INSIDEFRAME|PS_SOLID,1,RGB(55, 98, 6));
//画四个边的线,当鼠标移到上面时则显示
m_InsideBoundryPenLeft.CreatePen(PS_INSIDEFRAME|PS_SOLID,3,RGB(159,175,127));
m_InsideBoundryPenRight.CreatePen(PS_INSIDEFRAME|PS_SOLID,3,RGB(160,180,130));
m_InsideBoundryPenTop.CreatePen(PS_INSIDEFRAME|PS_SOLID,2,RGB(161,190,143));
m_InsideBoundryPenBottom.CreatePen(PS_INSIDEFRAME|PS_SOLID,2,RGB(140,155,0));
m_FillActive.CreateSolidBrush(RGB(236,233,216));
//没有焦点时,底边内框线的颜色
m_FillInactive.CreateSolidBrush(RGB(235,234,216));
//获得焦点后四个边线的颜色
m_InsideBoundryPenLeftSel.CreatePen(PS_INSIDEFRAME|PS_SOLID,3,RGB(153,198,252));
m_InsideBoundryPenTopSel.CreatePen(PS_INSIDEFRAME|PS_SOLID,2,RGB(162,201,255));
m_InsideBoundryPenRightSel.CreatePen(PS_INSIDEFRAME|PS_SOLID,3,RGB(162,189,252));
m_InsideBoundryPenBottomSel.CreatePen(PS_INSIDEFRAME|PS_SOLID,2,RGB(162,201,255));
m_bOver=m_bSelected=m_bTracking=m_bFocus=FALSE;
}
MyButton::~MyButton()
{
m_BoundryPen.DeleteObject();
m_InsideBoundryPenLeft.DeleteObject();
m_InsideBoundryPenRight.DeleteObject();
m_InsideBoundryPenTop.DeleteObject();
m_InsideBoundryPenBottom.DeleteObject();
m_FillActive.DeleteObject();
m_FillInactive.DeleteObject();
m_InsideBoundryPenLeftSel.DeleteObject();
m_InsideBoundryPenTopSel.DeleteObject();
m_InsideBoundryPenRightSel.DeleteObject();
m_InsideBoundryPenBottomSel.DeleteObject();
}
BEGIN_MESSAGE_MAP(MyButton, CButton)
//{{AFX_MSG_MAP(MyButton)
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// MyButton message handlers
//添加Owner Draw属性
void MyButton::PreSubclassWindow()
{
CButton::PreSubclassWindow();
ModifyStyle(0, BS_OWNERDRAW);//必须增加该属性,才能使所有的设置有效
//设置按钮的有效区域
CRgn rgn;
CRect rc;
GetClientRect(&rc);
//有效区域为一个角半径为5的圆角矩形
// rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom,5,5);
SetWindowRgn(rgn,TRUE);
CButton::PreSubclassWindow();
}
void MyButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
// 鼠标第一次移入窗口时, 请求一个WM_MOUSELEAVE 消息
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
}
void MyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
//从lpDrawItemStruct获取控件的相关信息
CRect rect = lpDrawItemStruct->rcItem;
CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
int nSaveDC=pDC->SaveDC();
UINT state = lpDrawItemStruct->itemState;
POINT pt;
TCHAR strText[MAX_PATH+1];
//获得按钮的文本内容
::GetWindowText(m_hWnd,strText,MAX_PATH);
//画按钮的外边框,它是一个半径为5的圆角矩形
pt.x =5;
pt.y =5;
//载入笔画对象m_BoundryPen
CPen*hOldPen=pDC->SelectObject(&m_BoundryPen);
pDC->RoundRect(&rect,pt);//画圆角矩形
//获取按钮的状态
if (state&ODS_FOCUS)
{
m_bFocus=TRUE;
m_bSelected=TRUE;
}
else
{
m_bFocus=FALSE;
m_bSelected=FALSE;
}
if (state & ODS_SELECTED || state & ODS_DEFAULT)
{
m_bFocus = TRUE;
}
pDC->SelectObject(hOldPen);
//3D边框的宽度和高度
rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE),
GetSystemMetrics(SM_CYEDGE)));
//根据按钮的状态填充按钮的底色
CBrush* pOldBrush;
if (m_bOver)
{
pOldBrush = pDC->SelectObject(&m_FillActive);
DoGradientFill(pDC, &rect);
}
else
{
pOldBrush = pDC->SelectObject(&m_FillInactive);
DoGradientFill(pDC, &rect);
}
//根据按钮的状态绘制内边框
if (m_bOver || m_bSelected)
DrawInsideBorder(pDC, &rect);
pDC->SelectObject(pOldBrush);
//显示按钮的文本
if (strText!=NULL)
{
CFont* hFont = GetFont();
CFont* hOldFont = pDC->SelectObject(hFont);
CSize szExtent = pDC->GetTextExtent(strText, lstrlen(strText));
CPoint pt( rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);
if (state & ODS_SELECTED)
pt.Offset(1, 1);
int nMode = pDC->SetBkMode(TRANSPARENT);
if (state & ODS_DISABLED)
pDC->DrawState(pt, szExtent, strText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
else
pDC->DrawState(pt, szExtent, strText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
pDC->SelectObject(hOldFont);
pDC->SetBkMode(nMode);
}
pDC->RestoreDC(nSaveDC);
}
//绘制按钮的底色,也就是按钮里面的颜色.
void MyButton::DoGradientFill(CDC *pDC, CRect *rect)
{
CBrush brBk[64];
int nWidth = rect->Width();
int nHeight = rect->Height();
CRect rct;
int i;
for (i=0; i<64; i++)
{
if (m_bOver)
{
if (m_bFocus)
brBk[i].CreateSolidBrush(RGB(255 - (i / 4), 255 - (i / 4), 255 - (i / 3)));
else
brBk[i].CreateSolidBrush(RGB(255 - (i / 4), 255 - (i / 4), 255 - (i / 5)));
}
else
{
if (m_bFocus)
brBk[i].CreateSolidBrush(RGB(255 - (i / 3), 255 - (i / 3), 255 - (i / 4)));
else
brBk[i].CreateSolidBrush(RGB(255 - (i / 3), 255 - (i / 3), 255 - (i / 5)));
}
}
for (i = rect->top; i <= nHeight + 2; i ++)
{
rct.SetRect(rect->left, i, nWidth + 2, i + 1);
pDC->FillRect(&rct, &brBk[((i * 63) / nHeight)]);
}
for (i = 0; i < 64; i ++)
brBk[i].DeleteObject();
}
//绘制按钮的内边框,也就是四个内边线的颜色
void MyButton::DrawInsideBorder(CDC *pDC, CRect *rect)
{
CPen *pLeft, *pRight, *pTop, *pBottom;
if (m_bSelected && !m_bOver)
{
pLeft = & m_InsideBoundryPenLeftSel;
pRight = &m_InsideBoundryPenRightSel;
pTop = &m_InsideBoundryPenTopSel;
pBottom = &m_InsideBoundryPenBottomSel;
}
else
{
pLeft = &m_InsideBoundryPenLeft;
pRight = &m_InsideBoundryPenRight;
pTop = &m_InsideBoundryPenTop;
pBottom = &m_InsideBoundryPenBottom;
}
CPoint oldPoint = pDC->MoveTo(rect->left, rect->bottom - 1);
CPen* pOldPen = pDC->SelectObject(pLeft);
pDC->LineTo(rect->left, rect->top + 1);
pDC->SelectObject(pRight);
pDC->MoveTo(rect->right - 1, rect->bottom - 1);
pDC->LineTo(rect->right - 1, rect->top);
pDC->SelectObject(pTop);
pDC->MoveTo(rect->left - 1, rect->top);
pDC->LineTo(rect->right - 1, rect->top);
pDC->SelectObject(pBottom);
pDC->MoveTo(rect->left, rect->bottom);
pDC->LineTo(rect->right - 1, rect->bottom);
pDC->SelectObject(pOldPen);
pDC->MoveTo(oldPoint);
if (m_bSelected && !m_bOver)
DrawFocusRect(pDC->m_hDC,rect);
}
BOOL MyButton::OnEraseBkgnd(CDC* pDC)
{
//禁止绘制底色
return TRUE;
}
LRESULT MyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bOver = TRUE;
InvalidateRect(NULL);
return 0;
}
LRESULT MyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bOver = FALSE;
m_bTracking = FALSE;
InvalidateRect(NULL, FALSE);
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
CColorStaticST::CColorStaticST()
{
// Set default parent window and notification message
m_pParent = NULL;
m_nMsg = WM_USER;
// By default the control is not blinking
m_bTextBlink = FALSE;
m_nTextBlinkStep = 0;
m_bBkBlink = FALSE;
m_nBkBlinkStep = 0;
m_nTimerId = 0;
// Set default foreground text
m_crTextColor = ::GetSysColor(COLOR_BTNTEXT);
// Set default foreground text (when blinking)
m_crBlinkTextColors[0] = m_crTextColor;
m_crBlinkTextColors[1] = m_crTextColor;
// Set default background text
m_crBkColor = ::GetSysColor(COLOR_BTNFACE);
// Set default background text (when blinking)
m_crBlinkBkColors[0] = m_crBkColor;
m_crBlinkBkColors[1] = m_crBkColor;
// Set default background brush
m_brBkgnd.CreateSolidBrush(m_crBkColor);
// Set default background brush (when blinking)
m_brBlinkBkgnd[0].CreateSolidBrush(m_crBkColor);
m_brBlinkBkgnd[1].CreateSolidBrush(m_crBkColor);
} // End of CColorStaticST
CColorStaticST::~CColorStaticST()
{
} // End of ~CColorStaticST
BEGIN_MESSAGE_MAP(CColorStaticST, CStatic)
//{{AFX_MSG_MAP(CColorStaticST)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_TIMER()
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CColorStaticST message handlers
HBRUSH CColorStaticST::CtlColor(CDC* pDC, UINT nCtlColor)
{
// Set foreground color
// If control is blinking (text)
if (m_bTextBlink == TRUE)
{
pDC->SetTextColor(m_crBlinkTextColors[m_nTextBlinkStep]);
}
else
{
pDC->SetTextColor(m_crTextColor);
}
// Set background color & brush
// If control is blinking (background)
if (m_bBkBlink == TRUE)
{
pDC->SetBkColor(m_crBlinkBkColors[m_nBkBlinkStep]);
return (HBRUSH)m_brBlinkBkgnd[m_nBkBlinkStep];
}
// If control is not blinking (background)
pDC->SetBkColor(m_crBkColor);
// Return a non-NULL brush if the parent's handler should not be called
return (HBRUSH)m_brBkgnd;
} // End of CtlColor
void CColorStaticST::OnDestroy()
{
CStatic::OnDestroy();
// Destroy timer (if any)
if (m_nTimerId > 0) KillTimer(m_nTimerId);
// Destroy resources
m_brBkgnd.DeleteObject();
m_brBlinkBkgnd[0].DeleteObject();
m_brBlinkBkgnd[1].DeleteObject();
} // End of OnDestroy
void CColorStaticST::SetTextColor(COLORREF crTextColor)
{
// Set new foreground color
if (crTextColor != 0xffffffff)
{
m_crTextColor = crTextColor;
}
else // Set default foreground color
{
m_crTextColor = ::GetSysColor(COLOR_BTNTEXT);
}
// Repaint control
Invalidate();
} // End of SetTextColor
COLORREF CColorStaticST::GetTextColor()
{
return m_crTextColor;
} // End of GetTextColor
void CColorStaticST::SetBkColor(COLORREF crBkColor)
{
// Set new background color
if (crBkColor != 0xffffffff)
{
m_crBkColor = crBkColor;
}
else // Set default background color
{
m_crBkColor = ::GetSysColor(COLOR_BTNFACE);
}
m_brBkgnd.DeleteObject();
m_brBkgnd.CreateSolidBrush(m_crBkColor);
// Repaint control
Invalidate();
} // End of SetBkColor
COLORREF CColorStaticST::GetBkColor()
{
return m_crBkColor;
} // End of GetBkColor
void CColorStaticST::SetBlinkTextColors(COLORREF crBlinkTextColor1, COLORREF crBlinkTextColor2)
{
// Set new blink text colors
m_crBlinkTextColors[0] = crBlinkTextColor1;
m_crBlinkTextColors[1] = crBlinkTextColor2;
} // End of SetBlinkTextColors
void CColorStaticST::StartTextBlink(BOOL bStart, UINT nElapse)
{
UINT nCount;
// Destroy any previous timer
if (m_nTimerId > 0)
{
KillTimer(m_nTimerId);
m_nTimerId = 0;
}
m_bTextBlink = bStart;
m_nTextBlinkStep = 0;
// Start timer
if (m_bTextBlink == TRUE)
{
switch (nElapse)
{
case ST_FLS_SLOW:
nCount = 2000;
break;
case ST_FLS_NORMAL:
nCount = 1000;
break;
case ST_FLS_FAST:
nCount = 500;
break;
default:
nCount = nElapse;
break;
}
m_nTimerId = SetTimer(1, nCount, NULL);
}
} // End of StartTextBlink
void CColorStaticST::SetBlinkBkColors(COLORREF crBlinkBkColor1, COLORREF crBlinkBkColor2)
{
// Set new blink background colors
m_crBlinkBkColors[0] = crBlinkBkColor1;
m_crBlinkBkColors[1] = crBlinkBkColor2;
m_brBlinkBkgnd[0].DeleteObject();
m_brBlinkBkgnd[0].CreateSolidBrush(m_crBlinkBkColors[0]);
m_brBlinkBkgnd[1].DeleteObject();
m_brBlinkBkgnd[1].CreateSolidBrush(m_crBlinkBkColors[1]);
// Repaint control
Invalidate();
} // End of SetBlinkBkColor
void CColorStaticST::StartBkBlink(BOOL bStart, UINT nElapse)
{
UINT nCount;
// Destroy any previous timer
if (m_nTimerId > 0)
{
KillTimer(m_nTimerId);
m_nTimerId = 0;
}
m_bBkBlink = bStart;
m_nBkBlinkStep = 0;
// Start timer
if (m_bBkBlink == TRUE)
{
switch (nElapse)
{
case ST_FLS_SLOW:
nCount = 2000;
break;
case ST_FLS_NORMAL:
nCount = 1000;
break;
case ST_FLS_FAST:
nCount = 500;
break;
default:
nCount = nElapse;
break;
}
m_nTimerId = SetTimer(1, nCount, NULL);
}
} // End of StartBkBlink
void CColorStaticST::EnableNotify(CWnd* pParent, UINT nMsg)
{
m_pParent = pParent;
m_nMsg = nMsg;
} // End of EnableNotify
void CColorStaticST::OnTimer(UINT nIDEvent)
{
if (nIDEvent == m_nTimerId)
{
// If control is blinking (text) switch its color
if (m_bTextBlink == TRUE) m_nTextBlinkStep = !m_nTextBlinkStep;
// If control is blinking (background) switch its color
if (m_bBkBlink == TRUE) m_nBkBlinkStep = !m_nBkBlinkStep;
// If there is any blinking in action then repaint the control
// and send the notification message (if any)
if (m_bBkBlink == TRUE || m_bTextBlink == TRUE)
{
Invalidate();
// Send notification message only on rising blink
if (m_pParent != NULL && (m_nBkBlinkStep == 1 || m_nTextBlinkStep == 1))
m_pParent->PostMessage(m_nMsg, GetDlgCtrlID(), 0);
}
}
else
CStatic::OnTimer(nIDEvent);
} // End of OnTimer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -