⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flatbutton.cpp

📁 磁盘容量扫描、但界面和程序结构非常不错
💻 CPP
字号:
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1998 by Yuheng Zhao
// All rights reserved
//
// Distribute freely, except: don't remove my name from the source or
// documentation (don't take credit for my work), mark your changes (don't
// get me blamed for your possible bugs), don't alter or remove this
// notice.
// No warrantee of any kind, express or implied, is included with this
// software; use at your own risk, responsibility for damages (if any) to
// anyone resulting from the use of this software rests entirely with the
// user.
//
// If you have any questions, I can be reached as follows:
//    yuheng@ministars.com
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "flatbutton.h"

/////////////////////////////////////////////////////////////////////////////
// CFlatButton

CFlatButton::CFlatButton()
{
	dwFlags = FBS_BORDER|FBS_FOCUS|FBS_ROLLOVER;

	m_bMouseIn = FALSE;
	m_bChecked = FALSE;
	m_bClickAgain = FALSE;
}

CFlatButton::~CFlatButton()
{
}


BEGIN_MESSAGE_MAP(CFlatButton, CButton)
	//{{AFX_MSG_MAP(CFlatButton)
	ON_WM_MOUSEMOVE()
	ON_WM_KILLFOCUS()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONDBLCLK()
	//}}AFX_MSG_MAP
	ON_WM_TIMER()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFlatButton message handlers
void CFlatButton::OnMouseMove(UINT nFlags, CPoint point) 
{
	// If the mouse enter the button with the left button pressed
	// then do nothing
	//if (nFlags & MK_LBUTTON && m_bMouseIn == FALSE) return;

	CWnd* pWnd = GetActiveWindow();
	CWnd* pParent = GetOwner();

	CRect rect;
	GetClientRect(&rect);
	
	if (!rect.PtInRect(point))
	{
		if (m_bMouseIn == TRUE)
		{
			m_bMouseIn = FALSE;

			if (nFlags & MK_LBUTTON || (dwFlags&FBS_ROLLOVER))
				Invalidate();
		}
	}else if (m_bMouseIn == FALSE && ((pWnd != NULL) && (pParent != NULL)))
	{
		m_bMouseIn = TRUE;
		KillTimer(14);
		SetTimer(14, 10, NULL);

		if (nFlags & MK_LBUTTON || (dwFlags&FBS_ROLLOVER))
			InvalidateRect(NULL, FALSE);
	}

	CButton::OnMouseMove(nFlags, point);
}

void CFlatButton::OnKillFocus(CWnd* pNewWnd) 
{
	CButton::OnKillFocus(pNewWnd);
	
	if (m_bMouseIn == TRUE)
	{
	    m_bMouseIn = FALSE;
	    InvalidateRect(NULL, FALSE);
	    UpdateWindow();
	}	
}

