天天看點

自繪實作半透明水晶按鈕 .運作效果實作方法實作源碼

運作效果

自繪實作半透明水晶按鈕 .運作效果實作方法實作源碼

實作方法

1.給按鈕加上BS_OWNERDRAW樣式

2.重載DrawItem函數,在這裡繪制按鈕

3.關鍵之處就是把父視窗的背景複制到按鈕上,實作視覺上的透明

4.最後通過AlphaBlend實作半透明.

實作源碼

[cpp] view plain copy print ?

  1. // MyButton.h   
  2. #pragma once   
  3. // CMyButton   
  4. class CMyButton : public CButton  
  5. {  
  6.     DECLARE_DYNAMIC(CMyButton)  
  7. public:  
  8.     CMyButton();  
  9.     virtual ~CMyButton();  
  10. public:  
  11.     void SetBkColor(COLORREF color);  
  12.     void SetTextColor(COLORREF color);  
  13. private:  
  14.     bool m_bOver;  
  15.     bool m_bDown;  
  16.     bool m_bDisable;  
  17.     bool m_bTracking;  
  18.     COLORREF m_bkColor;  
  19.     COLORREF m_textColor;  
  20. protected:  
  21.     DECLARE_MESSAGE_MAP()  
  22.     virtual BOOL PreCreateWindow(CREATESTRUCT& cs);  
  23.     virtual void PreSubclassWindow();  
  24. public:  
  25.     virtual void DrawItem(LPDRAWITEMSTRUCT );  
  26.     afx_msg void OnMouseMove(UINT nFlags, CPoint point);  
  27.     afx_msg void OnLButtonDown(UINT nFlags, CPoint point);  
  28.     afx_msg void OnLButtonUp(UINT nFlags, CPoint point);  
  29.     afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);  
  30.     afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);  
  31.     afx_msg void OnEnable(BOOL bEnable);  
  32. private:  
  33.     void ButtonInit();  
  34.     void DrawButton();  
  35.     void DrawButton(HDC hDestDC);  
  36. };  
// 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);
};
           

