自绘实现半透明水晶按钮(继承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.若要在继承类中使用基类的被覆盖方 ...
随机推荐
- 【博客之星】CSDN2013博客之星--分析和预测
本文纯属个人见解,多有得罪啊! 具体结果,还是看最后CSDN给的结果吧! 昵称 名字 题材 质量 数量 知名度 预测 阳光岛主 杨刚 Python,Clojure,SAE 很高 346+ 很大 一定( ...
- EventWaitHandle
在查资料的过程中,我突然想到一个类:EventWaitHandle,也就是本文的主角. 这个类通过在线程之间设置信号量,可以非常方便的控制线程运行的顺序.具体代码如下: 首先全局申明: EventWa ...
- Android Gradle统一依赖管理
目的: 避免在依赖包出新版本时,需要对每个module中的build.gradle文件都进行修改(如appcompat-v7包),使用这种方式即只需一次修改. 方法一 在项目的根目录创建一个gradl ...
- FindBug:Call to static DateFormat
今天在重构代码的过程中碰到了一个问题.使用SimpleDateFormat的问题. 本人今天写了一个类,主要是提供很多静态的方法由其他接口调用,过程中多个方法使用到了日期的格式化,所以我讲Simple ...
- UML学习总结(2)——StartUML 各种类图的例子
1.UML分为: 1)静态建模:系统基础和系统固定框架结构,这些图形往往是"静态"的. 类图(Class Diagram):常用来分析业务概念 用例图(Use Case Diagr ...
- git 配置用户名email地址,设置密码
- 14、编写一个通用的Makefile
编译test_Makefile的方法:a. gcc -o test a.c b.c对于a.c: 预处理.编译(C文件转换成汇编).汇编(汇编转换成机器码)对于b.c:预处理.编译.汇编最后链接优点:命 ...
- [Nuxt] Add Arrays of Data to the Vuex Store and Display Them in Vue.js Templates
You add array of todos to the store simply by adding them to the state defined in your store/index.j ...
- php课程 2-7 php中常量如何定义
php课程 2-7 php中常量如何定义 一.总结 一句话总结:函数方式定义和普通变量方式定义 define('PI','3.14').键值对,和session一样. const PI=3 ...
- open ball、closed ball 与 open set、closed set(interior point,limit point)、dense set
0. demo 在拓扑学上,open set(开集)是对实数轴(real line)上开区间(open interval)的拓展. 红色圆盘:{(x,y)|x2+y2<r2},蓝色圆圈:{(x, ...