#define _FBS_SPACE_ 4
#define _FBS_ARROWWIDTH_ 11
void CFlatButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	CDC* pDC   = CDC::FromHandle(lpDrawItemStruct->hDC);
	CRect rcClient = lpDrawItemStruct->rcItem;
	UINT state = lpDrawItemStruct->itemState;

	COLORREF colorFace = GetSysColor(COLOR_BTNFACE);
	COLORREF colorShadow = GetSysColor(COLOR_3DSHADOW);
	COLORREF colorLight = GetSysColor(COLOR_3DHILIGHT);
	
	CDC memDC;
	memDC.CreateCompatibleDC( pDC );

	// Select a compatible bitmap into the memory DC
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap( pDC, rcClient.Width(), rcClient.Height() );
	CBitmap* pOldBitmap = memDC.SelectObject( &bitmap );

	if (m_bChecked && (!m_bMouseIn || dwFlags & FBS_MENU_BUTTON || !(dwFlags&FBS_ROLLOVER)))
	{
		CBrush *pBrush = CDC::GetHalftoneBrush();
		memDC.SetTextColor(colorLight);
		memDC.SetBkColor(colorFace);
		memDC.FillRect(rcClient, pBrush);
		//dc.SetTextColor(RGB(0,0,0));
		//dc.SetBkColor(clrRect);
	}else
		memDC.FillSolidRect(rcClient, colorFace);

	int nIconOffset = 0;
	CString strText;
	GetWindowText(strText);

	bool bHasText = !strText.IsEmpty();
	CSize szText;

	if (bHasText)
	{
		CFont *pFont = GetFont();

		CFont* pOldFont = memDC.SelectObject (pFont);
		szText = memDC.GetTextExtent(strText);
		memDC.SelectObject (pOldFont);
	}

	if (dwFlags & FBS_HAS_ICON)
	{
		ASSERT(m_hIcon!=0);
		CRect rcIcon(rcClient);

		int nOffset = 0;

		if (!bHasText)
			nOffset = ((rcIcon.Width() - m_nIconWidth)/2);
		else
			nOffset = ((rcIcon.Width() - m_nIconWidth - szText.cx)/3);
			
		rcIcon.left += nOffset;

		rcIcon.top += ((rcIcon.Height() - m_nIconHeight)/2);

		if (state & ODS_SELECTED)
			rcIcon.OffsetRect(1, 1);

		/*::DrawIconEx(memDC.GetSafeHdc(), rcIcon.left, rcIcon.top,
			m_hIcon, m_nIconHeight, m_nIconWidth, 0, NULL,
			DI_NORMAL);*/
		memDC.DrawState(rcIcon.TopLeft(), 
						CSize(m_nIconWidth,m_nIconHeight), 
				        m_hIcon, 
				        ((state & ODS_DISABLED)? DSS_DISABLED : DSS_NORMAL), 
						(CBrush*)NULL);

		//memDC.DrawIcon(rcIcon.TopLeft(), m_hIcon);

		nIconOffset = nOffset*2+m_nIconWidth;
	}
	
	if ( bHasText)
	{
		CFont *pFont = GetFont();

		CFont* pOldFont = memDC.SelectObject (pFont);
		int iOldMode = memDC.GetBkMode();
		memDC.SetBkMode( TRANSPARENT );
		COLORREF crOldText ;
		crOldText = memDC.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));

		//CSize szText = memDC.GetTextExtent(strText);
		CPoint ptText;

		if (dwFlags & FBS_ARROW_UP || dwFlags & FBS_ARROW_DOWN)
		{
			int nTotalWidth = szText.cx + _FBS_SPACE_ + _FBS_ARROWWIDTH_;

			if (nIconOffset) // If has icon
				ptText.x = nIconOffset;
			else // Centrum
				ptText.x = (rcClient.Width()-nTotalWidth)/2;
			ptText.y = (rcClient.Height()-szText.cy)/2;
			
			// Draw Arrows if nessesary
			CPoint pt;
			pt.x = ptText.x + szText.cx  + _FBS_SPACE_;
			pt.y = (rcClient.Height() - _FBS_ARROWWIDTH_/2) / 2;
			
			if (state & ODS_SELECTED)
				pt.Offset(1,1);
			
			memDC.SelectStockObject(BLACK_PEN);
			memDC.SelectStockObject(BLACK_BRUSH);
			DrawArrow(&memDC, pt, _FBS_ARROWWIDTH_, dwFlags);
		}else
		{
			if (nIconOffset) // If has icon
				ptText.x = nIconOffset;
			else // Centrum
				ptText.x = (rcClient.Width()-szText.cx)/2;
			ptText.y = (rcClient.Height()-szText.cy)/2;
		}

		if (state & ODS_SELECTED)
			ptText.Offset(1,1);
		
		if (state & ODS_DISABLED)
			memDC.DrawState(ptText, szText, strText, DSS_DISABLED, 
				TRUE, 0, (HBRUSH)NULL);
		else
			memDC.DrawText(strText, CRect(ptText,szText), DT_CENTER|DT_VCENTER);

		memDC.SetBkMode( iOldMode );
		memDC.SetTextColor( crOldText );
		memDC.SelectObject (pOldFont);
	}

	if (state & ODS_SELECTED )
		memDC.DrawEdge(rcClient, BDR_SUNKENOUTER, BF_RECT);
	else if (m_bChecked)
	{
		if (!(dwFlags&FBS_CHECKED_NOBORDER))
			memDC.DrawEdge(rcClient, BDR_SUNKENOUTER, BF_RECT);
	}else if ((!m_bMouseIn) || !(dwFlags&FBS_ROLLOVER))
	{
		if (dwFlags & FBS_BORDER)
			memDC.DrawEdge(rcClient, BDR_RAISEDINNER, BF_RECT);
			//memDC.Draw3dRect(rcClient, colorLight, colorShadow);
	}else
	{
		if (dwFlags & FBS_BORDER)
			memDC.DrawEdge(rcClient, EDGE_RAISED, BF_RECT);
		else
			memDC.Draw3dRect(rcClient, colorLight, colorShadow);
	}

	pDC->BitBlt( 0, 0, rcClient.Width(), rcClient.Height(), &memDC, 
				0, 0, SRCCOPY );

	if (state & ODS_FOCUS && dwFlags & FBS_FOCUS)
	{
		CRect r(rcClient);
		r.DeflateRect(3,3);

		pDC->DrawFocusRect(r);
		//memDC.DrawEdge(r, EDGE_RAISED, BF_RECT);
		//::DrawFocusRect(memDC.m_hDC, r);
	}

	memDC.SelectObject( pOldBitmap);
}

