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

实现方法
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
相关文章:自绘按钮实现颜色选择器
http://blog.csdn.net/cometnet/article/details/8464693
http://blog.csdn.net/caichao1234/article/details/8466449
自绘实现半透明水晶按钮(继承CButton,设置BS_OWNERDRAW风格,覆盖DrawItem函数绘制按钮,把父窗口的背景复制到按钮上,实现视觉上的透明,最后通过AlphaBlend实现半透明)的更多相关文章
- Delphi自写组件:可设置颜色的按钮(改成BS_OWNERDRAW风格,然后CN_DRAWITEM)
unit ColorButton; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, StdCtrls; ...
- 简单的自绘CListBox(多行显示)(覆盖DrawItem函数,然后用CDC绘制)
之前写过一个自绘的CListBox类,详细请参考http://blog.csdn.net/VisualEleven/archive/2010/10/12/5935430.aspx现在修改这之前的代码, ...
- MFC 使用位图按钮,并且设置按钮的鼠标悬停效果
系统环境:Windows 10软件环境:Visual C++ 2013 SP1本次目的:使用位图按钮,并且设置按钮的鼠标悬停效果 在用MFC开发时,界面是比较不好开发的一块.VC中自带了CBitmap ...
- JavaGUI——设置框架背景颜色和按钮颜色
import java.awt.Color; import javax.swing.*; public class MyDraw { public static void main(String[] ...
- div滚动条,可以自由的给滚动条定义背景,上下按钮,当然不仅仅是颜色,连图片当背景也可以。
可以自由的给滚动条定义背景,上下按钮,当然不仅仅是颜色,连图片当背景也可以.支持鼠标滚轮,点击滚动条滚轴定位,上下按钮久按加速,兼容firefox,谷歌 下载地址
- C++类有继承时,析构函数必须为虚函数
C++类有继承时,析构函数必须为虚函数.如果不是虚函数,则使用时可能存在内在泄漏的问题. 假设我们有这样一种继承关系: 如果我们以这种方式创建对象: SubClass* pObj = new SubC ...
- C++ 继承体系中的名称覆盖
首先一个简单的样例: int x; int f() { double x; cin >> x; return x; } 在上述代码中.函数f的局部变量x掩盖了全局变量x.这得从 " ...
- ios开发之--textview意见反馈页面(占位label,字数统计,提交按钮的交互设置)
记录一个页面的功能: textview的占位符,字数统计,提交按钮的交互设置,具体效果图如下:
- 【C++】继承中的隐藏与覆盖
没有访问控制符时默认为私有继承. 当基类中的某个函数有若干个重载版本,继承类中也实现了该函数的某个重载版本时,参数完全相同的基类版本被覆盖,基类的其他版本被隐藏. 1.若要在继承类中使用基类的被覆盖方 ...
随机推荐
- JS概述
从Asp.NET跨越到JavaScript.这既是一个新的领域也是一个非常熟悉的地方,新是由于不知道什么是JavaScript,首先来了解一下什么是JavaScript. ...
- 单位转换 inch mm mil
从上面看:英寸(inch)是最大的单位 其次是毫米(mm) 再次是密耳(mil)
- CSS笔记 - fgm练习 - 三个div变色 - CSS div等分布局
<title>三个div变红</title> <style> *{margin: 0; padding: 0} body{ text-align: center; ...
- Loadrunner--基准测试的两种方法
2 练习基准测试方法1 2.1 问题 为登录业务设计场景. 2.2 方案 在控制台中使用循环多次的方式执行场景.(多次数) 2.3 步骤 实现此案例需要执行以下步骤: 步骤一: 1.打开控制台,如下图 ...
- TOMCAT8009端口与AJP13协议
Tomcat最主要的功能是提供Servlet/JSP容器,尽管它也可以作为独立的Java Web服务器,它在对静态资源(如HTML文件或图像文件)的处理速度,以及提供的Web服务器管理功能方面都不如其 ...
- 怎样用Adobe Acrobat 7 Pro把PDF文档拆分成多个啊?
这个pdf文档里有多篇文章,我想把他们分开并分别保存在独立的pdf文档.怎么操作?我的电脑基础不太好,麻烦说得详细一些. Adobe Acrobat 7 Pro拆分PDF文档的方法: 1.点左边的“书 ...
- 9.9 Binder系统_Java实现_Android里java程序的编译启动
如果知道了进程号:通过ls /proc/进程号/task 可以看到所有线程 cat /proc/进程号/task/线程号/comm 可以达到线程名字(主线程是main,主线程号就是进程号) d ...
- [WASM] Compile C Code into WebAssembly
We use the C language instead of pure WAST to create a square root function using WASM Fiddle (https ...
- 7、基于嵌入式Linux的视频采集系统---UVC驱动模型介绍
UVC 即 usb video class.USB协议中,除了通用的软硬件电气接口规范等,还包含了各种各样的Class协议,用来为不同的功能定义各自的标准接口和具体的总线上的数据交互格式和内容.这些C ...
- JAVA后端实现统一扫码支付:微信篇
最近做完了一个项目,正好没事做,产品经理就给我安排了一个任务. 做一个像收钱吧这样可以统一扫码收钱的功能. 一开始并不知道是怎么实现的,咨询了好几个朋友,才知道大概的业务流程:先是开一个网页用 ...