自绘实现半透明水晶按钮

运行效果

实现方法

1.给按钮加上BS_OWNERDRAW样式
2.重载DrawItem函数,在这里绘制按钮
3.关键之处就是把父窗口的背景复制到按钮上,实现视觉上的透明
4.最后通过AlphaBlend实现半透明.

实现源码

// MyButton.h
#pragma once


// CMyButton

class CMyButton : public CButton
{
	DECLARE_DYNAMIC(CMyButton)

public:
	CMyButton();
	virtual ~CMyButton();
public:
	void SetBkColor(COLORREF color);
	void SetTextColor(COLORREF color);
private:
	bool m_bOver;
	bool m_bDown;
	bool m_bDisable;
	bool m_bTracking;
	COLORREF m_bkColor;
	COLORREF m_textColor;
protected:
	DECLARE_MESSAGE_MAP()
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	virtual void PreSubclassWindow();
public:
	virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);
	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 wParam, LPARAM lParam);
	afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
	afx_msg void OnEnable(BOOL bEnable);
private:
	void ButtonInit();
	void DrawButton();
	void DrawButton(HDC hDestDC);
};

// MyButton.cpp : 实现文件
//

#include "stdafx.h"
#include "AlphaButton.h"
#include "MyButton.h"
#include "MainDlg.h"

// CMyButton

IMPLEMENT_DYNAMIC(CMyButton, CButton)

CMyButton::CMyButton()
{
	m_bkColor=0xFFFFFF;
	m_textColor=0x000000;
}

CMyButton::~CMyButton()
{
}


BEGIN_MESSAGE_MAP(CMyButton, CButton)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
	ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
	ON_WM_ENABLE()
END_MESSAGE_MAP()



// CMyButton 消息处理程序

void CMyButton::SetBkColor(COLORREF color)
{
	m_bkColor=color;
}
void CMyButton::SetTextColor(COLORREF color)
{
	m_textColor=color;
}

BOOL CMyButton::PreCreateWindow(CREATESTRUCT& cs)
{
	BOOL bRet=CButton::PreCreateWindow(cs);
	ButtonInit();
	return bRet;
}

void CMyButton::PreSubclassWindow()
{
	CButton::PreSubclassWindow();
	ButtonInit();
}
void CMyButton::ButtonInit()
{
	m_bTracking=false;
	m_bOver=m_bDown=m_bDisable=false;
	m_bDisable=IsWindowEnabled()?FALSE:TRUE;
	ModifyStyle(NULL,BS_OWNERDRAW);
}

void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{

	DrawButton(lpDrawItemStruct->hDC);
}

void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
	if (!m_bTracking)
	{
		m_bOver = TRUE;
		TRACKMOUSEEVENT tme;
		tme.cbSize = sizeof(tme);
		tme.hwndTrack = m_hWnd;
		tme.dwFlags = TME_LEAVE | TME_HOVER;
		tme.dwHoverTime = 50;
		m_bTracking = (bool)_TrackMouseEvent(&tme);
	}

	CButton::OnMouseMove(nFlags, point);
}

void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
	m_bDown=TRUE;

	CButton::OnLButtonDown(nFlags, point);
}

void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
	m_bDown=FALSE;
	CButton::OnLButtonUp(nFlags, point);
}
LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
	m_bOver = FALSE;
	m_bTracking = FALSE;
	m_bDown=FALSE;
	InvalidateRect(NULL, FALSE);
	return 0;
}

LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
	m_bOver = TRUE;
	InvalidateRect(NULL);
	return 0;
}
void CMyButton::DrawButton()
{
	HDC hDC=::GetDC(m_hWnd);
	DrawButton(hDC);
	::ReleaseDC(m_hWnd,hDC);
}
void CMyButton::DrawButton(HDC hDestDC)
{
	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);


	//-------------------------------------------------------------
	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 CMyButton::OnEnable(BOOL bEnable)
{
	CButton::OnEnable(bEnable);
	m_bDisable=IsWindowEnabled()?FALSE:TRUE;
	DrawButton();
}

源码下载:http://download.csdn.net/detail/cometnet/4955726

相关文章:自绘按钮实现颜色选择器

自绘实现半透明水晶按钮 -- 源码分享

01-04