void CFlatButton::PreSubclassWindow() 
{
	SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW);

	CButton::PreSubclassWindow();
}

void CFlatButton::OnTimer(UINT nIDEvent)
{
	if (m_bMouseIn == FALSE)
	{
		KillTimer(14);
		return;
	}

	CRect rect;
	GetClientRect(&rect);

	CPoint point;
	GetCursorPos(&point);
	ScreenToClient(&point);
	
	if (!rect.PtInRect(point) && m_bMouseIn == TRUE)
	{
		KillTimer(14);

		m_bMouseIn = FALSE;

		if (dwFlags&FBS_ROLLOVER)
			Invalidate();
	}
}

void CFlatButton::ModifyFlag(const DWORD & dwRemove, const DWORD & dwAdd, const UINT bRedraw)
{
	if (dwRemove)	dwFlags &= ~(dwRemove);
	if (dwAdd)		dwFlags |= dwAdd;

	if (bRedraw) 
		InvalidateRect(NULL);
}

void CFlatButton::DrawArrow(CDC* pDC, const CPoint& ptTopLeft, int nWidth, DWORD dwType)
{
	POINT ptArray[3];

	if (((dwType & FBS_ARROW_DOWN) && !m_bChecked) || ((dwType & FBS_ARROW_UP) && m_bChecked))
	{
		ptArray[0] = ptTopLeft;
		ptArray[1].x = ptTopLeft.x + nWidth - nWidth%2;
		ptArray[1].y = ptTopLeft.y;
		ptArray[2].x = ptTopLeft.x + nWidth / 2;
		ptArray[2].y = ptTopLeft.y + nWidth / 2;

		pDC->Polygon(ptArray, 3);
	}else if (((dwType & FBS_ARROW_UP) && !m_bChecked) || ((dwType & FBS_ARROW_DOWN) && m_bChecked))
	{
		ptArray[0].x = ptTopLeft.x;
		ptArray[0].y = ptTopLeft.y + nWidth / 2;
		ptArray[1].x = ptTopLeft.x + nWidth - nWidth%2;
		ptArray[1].y = ptTopLeft.y + nWidth / 2;
		ptArray[2].x = ptTopLeft.x + nWidth / 2;
		ptArray[2].y = ptTopLeft.y;

		pDC->Polygon(ptArray, 3);
	}
	
}

