📄 btnst.cpp
字号:
// BtnST.cpp : implementation file
//
#include "stdafx.h"
#include "BtnST.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CButtonST
CButtonST::CButtonST()
{
m_MouseOnButton = FALSE;
m_hIconIn = NULL;
m_hIconOut = NULL;
m_cxIcon = 0;
m_cyIcon = 0;
m_hCursor = NULL;
//默认类型为平面按钮
m_bIsFlat = TRUE;
//平面按钮中默认绘制边界
m_bDrawBorder = TRUE;
//默认图标水平对齐
m_nAlign = ST_ALIGN_HORIZ;
// 默认显示按钮文本
m_bShowText = TRUE;
// 对平面按钮,默认不绘制焦点边框
m_bDrawFlatFocus = FALSE;
//默认情况下,该按钮不是缺省按钮
m_bIsDefault = FALSE;
// 不产生提示信息
m_ToolTip.m_hWnd = NULL;
//不绘制透明按钮
m_bDrawTransparent = FALSE;
m_pbmpOldBk = NULL;
} // End of CButtonST
CButtonST::~CButtonST()
{
// Restore old bitmap (if any)
if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
{
m_dcBk.SelectObject(m_pbmpOldBk);
}
} // End of ~CButtonST
BEGIN_MESSAGE_MAP(CButtonST, CButton)
//{{AFX_MSG_MAP(CButtonST)
ON_WM_CAPTURECHANGED()
ON_WM_SETCURSOR()
ON_WM_KILLFOCUS()
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/*
设置按钮图标
参数nIconInId为鼠标在按钮上时需要显示的图标资源ID
参数nIconOutId为鼠标不在按钮上时需要显示的图标资源ID
*/
void CButtonST::SetIcon(int nIconInId, int nIconOutId)
{
HINSTANCE hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nIconInId),
RT_GROUP_ICON);
//当鼠标在按钮上时设置图标
m_hIconIn = (HICON)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nIconInId), IMAGE_ICON, 0, 0, 0);
//当鼠标不在按钮上时设置图标
m_hIconOut = (nIconOutId == NULL) ? m_hIconIn : (HICON)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nIconOutId), IMAGE_ICON, 0, 0, 0);
ICONINFO ii;
//取得图标大小
ZeroMemory(&ii, sizeof(ICONINFO));
::GetIconInfo(m_hIconIn, &ii);
m_cxIcon = (BYTE)(ii.xHotspot * 2);
m_cyIcon = (BYTE)(ii.yHotspot * 2);
RedrawWindow();
} // End of SetIcon
//设置光标,nCursorId为光标ID
BOOL CButtonST::SetBtnCursor(int nCursorId)
{
HINSTANCE hInstResource;
//销毁以前光标
if (m_hCursor != NULL) ::DestroyCursor(m_hCursor);
m_hCursor = NULL;
//如果需要光标
if (nCursorId != -1)
{
hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nCursorId),
RT_GROUP_CURSOR);
//获取图标资源
m_hCursor = (HCURSOR)::LoadImage(hInstResource/*AfxGetApp()->m_hInstance*/, MAKEINTRESOURCE(nCursorId), IMAGE_CURSOR, 0, 0, 0);
if (m_hCursor == NULL) return FALSE;
}
return TRUE;
} // End of SetBtnCursor
//设置按钮类型。
//如果bState为TRUE,则按钮为平面类型;如果bState为FALSE,则按钮为标准类型。
void CButtonST::SetFlat(BOOL bState)
{
m_bIsFlat = bState;
Invalidate();
} // End of SetFlat
//获取按钮类型
BOOL CButtonST::GetFlat()
{
return m_bIsFlat;
} // End of GetFlat
/*
设置按钮图标对齐方式
如果参数nAlign为ST_ALIGN_HORIZ,则按钮中图标在左,文字在右(默认方式)
如果参数nAlign为ST_ALIGN_VERT,则按钮中图标在上,文字在下
*/
void CButtonST::SetAlign(int nAlign)
{
switch (nAlign)
{
case ST_ALIGN_HORIZ:
m_nAlign = ST_ALIGN_HORIZ;
break;
case ST_ALIGN_VERT:
m_nAlign = ST_ALIGN_VERT;
break;
}
Invalidate();
} // End of SetAlign
//获取对齐方式
int CButtonST::GetAlign()
{
return m_nAlign;
} // End of GetAlign
//设置高亮开关
//如果bEnable为TRUE,则平面按钮自动高亮;如果为FALSE,则不高亮
void CButtonST::DrawBorder(BOOL bEnable)
{
m_bDrawBorder = bEnable;
} // End of DrawBorder
//在运行状态下增加或删除按钮标题
//如果参数bShow,则显示按钮标题;如果为FALSE,则不显示
//鼠标移动时的事件响应函数
void CButtonST::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pWnd;
CWnd* pParent;
CButton::OnMouseMove(nFlags, point);
// If the mouse enter the button with the left button pressed
// then do nothing
if (nFlags & MK_LBUTTON && m_MouseOnButton == FALSE) return;
// If our button is not flat then do nothing
if (m_bIsFlat == FALSE) return;
pWnd = GetActiveWindow();
pParent = GetOwner();
if ((GetCapture() != this) &&
(
#ifndef ST_LIKEIE
pWnd != NULL &&
#endif
pParent != NULL))
{
m_MouseOnButton = TRUE;
SetCapture();
Invalidate();
}
else
{
POINT p2 = point;
ClientToScreen(&p2);
CWnd* wndUnderMouse = WindowFromPoint(p2);
if (wndUnderMouse != this)
{
// 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();
}
}
} // End of OnMouseMove
void CButtonST::OnKillFocus(CWnd * pNewWnd)
{
CButton::OnKillFocus(pNewWnd);
// If our button is not flat then do nothing
if (m_bIsFlat == FALSE) return;
if (m_MouseOnButton == TRUE)
{
m_MouseOnButton = FALSE;
Invalidate();
}
} // End of OnKillFocus
void CButtonST::OnCaptureChanged(CWnd *pWnd)
{
if (m_MouseOnButton == TRUE)
{
ReleaseCapture();
Invalidate();
}
// Call base message handler
CButton::OnCaptureChanged(pWnd);
} // End of OnCaptureChanged
void CButtonST::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
#ifdef ST_USE_MEMDC
CDC *pdrawDC = CDC::FromHandle(lpDIS->hDC);
CMemDC memDC(pdrawDC);
CDC *pDC = &memDC;
#else
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
#endif
CPen *pOldPen;
BOOL bIsPressed = (lpDIS->itemState & ODS_SELECTED);
BOOL bIsFocused = (lpDIS->itemState & ODS_FOCUS);
BOOL bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
CRect itemRect = lpDIS->rcItem;
if (m_bIsFlat == FALSE)
{
if (bIsFocused || (GetDefault() == TRUE))
{
CBrush br(RGB(0,0,0));
pDC->FrameRect(&itemRect, &br);
itemRect.DeflateRect(1, 1);
}
}
COLORREF bgColor;
CBrush br(bgColor);
// Draw transparent?
if (m_bDrawTransparent == TRUE)
{
PaintBk(pDC);
}
else
{
pDC->FillRect(&itemRect, &br);
}
if (bIsPressed)
{
if (m_bIsFlat == TRUE)
{
if (m_bDrawBorder == TRUE)
{
CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // Bianco
CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); // Grigio scuro
// 暗灰线
pOldPen = pDC->SelectObject(&penBtnShadow);
pDC->MoveTo(itemRect.left, itemRect.bottom-1);
pDC->LineTo(itemRect.left, itemRect.top);
pDC->LineTo(itemRect.right, itemRect.top);
//白线
pDC->SelectObject(penBtnHiLight);
pDC->MoveTo(itemRect.left, itemRect.bottom-1);
pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
pDC->LineTo(itemRect.right-1, itemRect.top-1);
//
pDC->SelectObject(pOldPen);
}
}
else
{
CBrush brBtnShadow(GetSysColor(COLOR_BTNSHADOW));
pDC->FrameRect(&itemRect, &brBtnShadow);
}
}
else // ...else draw non pressed button
{
CPen penBtnHiLight(PS_SOLID, 0, GetSysColor(COLOR_BTNHILIGHT)); // White
CPen pen3DLight(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT)); // Light gray
CPen penBtnShadow(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW)); // Dark gray
CPen pen3DDKShadow(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW)); // Black
if (m_bIsFlat == TRUE)
{
if (m_MouseOnButton == TRUE && m_bDrawBorder == TRUE)
{
//白线
pOldPen = pDC->SelectObject(&penBtnHiLight);
pDC->MoveTo(itemRect.left, itemRect.bottom-1);
pDC->LineTo(itemRect.left, itemRect.top);
pDC->LineTo(itemRect.right, itemRect.top);
//暗灰线
pDC->SelectObject(penBtnShadow);
pDC->MoveTo(itemRect.left, itemRect.bottom-1);
pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
pDC->LineTo(itemRect.right-1, itemRect.top-1);
//
pDC->SelectObject(pOldPen);
}
}
else
{
//白线
pOldPen = pDC->SelectObject(&penBtnHiLight);
pDC->MoveTo(itemRect.left, itemRect.bottom-1);
pDC->LineTo(itemRect.left, itemRect.top);
pDC->LineTo(itemRect.right, itemRect.top);
//亮灰线
pDC->SelectObject(pen3DLight);
pDC->MoveTo(itemRect.left+1, itemRect.bottom-1);
pDC->LineTo(itemRect.left+1, itemRect.top+1);
pDC->LineTo(itemRect.right, itemRect.top+1);
//黑线
pDC->SelectObject(pen3DDKShadow);
pDC->MoveTo(itemRect.left, itemRect.bottom-1);
pDC->LineTo(itemRect.right-1, itemRect.bottom-1);
pDC->LineTo(itemRect.right-1, itemRect.top-1);
//暗灰线
pDC->SelectObject(penBtnShadow);
pDC->MoveTo(itemRect.left+1, itemRect.bottom-2);
pDC->LineTo(itemRect.right-2, itemRect.bottom-2);
pDC->LineTo(itemRect.right-2, itemRect.top);
pDC->SelectObject(pOldPen);
}
}
//取得按钮标题
CString sTitle;
GetWindowText(sTitle);
//如果不希望显示按钮标题
if (m_bShowText == FALSE) sTitle.Empty();
CRect captionRect = lpDIS->rcItem;
//绘制图标
if (m_hIconIn != NULL)
{
DrawTheIcon(pDC, &sTitle, &lpDIS->rcItem, &captionRect, bIsPressed, bIsDisabled);
}
//
if (sTitle.IsEmpty() == FALSE)
{
if (bIsPressed)
captionRect.OffsetRect(1, 1);
#ifdef ST_USE_MEMDC
//取得对话框字体
CFont *pCurrentFont = GetFont();
CFont *pOldFont = pDC->SelectObject(pCurrentFont);
#endif
CRect centerRect = captionRect;
pDC->DrawText(sTitle, -1, captionRect, DT_SINGLELINE|DT_CALCRECT);
captionRect.OffsetRect((centerRect.Width() - captionRect.Width())/2, (centerRect.Height() - captionRect.Height())/2);
pDC->SetBkMode(TRANSPARENT);
pDC->DrawState(captionRect.TopLeft(), captionRect.Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL),
TRUE, 0, (CBrush*)NULL);
#ifdef ST_USE_MEMDC
pDC->SelectObject(pOldFont);
#endif
}
if (m_bIsFlat == FALSE || (m_bIsFlat == TRUE && m_bDrawFlatFocus == TRUE))
{
//绘制焦点框
if (bIsFocused)
{
CRect focusRect = itemRect;
focusRect.DeflateRect(3, 3);
pDC->DrawFocusRect(&focusRect);
}
}
} // End of DrawItem
void CButtonST::DrawTheIcon(CDC* pDC, CString* title, RECT* rcItem, CRect* captionRect, BOOL IsPressed, BOOL IsDisabled)
{
CRect iconRect = rcItem;
switch (m_nAlign)
{
case ST_ALIGN_HORIZ:
if (title->IsEmpty())
{
//水平放置图标
iconRect.left += ((iconRect.Width() - m_cxIcon)/2);
}
else
{
iconRect.left += 3;
captionRect->left += m_cxIcon + 3;
}
//垂直放置图标
iconRect.top += ((iconRect.Height() - m_cyIcon)/2);
break;
case ST_ALIGN_VERT:
//水平放置图标
iconRect.left += ((iconRect.Width() - m_cxIcon)/2);
if (title->IsEmpty())
{
//垂直放置图标
iconRect.top += ((iconRect.Height() - m_cyIcon)/2);
}
else
{
captionRect->top += m_cyIcon;
}
break;
}
if (IsPressed) iconRect.OffsetRect(1, 1);
pDC->DrawState(iconRect.TopLeft(),
iconRect.Size(),
(m_MouseOnButton == TRUE || IsPressed) ? m_hIconIn : m_hIconOut,
(IsDisabled ? DSS_DISABLED : DSS_NORMAL),
(CBrush*)NULL);
} // End of DrawTheIcon
void CButtonST::PreSubclassWindow()
{
UINT nBS;
nBS = GetButtonStyle();
if (nBS & BS_DEFPUSHBUTTON) m_bIsDefault = TRUE;
// Add BS_OWNERDRAW style
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
} // End of PreSubclassWindow
BOOL CButtonST::PreTranslateMessage(MSG* pMsg)
{
return CButton::PreTranslateMessage(pMsg);
} // End of PreTranslateMessage
LRESULT CButtonST::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_LBUTTONDBLCLK)
{
message = WM_LBUTTONDOWN;
}
return CButton::DefWindowProc(message, wParam, lParam);
} // End of DefWindowProc
//设置平面按钮焦点框
//如果参数bDrawFlatFocus为TRUE,则平面按钮有焦点框;否则没有
//如果参数bRepaint为TRUE,则按钮立即重画
void CButtonST::SetFlatFocus(BOOL bDrawFlatFocus, BOOL bRepaint)
{
m_bDrawFlatFocus = bDrawFlatFocus;
if (bRepaint == TRUE) Invalidate();
} // End of SetFlatFocus
BOOL CButtonST::GetFlatFocus()
{
return m_bDrawFlatFocus;
} // End of GetFlatFocus
BOOL CButtonST::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_hCursor != NULL)
{
::SetCursor(m_hCursor);
return TRUE;
}
return CButton::OnSetCursor(pWnd, nHitTest, message);
} // End of OnSetCursor
BOOL CButtonST::GetDefault()
{
return m_bIsDefault;
} // End of GetDefault
void CButtonST::DrawTransparent()
{
m_bDrawTransparent = TRUE;
} // End of DrawTransparent
void CButtonST::PaintBk(CDC * pDC)
{
CClientDC clDC(GetParent());
CRect rect;
CRect rect1;
GetClientRect(rect);
GetWindowRect(rect1);
GetParent()->ScreenToClient(rect1);
if (m_dcBk.m_hDC == NULL)
{
m_dcBk.CreateCompatibleDC(&clDC);
m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
}
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk, 0, 0, SRCCOPY);
} // End of PaintBk
#undef ST_USE_MEMDC
#undef ST_LIKEIE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -