一个位图按钮类,实现了按下、放开和鼠标在按钮上的图片更换。
/
// 工程: YF_GCM -> ButtonDemo
// 作者: **
// 描述: 自绘制位图按钮
// 主要函数:
// SetButtonUpBitmapEx()设置鼠标放置在按钮上的图片
// SetButtonDownBitmapEx()设置按钮按下的图片
// SetButtonNormalBitmapEx()设置鼠标不在按钮是的图片
// 日期: 2013.12.16
// 版本: 1.0
// 修改:
/
// BitmapButtonEx.cpp : 实现文件
//
#include "stdafx.h"
#include "resource.h"
#include "BitmapButtonEx.h"
// CBitmapButtonEx
IMPLEMENT_DYNAMIC(CBitmapButtonEx, CBitmapButton)
CBitmapButtonEx::CBitmapButtonEx()
: m_hUpBitmap(NULL)
, m_hDownBitmap(NULL)
, m_hNormalBitmap(NULL)
, m_lButtonDown(FALSE)
, m_bMouseOver(FALSE)
, m_bTrack(FALSE)
{
m_rgn.CreateRectRgn(0,0,0,0);
}
CBitmapButtonEx::~CBitmapButtonEx()
{
if (NULL != m_hUpBitmap)
{
::DeleteObject(m_hUpBitmap);
}
if (NULL != m_hDownBitmap)
{
::DeleteObject(m_hDownBitmap);
}
if (NULL != m_hNormalBitmap)
{
::DeleteObject(m_hDownBitmap);
}
}
BEGIN_MESSAGE_MAP(CBitmapButtonEx, CBitmapButton)
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
// CBitmapButtonEx 消息处理程序
BOOL CBitmapButtonEx::SetButtonUpBitmapEx(const CString& szFilePath)
{
if (NULL != m_hUpBitmap)
{
::DeleteObject(m_hUpBitmap);
m_hUpBitmap = NULL;
}
m_hUpBitmap = (HBITMAP)LoadImage(NULL, szFilePath, IMAGE_BITMAP, 0,0, LR_LOADFROMFILE); // 载入
return NULL != m_hUpBitmap;
}
BOOL CBitmapButtonEx::SetButtonUpBitmapEx(HBITMAP hBitmap)
{
m_hUpBitmap = hBitmap;
return NULL != m_hUpBitmap;
}
BOOL CBitmapButtonEx::SetButtonNormalBitmapEx(HBITMAP hBitmap)
{
m_hNormalBitmap = hBitmap;
return NULL != m_hNormalBitmap;
}
BOOL CBitmapButtonEx::SetButtonNormalBitmapEx(const CString& szFilePath)
{
if (NULL != m_hNormalBitmap)
{
::DeleteObject(m_hNormalBitmap);
m_hNormalBitmap = NULL;
}
m_hNormalBitmap = (HBITMAP)LoadImage(NULL, szFilePath, IMAGE_BITMAP, 0,0, LR_LOADFROMFILE); // 载入
return NULL != m_hNormalBitmap;
}
BOOL CBitmapButtonEx::SetButtonDownBitmapEx(const CString& szFilePath)
{
if (NULL != m_hDownBitmap)
{
::DeleteObject(m_hDownBitmap);
m_hDownBitmap = NULL;
}
m_hDownBitmap = (HBITMAP)LoadImage(NULL, szFilePath, IMAGE_BITMAP, 0,0, LR_LOADFROMFILE); // 载入
return NULL != m_hDownBitmap;
}
BOOL CBitmapButtonEx::SetButtonDownBitmapEx(HBITMAP hBitmap)
{
m_hDownBitmap = hBitmap;
return NULL != m_hDownBitmap;
}
void CBitmapButtonEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: 添加您的代码以绘制指定项
CRect rect = lpDrawItemStruct->rcItem;
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
//
CBitmap hbmp;
if (m_lButtonDown)
{
hbmp.Attach(m_hDownBitmap);
}
else
{
if (m_bMouseOver)
{
hbmp.Attach(m_hUpBitmap);
}
else
{
hbmp.Attach(m_hNormalBitmap);
}
}
BITMAP bm;
hbmp.GetBitmap(&bm);
CDC* thisdc = NULL;
thisdc = GetDC();
CDC dcMem;
dcMem.CreateCompatibleDC(thisdc);
CBitmap *poldBitmap=(CBitmap*)dcMem.SelectObject(hbmp);
//显示位图
thisdc->SelectClipRgn(&m_rgn); //改变pDC的裁减区域
dcMem.SelectClipRgn(&m_rgn);
// 无缩放
// GetDC()->BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcMem, 0, 0, SRCCOPY);
// 缩放
thisdc->StretchBlt(rect.left ,rect.top , rect.Width(), rect.Height(),
&dcMem,0 ,0, bm.bmWidth, bm.bmHeight, SRCCOPY);
dcMem.SelectObject(&poldBitmap);
this->ReleaseDC(thisdc);
hbmp.Detach();
}
void CBitmapButtonEx::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
ModifyStyle(0, BS_OWNERDRAW); //设置按钮的有效区域
CRgn rgn;
CRect rc;
GetClientRect(&rc); //有效区域为一个角半径为5的圆角矩形
m_rgn.DeleteObject();
m_rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom, 5, 5);
rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom, 5, 5);
rgn.CopyRgn(&m_rgn);
SetWindowRgn(rgn, TRUE);
rgn.DeleteObject();
// CRgn rgn;
// CRect rc;
// GetClientRect(&rc); //有效区域为一个角半径为5的圆角矩形
//
// rgn.CreateRoundRectRgn(rc.left,rc.top,rc.right,rc.bottom, 5, 5);
// SetWindowRgn(rgn,TRUE);
// rgn.DeleteObject();
//
CBitmapButton::PreSubclassWindow();
}
void CBitmapButtonEx::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_lButtonDown = TRUE;
InvalidateRect(NULL);
CBitmapButton::OnLButtonDown(nFlags, point);
}
void CBitmapButtonEx::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_lButtonDown = FALSE;
InvalidateRect(NULL);
CBitmapButton::OnLButtonUp(nFlags, point);
}
BOOL CBitmapButtonEx::SetButtonRgn(const CRgn& rgn)
{
m_rgn.CopyRgn(&m_rgn);
return 0;
}
BOOL CBitmapButtonEx::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if(pMsg->message==WM_MOUSELEAVE)
{
m_bTrack=FALSE;
m_bMouseOver = FALSE;
InvalidateRect(NULL);
}
else if (pMsg->message==WM_MOUSEHOVER)
{
m_bMouseOver = TRUE;
InvalidateRect(NULL);
}
return CBitmapButton::PreTranslateMessage(pMsg);
}
void CBitmapButtonEx::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if(!m_bTrack)
{
TRACKMOUSEEVENT tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=TME_HOVER | TME_LEAVE;
tme.dwHoverTime=HOVER_DEFAULT;
tme.hwndTrack=m_hWnd;
m_bTrack=_TrackMouseEvent(&tme);
}
CBitmapButton::OnMouseMove(nFlags, point);
}
#pragma once
#include "afxwin.h"
/
// 工程: YF_GCM -> ButtonDemo
// 作者: **
// 描述: 自绘制位图按钮
// 主要函数:
// SetButtonUpBitmapEx()设置鼠标放置在按钮上的图片
// SetButtonDownBitmapEx()设置按钮按下的图片
// SetButtonNormalBitmapEx()设置鼠标不在按钮是的图片
// 日期: 2013.12.16
// 版本: 1.0
// 修改:
/
// CBitmapButtonEx
class CBitmapButtonEx : public CBitmapButton
{
DECLARE_DYNAMIC(CBitmapButtonEx)
public:
CBitmapButtonEx();
virtual ~CBitmapButtonEx();
protected:
DECLARE_MESSAGE_MAP()
protected:
// // all bitmaps must be the same size
// CBitmap m_bitmap; // normal image (REQUIRED)
// CBitmap m_bitmapSel; // selected image (OPTIONAL)
// CBitmap m_bitmapFocus; // focused but not selected (OPTIONAL)
// CBitmap m_bitmapDisabled; // disabled bitmap (OPTIONAL)
//
// virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
public:
// 设置按钮抬起图片
BOOL SetButtonUpBitmapEx(const CString& szFilePath);
BOOL SetButtonUpBitmapEx(HBITMAP hBitmap);
// 设置按钮按下图片
BOOL SetButtonDownBitmapEx(const CString& szFilePath);
BOOL SetButtonDownBitmapEx(HBITMAP hBitmap);
// 普通按钮图片
BOOL SetButtonNormalBitmapEx(const CString& szFilePath);
BOOL SetButtonNormalBitmapEx(HBITMAP hBitmap);
protected:
virtual void PreSubclassWindow();
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
protected:
BOOL m_lButtonDown;
// 按钮有效区域
CRgn m_rgn;
private:
// 图片
HBITMAP m_hUpBitmap;
HBITMAP m_hDownBitmap;
HBITMAP m_hNormalBitmap;
public:
BOOL SetButtonRgn(const CRgn & rgn);
virtual BOOL PreTranslateMessage(MSG* pMsg);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
protected:
BOOL m_bMouseOver;
BOOL m_bTrack;
};
效果图显示如图中in的按钮