[b]运行效果[/b]rn[img=http://img.my.csdn.net/uploads/201301/04/1357283576_1500.png][/img]rnrn[b]实现方法[/b]rn1.给按钮加上BS_OWNERDRAW样式rn2.重载DrawItem函数,在这里绘制按钮rn3.关键之处就是把父窗口的背景复制到按钮上,实现视觉上的透明rn4.最后通过AlphaBlend实现半透明.rnrn[b]源码下载:[/b]rn[url=http://blog.csdn.net/cometnet/article/details/8464693]http://blog.csdn.net/cometnet/article/details/8464693[/url]rnrn实现源码rn[code=c]// MyButton.hrn#pragma oncernrnrn// CMyButtonrnrnclass CMyButton : public CButtonrnrn DECLARE_DYNAMIC(CMyButton)rnrnpublic:rn CMyButton();rn virtual ~CMyButton();rnpublic:rn void SetBkColor(COLORREF color);rn void SetTextColor(COLORREF color);rnprivate:rn bool m_bOver;rn bool m_bDown;rn bool m_bDisable;rn bool m_bTracking;rn COLORREF m_bkColor;rn COLORREF m_textColor;rnprotected:rn DECLARE_MESSAGE_MAP()rn virtual BOOL PreCreateWindow(CREATESTRUCT& cs);rn virtual void PreSubclassWindow();rnpublic:rn virtual void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/);rn afx_msg void OnMouseMove(UINT nFlags, CPoint point);rn afx_msg void OnLButtonDown(UINT nFlags, CPoint point);rn afx_msg void OnLButtonUp(UINT nFlags, CPoint point);rn afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);rn afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);rn afx_msg void OnEnable(BOOL bEnable);rnprivate:rn void ButtonInit();rn void DrawButton();rn void DrawButton(HDC hDestDC);rn;rn[/code]rn[code=c]// MyButton.cpp : 实现文件rn//rnrn#include "stdafx.h"rn#include "AlphaButton.h"rn#include "MyButton.h"rn#include "MainDlg.h"rnrn// CMyButtonrnrnIMPLEMENT_DYNAMIC(CMyButton, CButton)rnrnCMyButton::CMyButton()rnrn m_bkColor=0xFFFFFF;rn m_textColor=0x000000;rnrnrnCMyButton::~CMyButton()rnrnrnrnrnBEGIN_MESSAGE_MAP(CMyButton, CButton)rn ON_WM_MOUSEMOVE()rn ON_WM_LBUTTONDOWN()rn ON_WM_LBUTTONUP()rn ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)rn ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)rn ON_WM_ENABLE()rnEND_MESSAGE_MAP()rnrnrnrn// CMyButton 消息处理程序rnrnvoid CMyButton::SetBkColor(COLORREF color)rnrn m_bkColor=color;rnrnvoid CMyButton::SetTextColor(COLORREF color)rnrn m_textColor=color;rnrnrnBOOL CMyButton::PreCreateWindow(CREATESTRUCT& cs)rnrn BOOL bRet=CButton::PreCreateWindow(cs);rn ButtonInit();rn return bRet;rnrnrnvoid CMyButton::PreSubclassWindow()rnrn CButton::PreSubclassWindow();rn ButtonInit();rnrnvoid CMyButton::ButtonInit()rnrn m_bTracking=false;rn m_bOver=m_bDown=m_bDisable=false;rn m_bDisable=IsWindowEnabled()?FALSE:TRUE;rn ModifyStyle(NULL,BS_OWNERDRAW);rnrnrnvoid CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)rnrnrn DrawButton(lpDrawItemStruct->hDC);rnrnrnvoid CMyButton::OnMouseMove(UINT nFlags, CPoint point)rnrn if (!m_bTracking)rn rn m_bOver = TRUE;rn TRACKMOUSEEVENT tme;rn tme.cbSize = sizeof(tme);rn tme.hwndTrack = m_hWnd;rn tme.dwFlags = TME_LEAVE | TME_HOVER;rn tme.dwHoverTime = 50;rn m_bTracking = (bool)_TrackMouseEvent(&tme);rn rnrn CButton::OnMouseMove(nFlags, point);rnrnrnvoid CMyButton::OnLButtonDown(UINT nFlags, CPoint point)rnrn m_bDown=TRUE;rnrn CButton::OnLButtonDown(nFlags, point);rnrnrnvoid CMyButton::OnLButtonUp(UINT nFlags, CPoint point)rnrn m_bDown=FALSE;rn CButton::OnLButtonUp(nFlags, point);rnrnLRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)rnrn m_bOver = FALSE;rn m_bTracking = FALSE;rn m_bDown=FALSE;rn InvalidateRect(NULL, FALSE);rn return 0;rnrnrnLRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)rnrn m_bOver = TRUE;rn InvalidateRect(NULL);rn return 0;rnrnvoid CMyButton::DrawButton()rnrn HDC hDC=::GetDC(m_hWnd);rn DrawButton(hDC);rn ::ReleaseDC(m_hWnd,hDC);rnrnvoid CMyButton::DrawButton(HDC hDestDC)rnrn CRect rc;rn GetClientRect(rc);rn int nWindth=rc.Width();rn int nHeight=rc.Height();rn HDC hDC=CreateCompatibleDC(hDestDC);//创建兼容DC,采用双缓冲画出rn HDC hMaskDC=CreateCompatibleDC(hDestDC);rn HBITMAP hBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);rn HBITMAP hMaskBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);rn HBITMAP hOldBitmap=(HBITMAP)SelectObject(hDC,hBitmap);rn HBITMAP hOldMaskBitmap=(HBITMAP)SelectObject(hMaskDC,hMaskBitmap);rn SetBkMode(hDC,TRANSPARENT);rnrn //把父窗口的背景图复制到按钮的DC上,实现视觉透明----------------rn CMainDlg* pParent=(CMainDlg*)GetParent();rn CPoint pt(0,0);rn MapWindowPoints(pParent,&pt,1);rn pParent->m_bkImage.BitBlt(hDC,rc,pt,SRCCOPY);rnrnrn //-------------------------------------------------------------rn int nAlpha=100;//0--255rn int nOffset=0;rnrn HBRUSH hbr=CreateSolidBrush(m_bkColor);rn FillRect(hMaskDC,&rc,hbr);rn DeleteObject(hbr);rnrn if(m_bDisable)rn nAlpha=100;rn else if(m_bDown)rn nAlpha=180;rn nOffset=1;rn else if(m_bOver)rn nAlpha=150;rn elsern nAlpha=100;rn rn BLENDFUNCTION blend;rn memset( &blend, 0, sizeof( blend) );rn blend.BlendOp= AC_SRC_OVER;rn blend.SourceConstantAlpha= nAlpha; // 透明度 最大255rnrn HRGN hRgn=CreateRoundRectRgn(0,0,nWindth,nHeight,3,3);rn SelectClipRgn (hDC,hRgn);rn AlphaBlend (hDC,0,0,nWindth,nHeight,hMaskDC, 0,0,nWindth,nHeight,blend);rnrn CString strText;rn GetWindowText(strText);rn if(strText!=_T(""))rn rc.InflateRect(-2,-2);rn rc.OffsetRect(nOffset,nOffset);rn HFONT hFont=(HFONT)SendMessage(WM_GETFONT);rn if(!hFont)hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);rn HFONT hOldFont=(HFONT)SelectObject(hDC,hFont);rn ::SetTextColor(hDC,m_textColor);rn ::DrawText(hDC,strText,-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_WORD_ELLIPSIS);rn ::SelectObject(hDC,hOldFont);rn rn SelectClipRgn (hDC,NULL);rn DeleteObject(hRgn);rn //复制到控件的DC上------------------------rn BitBlt(hDestDC,0,0,nWindth,nHeight,hDC,0,0,SRCCOPY);rn //删除资源,释放内存-----------------------rn SelectObject(hDC,hOldBitmap);rn DeleteObject(hBitmap);rn DeleteDC(hDC);rn SelectObject(hMaskDC,hOldMaskBitmap);rn DeleteObject(hMaskBitmap);rn DeleteDC(hMaskDC);rnrnrnvoid CMyButton::OnEnable(BOOL bEnable)rnrn CButton::OnEnable(bEnable);rn m_bDisable=IsWindowEnabled()?FALSE:TRUE;rn DrawButton();rnrn[/code]rnrn[b]源码下载:[/b][url=http://blog.csdn.net/cometnet/article/details/8464693]http://blog.csdn.net/cometnet/article/details/8464693[/url]rn[b]相关文章:[/b][url=http://blog.csdn.net/cometnet/article/details/7293913]自绘按钮实现颜色选择器[/url] 论坛

没有更多推荐了,返回首页