http://blog.youkuaiyun.com/yuzhenxiong0823/article/details/23278763
最近在为公司用MFC做产品界面。因为是小公司,所以也没有现成的界面库,必须自己一点一点写。自己在网上收集了点资料,就写了几个类型的button类,以供以后使用。
目前为止,做了三种类型的按钮,分别是:
1.一般情况使用的,比较常用的button类CNormalBtn;
2.特殊一点的,类似拥有菜单功能的button类CMenuBtn(和CNormal的区别是按钮selected后的状态不会随着鼠标的离开而消失);
3.静态按钮,用来呈现log等图片之类的button类CStatic,该类不会响应鼠标事件。
对于1,2种按钮,用的图片模式是:(png格式,一幅图里有四副小图,依次表示NoFoucs,Mousemove, buttondown, Disable四种状态);
对于3类按钮,用的图片模式是:(png格式)
下面贴代码:
基类代码(BaseBtn.h)
- #ifndef __BASEBTN_H__
- #define __BASEBTN_H__
- #include "stdafx.h"
- #include <atlimage.h>
- #if _MSC_VER > 1000
- #pragma once
- #endif
- class CBaseBtn : public CButton
- {
- public:
- CBaseBtn();
- ~CBaseBtn();
- public:
- virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
- virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
- virtual void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
- virtual void SetWindowText(LPCTSTR lpszString);
- public:
- void Init(UINT uImageID);
- void SetBtnTextColor(COLORREF clr);
- protected:
- afx_msg BOOL OnEraseBkgnd(CDC* pDC);
- DECLARE_MESSAGE_MAP()
- protected:
- int m_nCtrlState;
- CImage m_Image;
- int m_nSrcWidth;
- int m_nSrcHeight;
- private:
- CString m_strBtnText;
- CFont* m_pFont;
- COLORREF m_clr;
- };
- #endif
#ifndef __BASEBTN_H__
#define __BASEBTN_H__
#include "stdafx.h"
#include <atlimage.h>
#if _MSC_VER > 1000
#pragma once
#endif
class CBaseBtn : public CButton
{
public:
CBaseBtn();
~CBaseBtn();
public:
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void SetFont(CFont* pFont, BOOL bRedraw = TRUE);
virtual void SetWindowText(LPCTSTR lpszString);
public:
void Init(UINT uImageID);
void SetBtnTextColor(COLORREF clr);
protected:
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()
protected:
int m_nCtrlState;
CImage m_Image;
int m_nSrcWidth;
int m_nSrcHeight;
private:
CString m_strBtnText;
CFont* m_pFont;
COLORREF m_clr;
};
#endif
基类代码(BaseBtn.cpp)
- #include "stdafx.h"
- #include "BaseBtn.h"
- #include "Public.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CBaseBtn::CBaseBtn()
- {
- m_pFont = new CFont;
- VERIFY(m_pFont->CreateFont(15, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
- CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Tahoma")));
- m_strBtnText = L"";
- m_clr = RGB(0, 0, 0);
- }
- CBaseBtn::~CBaseBtn()
- {
- if (!m_Image.IsNull())
- m_Image.Destroy();
- if (m_pFont != NULL)
- {
- m_pFont->DeleteObject();
- delete m_pFont;
- m_pFont = NULL;
- }
- }
- BEGIN_MESSAGE_MAP(CBaseBtn, CButton)
- ON_WM_ERASEBKGND()
- END_MESSAGE_MAP()
- void CBaseBtn::Init(UINT uImageID)
- {
- SetButtonStyle(BS_OWNERDRAW);
- LoadPicture(m_Image, uImageID);
- m_nSrcWidth = m_Image.GetWidth();
- m_nSrcHeight = m_Image.GetHeight();
- SetWindowPos(NULL, 0, 0, m_nSrcWidth/4, m_nSrcHeight, SWP_NOMOVE|SWP_NOACTIVATE);
- if (IsWindowEnabled())
- m_nCtrlState = CTRL_NOFOCUS;
- else
- m_nCtrlState = CTRL_DISABLE;
- }
- void CBaseBtn::SetFont(CFont* pFont, BOOL bRedraw)
- {
- m_pFont = pFont;
- if(bRedraw)
- Invalidate();
- }
- void CBaseBtn::SetWindowText(LPCTSTR lpszString)
- {
- m_strBtnText = lpszString;
- Invalidate();
- }
- void CBaseBtn::SetBtnTextColor(COLORREF clr)
- {
- m_clr = clr;
- Invalidate();
- }
- BOOL CBaseBtn::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
- {
- return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
- }
- void CBaseBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- if (m_Image.IsNull())
- return ;
- CRect buttonRect;
- GetClientRect(buttonRect);
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); //按钮控件DC
- CDC dcMem;
- dcMem.CreateCompatibleDC(pDC);
- CBitmap memBitmap;
- memBitmap.CreateCompatibleBitmap(pDC, buttonRect.Width(), buttonRect.Height());
- dcMem.SelectObject(memBitmap);
- dcMem.FillSolidRect(buttonRect, RGB(255,0,255)); //设置画布颜色
- CRect rcSrc = CRect(0,0,0,0);
- switch(m_nCtrlState)
- {
- case CTRL_NOFOCUS:
- {
- rcSrc = CRect(0, 0, m_nSrcWidth/4, m_nSrcHeight);
- }
- break;
- case CTRL_FOCUS:
- {
- rcSrc = CRect(m_nSrcWidth/4, 0, m_nSrcWidth/4 * 2, m_nSrcHeight);
- }
- break;
- case CTRL_SELECTED:
- {
- rcSrc = CRect(m_nSrcWidth/4 * 2, 0, m_nSrcWidth/4 * 3, m_nSrcHeight);
- }
- break;
- case CTRL_DISABLE:
- {
- rcSrc = CRect(m_nSrcWidth/4 * 3, 0, m_nSrcWidth, m_nSrcHeight);
- }
- break;
- default:
- break;
- }
- m_Image.Draw(dcMem.m_hDC, buttonRect, rcSrc);
- dcMem.SetBkMode(TRANSPARENT);
- dcMem.SetTextColor(m_clr);
- CFont* pOldFont = dcMem.SelectObject(m_pFont);
- DrawText(dcMem.m_hDC, m_strBtnText, -1, buttonRect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
- dcMem.SelectObject(pOldFont);
- pDC->BitBlt(0, 0, buttonRect.Width(), buttonRect.Height(), &dcMem, 0, 0, SRCCOPY);
- memBitmap.DeleteObject();
- }
- BOOL CBaseBtn::OnEraseBkgnd(CDC* pDC)
- {
- return TRUE;
- }
#include "stdafx.h"
#include "BaseBtn.h"
#include "Public.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CBaseBtn::CBaseBtn()
{
m_pFont = new CFont;
VERIFY(m_pFont->CreateFont(15, 0, 0, 0, FW_BOLD, FALSE, FALSE, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Tahoma")));
m_strBtnText = L"";
m_clr = RGB(0, 0, 0);
}
CBaseBtn::~CBaseBtn()
{
if (!m_Image.IsNull())
m_Image.Destroy();
if (m_pFont != NULL)
{
m_pFont->DeleteObject();
delete m_pFont;
m_pFont = NULL;
}
}
BEGIN_MESSAGE_MAP(CBaseBtn, CButton)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
void CBaseBtn::Init(UINT uImageID)
{
SetButtonStyle(BS_OWNERDRAW);
LoadPicture(m_Image, uImageID);
m_nSrcWidth = m_Image.GetWidth();
m_nSrcHeight = m_Image.GetHeight();
SetWindowPos(NULL, 0, 0, m_nSrcWidth/4, m_nSrcHeight, SWP_NOMOVE|SWP_NOACTIVATE);
if (IsWindowEnabled())
m_nCtrlState = CTRL_NOFOCUS;
else
m_nCtrlState = CTRL_DISABLE;
}
void CBaseBtn::SetFont(CFont* pFont, BOOL bRedraw)
{
m_pFont = pFont;
if(bRedraw)
Invalidate();
}
void CBaseBtn::SetWindowText(LPCTSTR lpszString)
{
m_strBtnText = lpszString;
Invalidate();
}
void CBaseBtn::SetBtnTextColor(COLORREF clr)
{
m_clr = clr;
Invalidate();
}
BOOL CBaseBtn::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}
void CBaseBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (m_Image.IsNull())
return ;
CRect buttonRect;
GetClientRect(buttonRect);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); //按钮控件DC
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap(pDC, buttonRect.Width(), buttonRect.Height());
dcMem.SelectObject(memBitmap);
dcMem.FillSolidRect(buttonRect, RGB(255,0,255)); //设置画布颜色
CRect rcSrc = CRect(0,0,0,0);
switch(m_nCtrlState)
{
case CTRL_NOFOCUS:
{
rcSrc = CRect(0, 0, m_nSrcWidth/4, m_nSrcHeight);
}
break;
case CTRL_FOCUS:
{
rcSrc = CRect(m_nSrcWidth/4, 0, m_nSrcWidth/4 * 2, m_nSrcHeight);
}
break;
case CTRL_SELECTED:
{
rcSrc = CRect(m_nSrcWidth/4 * 2, 0, m_nSrcWidth/4 * 3, m_nSrcHeight);
}
break;
case CTRL_DISABLE:
{
rcSrc = CRect(m_nSrcWidth/4 * 3, 0, m_nSrcWidth, m_nSrcHeight);
}
break;
default:
break;
}
m_Image.Draw(dcMem.m_hDC, buttonRect, rcSrc);
dcMem.SetBkMode(TRANSPARENT);
dcMem.SetTextColor(m_clr);
CFont* pOldFont = dcMem.SelectObject(m_pFont);
DrawText(dcMem.m_hDC, m_strBtnText, -1, buttonRect, DT_CENTER|DT_SINGLELINE|DT_VCENTER);
dcMem.SelectObject(pOldFont);
pDC->BitBlt(0, 0, buttonRect.Width(), buttonRect.Height(), &dcMem, 0, 0, SRCCOPY);
memBitmap.DeleteObject();
}
BOOL CBaseBtn::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
第一类button(NormalBtn.h)
- #ifndef __NORMALBTN_H__
- #define __NORMALBTN_H__
- #include "BaseBtn.h"
- class CNormalBtn : public CBaseBtn
- {
- public:
- CNormalBtn();
- ~CNormalBtn();
- protected:
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
- afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
- afx_msg LRESULT OnMouseHover(WPARAM, LPARAM);
- DECLARE_MESSAGE_MAP()
- private:
- BOOL m_bTracking; // 捕获设置标记
- };
- #endif
#ifndef __NORMALBTN_H__
#define __NORMALBTN_H__
#include "BaseBtn.h"
class CNormalBtn : public CBaseBtn
{
public:
CNormalBtn();
~CNormalBtn();
protected:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
afx_msg LRESULT OnMouseHover(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
private:
BOOL m_bTracking; // 捕获设置标记
};
#endif
第一类button(NormalBtn. cpp)
- #include "stdafx.h"
- #include "NormalBtn.h"
- #include "Public.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CNormalBtn::CNormalBtn()
- :m_bTracking(FALSE)
- {
- }
- CNormalBtn::~CNormalBtn()
- {
- }
- BEGIN_MESSAGE_MAP(CNormalBtn, CBaseBtn)
- ON_WM_MOUSEMOVE()
- ON_WM_LBUTTONDOWN()
- ON_WM_LBUTTONUP()
- ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
- ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover)
- END_MESSAGE_MAP()
- void CNormalBtn::OnMouseMove(UINT nFlags, CPoint point)
- {
- if (!m_bTracking)
- {
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof(tme);
- tme.hwndTrack = m_hWnd;
- tme.dwFlags = TME_LEAVE|TME_HOVER;
- tme.dwHoverTime = 1;
- m_bTracking = _TrackMouseEvent(&tme);
- }
- CBaseBtn::OnMouseMove(nFlags, point);
- }
- LRESULT CNormalBtn::OnMouseHover(WPARAM wParam,LPARAM lParam)
- {
- if (m_nCtrlState == CTRL_NOFOCUS)
- {
- m_nCtrlState = CTRL_FOCUS;
- Invalidate();
- }
- m_bTracking = FALSE;
- return 0;
- }
- LRESULT CNormalBtn::OnMouseLeave(WPARAM wParam,LPARAM lParam)
- {
- if(m_nCtrlState != CTRL_NOFOCUS)
- {
- m_nCtrlState = CTRL_NOFOCUS;
- Invalidate();
- }
- m_bTracking = FALSE;
- return 0;
- }
- void CNormalBtn::OnLButtonDown(UINT nFlags, CPoint point)
- {
- if(m_nCtrlState == CTRL_FOCUS)
- {
- m_nCtrlState = CTRL_SELECTED;
- Invalidate();
- }
- CBaseBtn::OnLButtonDown(nFlags, point);
- }
- void CNormalBtn::OnLButtonUp(UINT nFlags, CPoint point)
- {
- if(m_nCtrlState == CTRL_SELECTED)
- {
- m_nCtrlState = CTRL_FOCUS;
- Invalidate();
- }
- CBaseBtn::OnLButtonUp(nFlags, point);
- }
#include "stdafx.h"
#include "NormalBtn.h"
#include "Public.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CNormalBtn::CNormalBtn()
:m_bTracking(FALSE)
{
}
CNormalBtn::~CNormalBtn()
{
}
BEGIN_MESSAGE_MAP(CNormalBtn, CBaseBtn)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover)
END_MESSAGE_MAP()
void CNormalBtn::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE|TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
}
CBaseBtn::OnMouseMove(nFlags, point);
}
LRESULT CNormalBtn::OnMouseHover(WPARAM wParam,LPARAM lParam)
{
if (m_nCtrlState == CTRL_NOFOCUS)
{
m_nCtrlState = CTRL_FOCUS;
Invalidate();
}
m_bTracking = FALSE;
return 0;
}
LRESULT CNormalBtn::OnMouseLeave(WPARAM wParam,LPARAM lParam)
{
if(m_nCtrlState != CTRL_NOFOCUS)
{
m_nCtrlState = CTRL_NOFOCUS;
Invalidate();
}
m_bTracking = FALSE;
return 0;
}
void CNormalBtn::OnLButtonDown(UINT nFlags, CPoint point)
{
if(m_nCtrlState == CTRL_FOCUS)
{
m_nCtrlState = CTRL_SELECTED;
Invalidate();
}
CBaseBtn::OnLButtonDown(nFlags, point);
}
void CNormalBtn::OnLButtonUp(UINT nFlags, CPoint point)
{
if(m_nCtrlState == CTRL_SELECTED)
{
m_nCtrlState = CTRL_FOCUS;
Invalidate();
}
CBaseBtn::OnLButtonUp(nFlags, point);
}
第二类按钮(CMenu.h)
- #ifndef __MENUBTN_H__
- #define __MENUBTN_H__
- #include "BaseBtn.h"
- class CMenuBtn : public CBaseBtn
- {
- public:
- CMenuBtn();
- ~CMenuBtn();
- public:
- BOOL GetMenuOn() { return m_bMenuOn; }
- void SetMenuOn(BOOL bMenuOn);
- protected:
- afx_msg void OnMouseMove(UINT nFlags, CPoint point);
- afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
- afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
- afx_msg LRESULT OnMouseHover(WPARAM, LPARAM);
- DECLARE_MESSAGE_MAP()
- private:
- BOOL m_bTracking; // 捕获设置标记
- BOOL m_bMenuOn; // 该菜单按钮是否被选中
- };
- #endif
#ifndef __MENUBTN_H__
#define __MENUBTN_H__
#include "BaseBtn.h"
class CMenuBtn : public CBaseBtn
{
public:
CMenuBtn();
~CMenuBtn();
public:
BOOL GetMenuOn() { return m_bMenuOn; }
void SetMenuOn(BOOL bMenuOn);
protected:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM, LPARAM);
afx_msg LRESULT OnMouseHover(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
private:
BOOL m_bTracking; // 捕获设置标记
BOOL m_bMenuOn; // 该菜单按钮是否被选中
};
#endif
第二类按钮(CButton.cpp)
- #include "stdafx.h"
- #include "MenuBtn.h"
- #include "Public.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- CMenuBtn::CMenuBtn()
- :m_bTracking(FALSE)
- ,m_bMenuOn(FALSE)
- {
- }
- CMenuBtn::~CMenuBtn()
- {
- }
- BEGIN_MESSAGE_MAP(CMenuBtn, CBaseBtn)
- ON_WM_MOUSEMOVE()
- ON_WM_LBUTTONDOWN()
- ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
- ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover)
- END_MESSAGE_MAP()
- void CMenuBtn::OnMouseMove(UINT nFlags, CPoint point)
- {
- if (!m_bTracking)
- {
- 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 CMenuBtn::OnLButtonDown(UINT nFlags, CPoint point)
- {
- if(m_nCtrlState != CTRL_SELECTED)
- {
- m_nCtrlState = CTRL_SELECTED;
- m_bMenuOn = TRUE;
- Invalidate();
- }
- CButton::OnLButtonDown(nFlags, point);
- }
- LRESULT CMenuBtn::OnMouseLeave(WPARAM wParam,LPARAM lParam)
- {
- if(m_bMenuOn)
- {
- m_nCtrlState = CTRL_SELECTED;
- Invalidate();
- }
- else
- {
- m_nCtrlState = CTRL_NOFOCUS;
- Invalidate();
- }
- m_bTracking = FALSE;
- return 0;
- }
- LRESULT CMenuBtn::OnMouseHover(WPARAM wParam,LPARAM lParam)
- {
- if (m_nCtrlState != CTRL_FOCUS)
- {
- m_nCtrlState = CTRL_FOCUS;
- Invalidate();
- }
- m_bTracking = FALSE;
- return 0;
- }
- void CMenuBtn::SetMenuOn(BOOL bMenuOn)
- {
- m_bMenuOn = bMenuOn;
- Invalidate();
- }
#include "stdafx.h"
#include "MenuBtn.h"
#include "Public.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CMenuBtn::CMenuBtn()
:m_bTracking(FALSE)
,m_bMenuOn(FALSE)
{
}
CMenuBtn::~CMenuBtn()
{
}
BEGIN_MESSAGE_MAP(CMenuBtn, CBaseBtn)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER,OnMouseHover)
END_MESSAGE_MAP()
void CMenuBtn::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
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 CMenuBtn::OnLButtonDown(UINT nFlags, CPoint point)
{
if(m_nCtrlState != CTRL_SELECTED)
{
m_nCtrlState = CTRL_SELECTED;
m_bMenuOn = TRUE;
Invalidate();
}
CButton::OnLButtonDown(nFlags, point);
}
LRESULT CMenuBtn::OnMouseLeave(WPARAM wParam,LPARAM lParam)
{
if(m_bMenuOn)
{
m_nCtrlState = CTRL_SELECTED;
Invalidate();
}
else
{
m_nCtrlState = CTRL_NOFOCUS;
Invalidate();
}
m_bTracking = FALSE;
return 0;
}
LRESULT CMenuBtn::OnMouseHover(WPARAM wParam,LPARAM lParam)
{
if (m_nCtrlState != CTRL_FOCUS)
{
m_nCtrlState = CTRL_FOCUS;
Invalidate();
}
m_bTracking = FALSE;
return 0;
}
void CMenuBtn::SetMenuOn(BOOL bMenuOn)
{
m_bMenuOn = bMenuOn;
Invalidate();
}
第三类按钮(CStaticBtn.h)
- #ifndef __STATICBTN_H__
- #define __STATICBTN_H__
- #include "BaseBtn.h"
- class CStaticBtn : public CBaseBtn
- {
- public:
- CStaticBtn();
- ~CStaticBtn();
- public:
- virtual void Init(UINT uImageID);
- virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
- };
- #endif
#ifndef __STATICBTN_H__
#define __STATICBTN_H__
#include "BaseBtn.h"
class CStaticBtn : public CBaseBtn
{
public:
CStaticBtn();
~CStaticBtn();
public:
virtual void Init(UINT uImageID);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
};
#endif
第三类按钮(CStaticBtn.cpp)
- #include "stdafx.h"
- #include "StaticBtn.h"
- #include "Public.h"
- CStaticBtn::CStaticBtn()
- {
- }
- CStaticBtn::~CStaticBtn()
- {
- }
- void CStaticBtn::Init(UINT uImageID)
- {
- SetButtonStyle(BS_OWNERDRAW);
- LoadPicture(m_Image, uImageID);
- m_nSrcWidth = m_Image.GetWidth();
- m_nSrcHeight = m_Image.GetHeight();
- SetWindowPos(NULL, 0, 0, m_nSrcWidth, m_nSrcHeight, SWP_NOMOVE|SWP_NOACTIVATE);
- }
- void CStaticBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- if (m_Image.IsNull())
- return;
- CRect rcBtutton;
- GetClientRect(rcBtutton);
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- CRect rcSrc = CRect(0, 0, m_nSrcWidth, m_nSrcHeight);
- m_Image.Draw(pDC->m_hDC, rcBtutton, rcSrc);
- }
#include "stdafx.h"
#include "StaticBtn.h"
#include "Public.h"
CStaticBtn::CStaticBtn()
{
}
CStaticBtn::~CStaticBtn()
{
}
void CStaticBtn::Init(UINT uImageID)
{
SetButtonStyle(BS_OWNERDRAW);
LoadPicture(m_Image, uImageID);
m_nSrcWidth = m_Image.GetWidth();
m_nSrcHeight = m_Image.GetHeight();
SetWindowPos(NULL, 0, 0, m_nSrcWidth, m_nSrcHeight, SWP_NOMOVE|SWP_NOACTIVATE);
}
void CStaticBtn::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (m_Image.IsNull())
return;
CRect rcBtutton;
GetClientRect(rcBtutton);
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rcSrc = CRect(0, 0, m_nSrcWidth, m_nSrcHeight);
m_Image.Draw(pDC->m_hDC, rcBtutton, rcSrc);
}
使用方法:
CNoraml m_NorBtn;
m_NorBtn.Init(UNIT);
因为NormalBtn和MenuBtn需要相应鼠标事件,有图片切换,为了更好的图片切换效果使用双缓冲绘图。双缓冲绘图需要先创建一张画布(CBaseBtn::DrawItem()函数)
- CBitmap memBitmap;
- memBitmap.CreateCompatibleBitmap(pDC, buttonRect.Width(), buttonRect.Height());
- dcMem.SelectObject(memBitmap);
- dcMem.FillSolidRect(buttonRect, RGB(255,0,255)); //设置画布颜色
CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap(pDC, buttonRect.Width(), buttonRect.Height());
dcMem.SelectObject(memBitmap);
dcMem.FillSolidRect(buttonRect, RGB(255,0,255)); //设置画布颜色
所以虽然用了虽然PNG图片有透明属性,但是画布无法设置透明属性,最后的结果是虽然PNG图片背景透明了,因为画布的存在,无法做出一个不规程的按钮出来。
而StaticBtn使用的是单缓冲,没有画布的存在,利用PNG图片的透明属性,可以做出一个不规则的按钮。但是单缓冲绘图对于图片的切换效果不好,所以只用来做一个不响应鼠标消息的静态按钮。未来有空我将会写《MFC 之 CButton 控件重绘(GDI+篇)》利用GDI+绘图来解决这个问题。
完整的项目工程下载地址:http://download.youkuaiyun.com/detail/yuzhenxiong0823/7167827
- <pre class="cpp" name="code" snippet_file_name="blog_20140409_9_2739585" code_snippet_id="283280"><pre snippet_file_name="blog_20140409_9_2739585" code_snippet_id="283280"></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <pre></pre>
- <div style="padding-top: 20px;">
- <p style="font-size: 12px;">版权声明:本文为博主原创文章,未经博主允许不得转载。</p>
- </div>
- </pre>
<div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><strong>[cpp]</strong> <a target=_blank title="view plain" class="ViewSource" href="http://blog.youkuaiyun.com/yuzhenxiong0823/article/details/23278763#">view plain</a><a target=_blank title="copy" class="CopyToClipboard" href="http://blog.youkuaiyun.com/yuzhenxiong0823/article/details/23278763#">copy</a><a target=_blank title="print" class="PrintSource" href="http://blog.youkuaiyun.com/yuzhenxiong0823/article/details/23278763#">print</a><a target=_blank title="?" class="About" href="http://blog.youkuaiyun.com/yuzhenxiong0823/article/details/23278763#">?</a><a target=_blank title="在CODE上查看代码片" style="text-indent: 0px;" href="https://code.youkuaiyun.com/snippets/283280" target="_blank"><img width="12" height="12" style="left: 2px; top: 1px; position: relative;" alt="在CODE上查看代码片" src="https://code.youkuaiyun.com/assets/CODE_ico.png" /></a><a target=_blank title="派生到我的代码片" style="text-indent: 0px;" href="https://code.youkuaiyun.com/snippets/283280/fork" target="_blank"><img width="12" height="12" style="left: 2px; top: 2px; position: relative;" alt="派生到我的代码片" src="https://code.youkuaiyun.com/assets/ico_fork.svg" /></a></div></div><ol class="dp-cpp"><li class="alt"><span><span><pre snippet_file_name=</span><span class="string">"blog_20140409_9_2739585"</span><span> code_snippet_id=</span><span class="string">"283280"</span><span>></pre> </span></span></li><li><span><pre></pre> </span></li><li class="alt"><span><pre></pre> </span></li><li><span><pre></pre> </span></li><li class="alt"><span><pre></pre> </span></li><li><span> </span></li><li class="alt"><span> <div style=<span class="string">"padding-top: 20px;"</span><span>> </span></span></li><li><span> <p style=<span class="string">"font-size: 12px;"</span><span>>版权声明:本文为博主原创文章,未经博主允许不得转载。</p> </span></span></li><li class="alt"><span> </div> </span></li></ol></div><pre class="cpp" style="display: none;" name="code" code_snippet_id="283280" snippet_file_name="blog_20140409_9_2739585"><pre code_snippet_id="283280" snippet_file_name="blog_20140409_9_2739585">
版权声明:本文为博主原创文章,未经博主允许不得转载。