运行效果

实现方法

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

实现源码

  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 /*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. };
  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. }

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

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

http://blog.csdn.net/cometnet/article/details/8464693

http://blog.csdn.net/caichao1234/article/details/8466449

自绘实现半透明水晶按钮(继承CButton,设置BS_OWNERDRAW风格,覆盖DrawItem函数绘制按钮,把父窗口的背景复制到按钮上,实现视觉上的透明,最后通过AlphaBlend实现半透明)的更多相关文章

  1. Delphi自写组件:可设置颜色的按钮(改成BS_OWNERDRAW风格,然后CN_DRAWITEM)

    unit ColorButton; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, StdCtrls; ...

  2. 简单的自绘CListBox(多行显示)(覆盖DrawItem函数,然后用CDC绘制)

    之前写过一个自绘的CListBox类,详细请参考http://blog.csdn.net/VisualEleven/archive/2010/10/12/5935430.aspx现在修改这之前的代码, ...

  3. MFC 使用位图按钮,并且设置按钮的鼠标悬停效果

    系统环境:Windows 10软件环境:Visual C++ 2013 SP1本次目的:使用位图按钮,并且设置按钮的鼠标悬停效果 在用MFC开发时,界面是比较不好开发的一块.VC中自带了CBitmap ...

  4. JavaGUI——设置框架背景颜色和按钮颜色

    import java.awt.Color; import javax.swing.*; public class MyDraw { public static void main(String[] ...

  5. div滚动条,可以自由的给滚动条定义背景,上下按钮,当然不仅仅是颜色,连图片当背景也可以。

    可以自由的给滚动条定义背景,上下按钮,当然不仅仅是颜色,连图片当背景也可以.支持鼠标滚轮,点击滚动条滚轴定位,上下按钮久按加速,兼容firefox,谷歌 下载地址

  6. C++类有继承时,析构函数必须为虚函数

    C++类有继承时,析构函数必须为虚函数.如果不是虚函数,则使用时可能存在内在泄漏的问题. 假设我们有这样一种继承关系: 如果我们以这种方式创建对象: SubClass* pObj = new SubC ...

  7. C++ 继承体系中的名称覆盖

    首先一个简单的样例: int x; int f() { double x; cin >> x; return x; } 在上述代码中.函数f的局部变量x掩盖了全局变量x.这得从 " ...

  8. ios开发之--textview意见反馈页面(占位label,字数统计,提交按钮的交互设置)

    记录一个页面的功能: textview的占位符,字数统计,提交按钮的交互设置,具体效果图如下:

  9. 【C++】继承中的隐藏与覆盖

    没有访问控制符时默认为私有继承. 当基类中的某个函数有若干个重载版本,继承类中也实现了该函数的某个重载版本时,参数完全相同的基类版本被覆盖,基类的其他版本被隐藏. 1.若要在继承类中使用基类的被覆盖方 ...

随机推荐

  1. Android Material风格的应用(三)--DrawerLayout

    添加抽屉导航 Android Material风格的应用(一)--AppBar TabLayoutAndroid Material风格的应用(二)--RecyclerViewAndroid Mater ...

  2. 读文件头数据判断 PE 文件格式和类型

    namespace X.Reflection { using System; using System.IO; public static partial class ReflectionX { pu ...

  3. ehcache、memcache、redis三大缓存比较(转)

    最近项目组有用到这三个缓存,去各自的官方看了下,觉得还真的各有千秋!今天特意归纳下各个缓存的优缺点,仅供参考!  Ehcache 在Java项目广泛的使用.它是一个开源的.设计于提高在数据从RDBMS ...

  4. 首次使用vim

    不管是linux还是cygwin,刚安装完系统之后使用vim时都需要对vim进行配置.未配置的情况下,象方向键.回车键.退格键都不会是正常的反应.因为vim默认使用了vi的操作模式. 不多说,上代码. ...

  5. js 小数乘积位数太长

    function accMul(arg1,arg2) { var m=0,s1=arg1.toString(),s2=arg2.toString(); try{m+=s1.split(".& ...

  6. Log Explorer 使用说明(原创)

    关于Log Explorer (我抄的) 介绍Log Explorer主要用于对MSSQLServer的事物分析和数据恢复.你可以浏览日志.导出数据.恢复被修改或者删除的数据(包括执行过update, ...

  7. php ignore_user_abort()实现计划(定时执行)任务功能

    ? 1 2 3 4 5 6 7 8 9 10 11 12 <?php     ignore_user_abort(TRUE);  //关掉浏览器,PHP脚本也可以继续执行.     set_ti ...

  8. 【例题 6-3 UVA - 442】Matrix Chain Multiplication

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用栈来处理一下表达式就好. 因为括号是一定匹配的.所以简单很多. ab x bc会做abc次乘法. [代码] #include< ...

  9. [Nuxt] Load Data from APIs with Nuxt and Vuex

    In a server-rendered application, if you attempt to load data before the page renders and the data f ...

  10. ECMAScript5和ECMAScript6_浏览器支持情况

    ECMAScript5浏览器支持情况: Opera 11.60 Internet Explorer 9* Firefox 4 Safari 5.1** Chrome 13 * IE9不支持严格模式 - ...