[cpp] view plain copy print ?

  1. // MyButton.cpp : 實作檔案   
  2. //   
  3. #include "stdafx.h"   
  4. #include "AlphaButton.h"   
  5. #include "MyButton.h"   
  6. #include "MainDlg.h"   
  7. // CMyButton   
  8. IMPLEMENT_DYNAMIC(CMyButton, CButton)  
  9. CMyButton::CMyButton()  
  10. {  
  11.     m_bkColor=0xFFFFFF;  
  12.     m_textColor=0x000000;  
  13. }  
  14. CMyButton::~CMyButton()  
  15. {  
  16. }  
  17. BEGIN_MESSAGE_MAP(CMyButton, CButton)  
  18.     ON_WM_MOUSEMOVE()  
  19.     ON_WM_LBUTTONDOWN()  
  20.     ON_WM_LBUTTONUP()  
  21.     ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)  
  22.     ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)  
  23.     ON_WM_ENABLE()  
  24. END_MESSAGE_MAP()  
  25. // CMyButton 消息處理程式   
  26. void CMyButton::SetBkColor(COLORREF color)  
  27. {  
  28.     m_bkColor=color;  
  29. }  
  30. void CMyButton::SetTextColor(COLORREF color)  
  31. {  
  32.     m_textColor=color;  
  33. }  
  34. BOOL CMyButton::PreCreateWindow(CREATESTRUCT& cs)  
  35. {  
  36.     BOOL bRet=CButton::PreCreateWindow(cs);  
  37.     ButtonInit();  
  38.     return bRet;  
  39. }  
  40. void CMyButton::PreSubclassWindow()  
  41. {  
  42.     CButton::PreSubclassWindow();  
  43.     ButtonInit();  
  44. }  
  45. void CMyButton::ButtonInit()  
  46. {  
  47.     m_bTracking=false;  
  48.     m_bOver=m_bDown=m_bDisable=false;  
  49.     m_bDisable=IsWindowEnabled()?FALSE:TRUE;  
  50.     ModifyStyle(NULL,BS_OWNERDRAW);  
  51. }  
  52. void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)  
  53. {  
  54.     DrawButton(lpDrawItemStruct->hDC);  
  55. }  
  56. void CMyButton::OnMouseMove(UINT nFlags, CPoint point)  
  57. {  
  58.     if (!m_bTracking)  
  59.     {  
  60.         m_bOver = TRUE;  
  61.         TRACKMOUSEEVENT tme;  
  62.         tme.cbSize = sizeof(tme);  
  63.         tme.hwndTrack = m_hWnd;  
  64.         tme.dwFlags = TME_LEAVE | TME_HOVER;  
  65.         tme.dwHoverTime = 50;  
  66.         m_bTracking = (bool)_TrackMouseEvent(&tme);  
  67.     }  
  68.     CButton::OnMouseMove(nFlags, point);  
  69. }  
  70. void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)  
  71. {  
  72.     m_bDown=TRUE;  
  73.     CButton::OnLButtonDown(nFlags, point);  
  74. }  
  75. void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)  
  76. {  
  77.     m_bDown=FALSE;  
  78.     CButton::OnLButtonUp(nFlags, point);  
  79. }  
  80. LRESULT CMyButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)  
  81. {  
  82.     m_bOver = FALSE;  
  83.     m_bTracking = FALSE;  
  84.     m_bDown=FALSE;  
  85.     InvalidateRect(NULL, FALSE);  
  86.     return 0;  
  87. }  
  88. LRESULT CMyButton::OnMouseHover(WPARAM wParam, LPARAM lParam)  
  89. {  
  90.     m_bOver = TRUE;  
  91.     InvalidateRect(NULL);  
  92.     return 0;  
  93. }  
  94. void CMyButton::DrawButton()  
  95. {  
  96.     HDC hDC=::GetDC(m_hWnd);  
  97.     DrawButton(hDC);  
  98.     ::ReleaseDC(m_hWnd,hDC);  
  99. }  
  100. void CMyButton::DrawButton(HDC hDestDC)  
  101. {  
  102.     CRect rc;  
  103.     GetClientRect(rc);  
  104.     int nWindth=rc.Width();  
  105.     int nHeight=rc.Height();  
  106.     HDC hDC=CreateCompatibleDC(hDestDC);//建立相容DC,采用雙緩沖畫出   
  107.     HDC hMaskDC=CreateCompatibleDC(hDestDC);  
  108.     HBITMAP hBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);  
  109.     HBITMAP hMaskBitmap=CreateCompatibleBitmap(hDestDC,nWindth,nHeight);  
  110.     HBITMAP hOldBitmap=(HBITMAP)SelectObject(hDC,hBitmap);  
  111.     HBITMAP hOldMaskBitmap=(HBITMAP)SelectObject(hMaskDC,hMaskBitmap);  
  112.     SetBkMode(hDC,TRANSPARENT);  
  113.     //把父視窗的背景圖複制到按鈕的DC上,實作視覺透明----------------   
  114.     CMainDlg* pParent=(CMainDlg*)GetParent();  
  115.     CPoint pt(0,0);  
  116.     MapWindowPoints(pParent,&pt,1);  
  117.     pParent->m_bkImage.BitBlt(hDC,rc,pt,SRCCOPY);  
  118.     //-------------------------------------------------------------   
  119.     int nAlpha=100;//0--255   
  120.     int nOffset=0;  
  121.     HBRUSH hbr=CreateSolidBrush(m_bkColor);  
  122.     FillRect(hMaskDC,&rc,hbr);  
  123.     DeleteObject(hbr);  
  124.     if(m_bDisable){  
  125.         nAlpha=100;  
  126.     }else if(m_bDown){  
  127.         nAlpha=180;  
  128.         nOffset=1;  
  129.     }else if(m_bOver){  
  130.         nAlpha=150;  
  131.     }else{  
  132.         nAlpha=100;  
  133.     }  
  134.     BLENDFUNCTION blend;  
  135.     memset( &blend, 0, sizeof( blend) );  
  136.     blend.BlendOp= AC_SRC_OVER;  
  137.     blend.SourceConstantAlpha= nAlpha; // 透明度 最大255   
  138.     HRGN hRgn=CreateRoundRectRgn(0,0,nWindth,nHeight,3,3);  
  139.     SelectClipRgn (hDC,hRgn);  
  140.     AlphaBlend (hDC,0,0,nWindth,nHeight,hMaskDC, 0,0,nWindth,nHeight,blend);  
  141.     CString strText;  
  142.     GetWindowText(strText);  
  143.     if(strText!=_T("")){  
  144.         rc.InflateRect(-2,-2);  
  145.         rc.OffsetRect(nOffset,nOffset);  
  146.         HFONT hFont=(HFONT)SendMessage(WM_GETFONT);  
  147.         if(!hFont)hFont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);  
  148.         HFONT hOldFont=(HFONT)SelectObject(hDC,hFont);  
  149.         ::SetTextColor(hDC,m_textColor);  
  150.         ::DrawText(hDC,strText,-1,&rc,DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_WORD_ELLIPSIS);  
  151.         ::SelectObject(hDC,hOldFont);  
  152.     }  
  153.     SelectClipRgn (hDC,NULL);  
  154.     DeleteObject(hRgn);  
  155.     //複制到控件的DC上------------------------   
  156.     BitBlt(hDestDC,0,0,nWindth,nHeight,hDC,0,0,SRCCOPY);  
  157.     //删除資源,釋放記憶體-----------------------   
  158.     SelectObject(hDC,hOldBitmap);  
  159.     DeleteObject(hBitmap);  
  160.     DeleteDC(hDC);  
  161.     SelectObject(hMaskDC,hOldMaskBitmap);  
  162.     DeleteObject(hMaskBitmap);  
  163.     DeleteDC(hMaskDC);  
  164. }  
  165. void CMyButton::OnEnable(BOOL bEnable)  
  166. {  
  167.     CButton::OnEnable(bEnable);  
  168.     m_bDisable=IsWindowEnabled()?FALSE:TRUE;  
  169.     DrawButton();  
  170. }  
// 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