直接将类加入项目工程,并在对话框类中增加
CImage m_bkImage;//背景图片
// 给按钮绑定控件变量,修改类型为CButtonTranslucent
CButtonTranslucent/*CButton*/ m_btTest3;
OnInitDialog()中设置图片:
m_bkImage.Load("bkBitmap.bmp"); // bkBitmap.bmp是背景图片
加载图片,或者使用
m_bkImage.LoadFromResource(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP_BK));
加载图片
m_btTest3.SetImage(m_bkImage);// 绑定图片 m_btTest3按钮绑定的控件变量
MFC半透明按钮类
#pragma once
// CButtonBmp
class CButtonTranslucent : public CButton
{
DECLARE_DYNAMIC(CButtonTranslucent)
public:
CButtonTranslucent();
virtual ~CButtonTranslucent();
protected:
DECLARE_MESSAGE_MAP()
virtual void PreSubclassWindow();
public:
void SetBkColor(COLORREF color);
void SetTextColor(COLORREF color);
// add byzt
// 图片路径
void SetImage(const CString& szFilePath);
// 生命周期与对话框相同的图片
void SetImage(const CImage& image);
private:
COLORREF m_bkColor;
COLORREF m_textColor;
BOOL m_bTrack;
BOOL m_bOver;
BOOL m_bDown;
BOOL m_bDisable;
// add byzt
CImage m_bkImage;
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
};
// ButtonBmp.cpp : 实现文件
//
#include "stdafx.h"
#include "ButtonDemo.h"
#include "ButtonTranslucent.h"
#include "ButtonDemoDlg.h"
// CButtonBmp
IMPLEMENT_DYNAMIC(CButtonTranslucent, CButton)
CButtonTranslucent::CButtonTranslucent()
: m_bkColor(0)
, m_textColor(0)
, m_bTrack(FALSE)
, m_bOver(FALSE)
, m_bDown(FALSE)
, m_bDisable(FALSE)
{
}
CButtonTranslucent::~CButtonTranslucent()
{
}
BEGIN_MESSAGE_MAP(CButtonTranslucent, CButton)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
// CButtonBmp 消息处理程序
void CButtonTranslucent::PreSubclassWindow()
{
// TODO: 在此添加专用代码和/或调用基类
m_bTrack = FALSE;
m_bOver = m_bDown = m_bDisable = FALSE;
m_bDisable = IsWindowEnabled() ? FALSE : TRUE;
ModifyStyle(NULL,BS_OWNERDRAW);
CButton::PreSubclassWindow();
}
void CButtonTranslucent::SetBkColor(COLORREF color)
{
m_bkColor = color;
}
void CButtonTranslucent::SetTextColor(COLORREF color)
{
m_textColor = color;
}
void CButtonTranslucent::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (!m_bTrack)
{
// m_bOver = TRUE;
TRACKMOUSEEVENT tme;
tme.cbSize=sizeof(TRACKMOUSEEVENT);
tme.dwFlags=TME_HOVER | TME_LEAVE;
tme.dwHoverTime=HOVER_DEFAULT;
tme.hwndTrack=m_hWnd;
m_bTrack=_TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
}
void CButtonTranslucent::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_bDown = TRUE;
CButton::OnLButtonDown(nFlags, point);
}
void CButtonTranslucent::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_bDown = FALSE;
CButton::OnLButtonUp(nFlags, point);
}
BOOL CButtonTranslucent::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if (WM_MOUSELEAVE == pMsg->message)
{
m_bOver = FALSE;
m_bTrack = FALSE;
InvalidateRect(NULL, FALSE);
} else if (WM_MOUSEHOVER == pMsg->message)
{
m_bOver = TRUE;
InvalidateRect(NULL);
}
return CButton::PreTranslateMessage(pMsg);
}
void CButtonTranslucent::DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/)
{
// TODO: 添加您的代码以绘制指定项
HDC hDestDC=::GetDC(m_hWnd);
CRect rc;
GetClientRect(rc);
int nWindth=rc.Width();
int nHeight=rc.Height();
HDC hDC=CreateCompatibleDC(hDestDC);//创建兼容DC,采用双缓冲画出
HDC hMaskDC=CreateCompatibleDC(hDestDC);
HBITMAP hBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);
HBITMAP hMaskBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);
HBITMAP hOldBitmap=(HBITMAP)SelectObject(hDC,hBitmap);
HBITMAP hOldMaskBitmap=(HBITMAP)SelectObject(hMaskDC,hMaskBitmap);
SetBkMode(hDC,TRANSPARENT);
//把父窗口的背景图复制到按钮的DC上,实现视觉透明----------------
// CMainDlg* pParent=(CMainDlg*)GetParent();
// CPoint pt(0,0);
// MapWindowPoints(pParent,&pt,1);
// pParent->m_bkImage.BitBlt(hDC,rc,pt,SRCCOPY);
// Modify BYZT
CDialog* pParent=(CDialog*)GetParent();
CPoint pt(0,0);
MapWindowPoints(pParent,&pt,1);
m_bkImage.BitBlt(hDC,rc,pt,SRCCOPY);
//-------------------------------------------------------------
int nAlpha=100;//0--255
int nOffset=0;
HBRUSH hbr=CreateSolidBrush(m_bkColor);
FillRect(hMaskDC,&rc,hbr);
DeleteObject(hbr);
if(m_bDisable)
{
nAlpha=100;
}
else if(m_bDown)
{
nAlpha=180;
nOffset=1;
}
else if(m_bOver)
{
nAlpha=150;
}
else
{
nAlpha=100;
}
BLENDFUNCTION blend;
memset( &blend, 0, sizeof( blend) );
blend.BlendOp= AC_SRC_OVER;
blend.SourceConstantAlpha= nAlpha; // 透明度 最大255
HRGN hRgn=CreateRoundRectRgn(0,0,nWindth,nHeight,3,3);
SelectClipRgn (hDC,hRgn);
AlphaBlend (hDC,0,0,nWindth,nHeight,hMaskDC, 0,0,nWindth,nHeight,blend);
CString strText;
GetWindowText(strText);
if(strText!=_T(""))
{
rc.InflateRect(-2,-2);
rc.OffsetRect(nOffset,nOffset);
HFONT hFont=(HFONT)SendMessage(WM_GETFONT);
if(!hFont)hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);
HFONT hOldFont=(HFONT)SelectObject(hDC,hFont);
::SetTextColor(hDC,m_textColor);
::DrawText(hDC,strText,-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_WORD_ELLIPSIS);
::SelectObject(hDC,hOldFont);
}
SelectClipRgn (hDC,NULL);
DeleteObject(hRgn);
//复制到控件的DC上------------------------
BitBlt(hDestDC,0,0,nWindth,nHeight,hDC,0,0,SRCCOPY);
//删除资源,释放内存-----------------------
SelectObject(hDC,hOldBitmap);
DeleteObject(hBitmap);
DeleteDC(hDC);
SelectObject(hMaskDC,hOldMaskBitmap);
DeleteObject(hMaskBitmap);
DeleteDC(hMaskDC);
}
void CButtonTranslucent::SetImage(const CString& szFilePath)
{
m_bkImage.Load(szFilePath);
}
void CButtonTranslucent::SetImage(const CImage& image)
{
m_bkImage = image;
return;
if (!m_bkImage.IsNull())
{
m_bkImage.Destroy();
}
m_bkImage.Create(image.GetWidth(), image.GetHeight(), image.GetBPP());
image.BitBlt(m_bkImage.GetDC(), 0, 0);
}
效果图如下
因没有使用双缓冲技术,所以按钮图片有闪烁。