void CFlatButton::SetCheck(BOOL b)
{
	m_bChecked = b;
	InvalidateRect(NULL);
}

BOOL CFlatButton::GetCheck()
{
	return m_bChecked;
}

void CFlatButton::SetIcon(HICON hIcon, BYTE cx, BYTE cy)
{
	m_hIcon = hIcon;
	m_nIconWidth = cx;
	m_nIconHeight = cy;
}

void CFlatButton::DoMenu()
{
	if (dwFlags & FBS_MENU_BUTTON)
	{
		if (m_bClickAgain)
		{
			m_bClickAgain = FALSE;
			return;
		}

		ASSERT(m_pMenu!=NULL);

		SetCheck(TRUE);

		CRect rect;
		GetWindowRect(&rect);	
		CPoint pt;
		pt = rect.TopLeft();
		DWORD dwMenu = TPM_LEFTALIGN;
		if (dwFlags & FBS_MENU_ALIGN_RIGHT)
			pt.x += rect.Width();
		if (!(dwFlags & FBS_MENU_ALIGN_TOP))		
			pt.y += rect.Height();

		if (dwFlags & FBS_MENU_ALIGN_RIGHT && !(dwFlags & FBS_MENU_ALIGN_TOP))
			dwMenu = TPM_RIGHTALIGN;
		else if (!(dwFlags & FBS_MENU_ALIGN_RIGHT) && (dwFlags & FBS_MENU_ALIGN_TOP))
			dwMenu = TPM_RIGHTALIGN;

		GetOwner()->SendMessage(WM_FB_NOTIFY, FB_NOTIFY_INITMENU, (LPARAM)m_pMenu);

		int n = m_pMenu->TrackPopupMenu(dwMenu|TPM_RIGHTBUTTON|TPM_RETURNCMD, pt.x, pt.y, GetOwner());
		
		SetCheck(FALSE);

		if (n>0)
		{
			GetOwner()->SendMessage(WM_COMMAND, n, NULL);
		}else
		{
			CPoint pt;
			GetCursorPos(&pt);
			if (rect.PtInRect(pt))
				m_bClickAgain = TRUE;
			else
				m_bClickAgain = FALSE;
		}		
	}
}

void CFlatButton::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CButton::OnLButtonDown(nFlags, point);

	DoMenu();
}

LRESULT CFlatButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	if (message == WM_LBUTTONDBLCLK && !(dwFlags & FBS_MENU_BUTTON))
	{
		message = WM_LBUTTONDOWN;
	}

	return CButton::DefWindowProc(message, wParam, lParam);
}

void CFlatButton::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	CButton::OnLButtonDblClk(nFlags, point);
	DoMenu();
}

BOOL CFlatButton::PreTranslateMessage(MSG* pMsg) 
{
	if (m_ToolTip.GetSafeHwnd()!=NULL)
		m_ToolTip.RelayEvent(pMsg);
	
	return CButton::PreTranslateMessage(pMsg);
}

void CFlatButton::SetTooltipText(int nId, BOOL bActivate)
{
	CString str;
	str.LoadString(nId);
	
	if (!str.IsEmpty()) 
		SetTooltipText(str, bActivate);
}

void CFlatButton::SetTooltipText(LPCTSTR strTooltip, BOOL bActivate)
{
	if (!m_ToolTip.GetSafeHwnd())
		m_ToolTip.Create(this);

	if (!m_ToolTip.GetToolCount())
	{
		CRect rc; 
		GetClientRect(rc);
		m_ToolTip.AddTool(this, strTooltip, rc, GetDlgCtrlID());
	}

	m_ToolTip.UpdateTipText(strTooltip, this, GetDlgCtrlID());
	m_ToolTip.Activate(bActivate);
}

void CFlatButton::EnableTooltip(BOOL bEnable)
{
	if (!m_ToolTip.GetSafeHwnd())
		return;

	if (!m_ToolTip.GetToolCount()) 
		return;

	m_ToolTip.Activate(bEnable);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -