MFC下一个简单的按钮重绘,功能不是那么全
#if !defined(AFX_BMPBUTTON_H__FBB70540_EC88_4021_9272_574C1A7A571B__INCLUDED_)
#define AFX_BMPBUTTON_H__FBB70540_EC88_4021_9272_574C1A7A571B__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// BmpButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CBmpButton window
class CBmpButton : public CButton
{
// Construction
public:
BOOL m_bNonToolBarBtn;
UINT m_uiDisBmpID;
UINT m_uiNorBmpID;
CBmpButton();
void SetNonToolBarBtn(BOOL bBtn);
void SetBitmap(UINT nBmpID);
void SetItemData(DWORD dwData){m_dwData=dwData;}
void SetDisableBmp(UINT nBmpID){m_uiDisBmpID=nBmpID;}
void SetNormalBmp(UINT nBmpID){m_uiNorBmpID=nBmpID;}
/*
OK 可用 不可用 SetNorBmp SetDisBmp
Select All 可用 可用
Zoomin 可用 不可用 可用 不可用 SetNorBmp SetDisBmp SetNorBmp SetDisBmp
*/
DWORD GetItemData(){return m_dwData;}
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBmpButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
virtual void PreSubclassWindow();
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CBmpButton();
// Generated message map functions
protected:
//{{AFX_MSG(CBmpButton)
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
afx_msg void OnCaptureChanged(CWnd *pWnd);
afx_msg void OnKillFocus(CWnd* pNewWnd);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
//}}AFX_MSG
void ResetWndRgn();
DECLARE_MESSAGE_MAP()
private:
BOOL m_bIsTracking;
BOOL m_bIsHovering;
HBITMAP m_hBitmap;
BOOL m_MouseOnButton;
DWORD m_dwData;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_BMPBUTTON_H__FBB70540_EC88_4021_9272_574C1A7A571B__INCLUDED_)
实现
// BmpButton.cpp : implementation file
//
#include "stdafx.h"
#include "BmpButton.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
extern CFont* g_DisplayFont24;
/////////////////////////////////////////////////////////////////////////////
// CBmpButton
CBmpButton::CBmpButton()
{
m_hBitmap=NULL;
m_MouseOnButton=FALSE;
m_dwData=0xFFFFFFFF;
m_bIsTracking = FALSE;
m_bIsHovering = FALSE;
m_uiDisBmpID = -1;
m_uiNorBmpID = -1;
m_bNonToolBarBtn = FALSE;
}
CBmpButton::~CBmpButton()
{
if(m_hBitmap)::DeleteObject(m_hBitmap);
}
BEGIN_MESSAGE_MAP(CBmpButton, CButton)
//{{AFX_MSG_MAP(CBmpButton)
ON_WM_CTLCOLOR()
ON_WM_CAPTURECHANGED()
ON_WM_KILLFOCUS()
ON_WM_MOUSEMOVE()
ON_WM_SIZE()
ON_WM_ERASEBKGND()
ON_WM_SETCURSOR()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBmpButton message handlers
HBRUSH CBmpButton::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
return (HBRUSH)::GetStockObject(NULL_BRUSH);
}
void CBmpButton::PreSubclassWindow()
{
ModifyStyle(0,BS_OWNERDRAW);
ResetWndRgn();
CButton::PreSubclassWindow();
}
void CBmpButton::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pWnd;
CWnd* pParent;
if(!m_bIsTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE|TME_HOVER;
tme.dwHoverTime = 1;
m_bIsTracking = _TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
if (nFlags & MK_LBUTTON && m_MouseOnButton == FALSE) return;
pWnd = GetActiveWindow();
pParent = GetOwner();
if ((GetCapture() != this) && (pWnd != NULL && pParent != NULL))
{
m_MouseOnButton = TRUE;
SetFocus();
SetCapture();
Invalidate();
}
else
{
CRect rc;
GetClientRect(&rc);
if(!rc.PtInRect(point))
{
if(m_MouseOnButton == TRUE)
{
m_MouseOnButton = FALSE;
Invalidate();
}
if(!(nFlags & MK_LBUTTON)) ReleaseCapture();
}
}
}
LRESULT CBmpButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bIsTracking = FALSE;
m_bIsHovering = FALSE;
Invalidate();
return 0;
}
LRESULT CBmpButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bIsHovering = TRUE;
Invalidate();
return 0;
}
void CBmpButton::OnKillFocus(CWnd * pNewWnd)
{
CButton::OnKillFocus(pNewWnd);
if(m_MouseOnButton == TRUE){
m_MouseOnButton = FALSE;
Invalidate();
}
}
void CBmpButton::OnCaptureChanged(CWnd *pWnd)
{
if (m_MouseOnButton == TRUE){
ReleaseCapture();
Invalidate();
}
CButton::OnCaptureChanged(pWnd);
}
void CBmpButton::SetBitmap(UINT nBmpID)
{
HINSTANCE hInstResource = NULL;
hInstResource = AfxFindResourceHandle(MAKEINTRESOURCE(nBmpID), RT_BITMAP);
if(m_hBitmap)::DeleteObject(m_hBitmap);
m_hBitmap = (HBITMAP)::LoadImage(hInstResource, MAKEINTRESOURCE(nBmpID), IMAGE_BITMAP, 0, 0, 0);
}
void CBmpButton::ResetWndRgn()
{
CRect rcItem;
GetClientRect(&rcItem);
#define DOTS 5
CPoint pt[8];
pt[0].x=DOTS; pt[0].y=0;
pt[1].x=rcItem.right-DOTS; pt[1].y=0;
pt[2].x=rcItem.right; pt[2].y=DOTS;
pt[3].x=rcItem.right; pt[3].y=rcItem.bottom-DOTS;
pt[4].x=rcItem.right-DOTS; pt[4].y=rcItem.bottom;
pt[5].x=DOTS; pt[5].y=rcItem.bottom;
pt[6].x=rcItem.left; pt[6].y=rcItem.bottom-DOTS;
pt[7].x=rcItem.left; pt[7].y=DOTS;
HRGN hRgn=::CreatePolygonRgn(pt,8,ALTERNATE);
// HRGN hRgn = CreateRoundRectRgn(0,0,rcItem.right-rcItem.left,rcItem.bottom-rcItem.top,50,50);
SetWindowRgn(hRgn,TRUE);
::DeleteObject(hRgn);
}
void CBmpButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
HDC hDC = lpDrawItemStruct->hDC;
BOOL bIsPressed = (lpDrawItemStruct->itemState & ODS_SELECTED);
BOOL bIsFocused = (lpDrawItemStruct->itemState & ODS_FOCUS);
BOOL bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);
CRect rcItem = lpDrawItemStruct->rcItem;
CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
CString strTitle;
GetWindowText(strTitle);
CFont *pOldFont=pDC->SelectObject(g_DisplayFont24);
CSize szText=pDC->GetTextExtent(strTitle);
::SetBkMode(hDC,TRANSPARENT);
CRect rcCalc=rcItem;
if(bIsDisabled)
{
pDC->FillSolidRect(&rcItem,RGB(97,198,49));
pDC->SetTextColor(RGB(128,128,128));
}
else if(m_bIsHovering)
{
CBrush brsh;
brsh.CreateSolidBrush(RGB(32,143,255));//76,137,189 18,118,191
CPoint pt(10,10);
CPen pen(PS_SOLID,1,RGB(32,143,255));//76,137,189 18,118,191
pDC->SelectObject(&brsh);
pDC->SelectObject(&pen);
pDC->RoundRect(&rcItem,pt);
if(bIsPressed)
pDC->SetTextColor(RGB(255,0,0));
else
pDC->SetTextColor(RGB(0,0,0));
}
else
{
// pDC->FillSolidRect(&rcItem,RGB(97,198,49));
pDC->SetTextColor(RGB(0,0,0));//设置按钮文字的颜色
CPen pen(PS_SOLID,1,RGB(0,128,255));//98,177,245 8,109,169
CBrush brsh;
brsh.CreateSolidBrush(RGB(0,128,255));//98,177,245 8,109,169
CPoint pt(10,10);
pDC->SelectObject(&brsh);
pDC->SelectObject(&pen);
pDC->RoundRect(&rcItem,pt);
}
if(szText.cx>rcItem.Width())
{
rcCalc.left = rcItem.left;
rcCalc.right= rcItem.right;
}
else
{
rcCalc.left = (rcItem.Width()-szText.cx)/2;
rcCalc.right= rcCalc.left+szText.cx;
}
rcCalc.top = rcItem.top;
rcCalc.bottom = rcItem.bottom;
pDC->DrawText(strTitle,rcCalc,/*DT_WORDBREAK*/DT_CENTER|DT_VCENTER|DT_SINGLELINE);
pDC->SelectObject(pOldFont);
}
void CBmpButton::OnSize(UINT nType, int cx, int cy)
{
CButton::OnSize(nType, cx, cy);
if(IsWindow(m_hWnd))ResetWndRgn();
}
BOOL CBmpButton::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
BOOL CBmpButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
::SetCursor(AfxGetApp()->LoadStandardCursor(MAKEINTRESOURCE(32649)));
return TRUE;
}
void CBmpButton::SetNonToolBarBtn(BOOL bBtn)
{
m_bNonToolBarBtn = bBtn;
}
//////////////////////////////////////////////////////////////////////////
/*
void CBmpButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
HDC hDC = lpDrawItemStruct->hDC;
BOOL bIsDisabled = (lpDrawItemStruct->itemState & ODS_DISABLED);
CRect rcItem = lpDrawItemStruct->rcItem;
CDC *pDC=CDC::FromHandle(lpDrawItemStruct->hDC);
HDC hMemDC;
CString strTitle;
GetWindowText(strTitle);
CSize szText=pDC->GetTextExtent(strTitle);
CFont *pOldFont=pDC->SelectObject(g_DisplayFont16);
::SetBkMode(hDC,TRANSPARENT);
CRect rcCalc=rcItem;
CRect rcBmp(0,0,39,36);
if(bIsDisabled)
pDC->SetTextColor(RGB(128,128,128));
else if(m_bIsHovering)
{
HRGN hRgnRct;
hRgnRct = CreateRoundRectRgn(0,0,rcItem.right-rcItem.left,rcItem.bottom-rcItem.top,5,5);
SetWindowRgn(hRgnRct,TRUE);
pDC->FillSolidRect(&rcItem,RGB(255,255,255));
pDC->SetTextColor(RGB(0,0,0));
}
else
{
HRGN hRgnRct;
hRgnRct = CreateRoundRectRgn(0,0,rcItem.right-rcItem.left,rcItem.bottom-rcItem.top,5,5);
SetWindowRgn(hRgnRct,TRUE);
pDC->FillSolidRect(&rcItem,RGB(23,75,153));
pDC->SetTextColor(RGB(255,255,255));
}
if(szText.cx>rcItem.Width())
{
rcCalc.left = rcItem.left;
rcCalc.right= rcItem.right;
}
else
{14
rcCalc.left = (rcItem.Width()-szText.cx)/2;
rcCalc.right= rcCalc.left+szText.cx;
}
rcCalc.top = rcBmp.Height()+5;
rcCalc.bottom = rcItem.bottom;
hMemDC=::CreateCompatibleDC(hDC);
::SelectObject(hMemDC,m_hBitmap);
::SetStretchBltMode(hDC,COLORONCOLOR);
::StretchBlt(hDC,(rcItem.Width()-rcBmp.Width())/2,5,rcBmp.Width(),rcBmp.Height(),hMemDC,rcBmp.left,rcBmp.top,rcBmp.Width(),rcBmp.Height(),SRCCOPY);
pDC->DrawText(strTitle,rcCalc,DT_WORDBREAK);
pDC->SelectObject(pOldFont);
::DeleteDC(hMemDC);
}*/