vc 按钮自绘

按钮自绘,将按钮区域分成三部分,左边、右边、中间都由贴图绘制,可用于手动进度条按钮,或者左右选择项按钮
cpp代码部分:
- // LRSkinButton.cpp : implementation file
- //
- #include "stdafx.h"
- #include "CRedrawButtonDemo.h"
- #include "LRSkinButton.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CLRSkinButton
- CLRSkinButton::CLRSkinButton()
- {
- m_nWidth = 17;
- m_nHeight = 16;
- m_bDrawBorder = TRUE;
- }
- CLRSkinButton::~CLRSkinButton()
- {
- }
- BEGIN_MESSAGE_MAP(CLRSkinButton, CButton)
- //{{AFX_MSG_MAP(CLRSkinButton)
- // NOTE - the ClassWizard will add and remove mapping macros here.
- //}}AFX_MSG_MAP
- ON_WM_CAPTURECHANGED()
- ON_WM_MOUSEMOVE()
- ON_WM_SETCURSOR()
- ON_WM_KILLFOCUS()
- END_MESSAGE_MAP()
- void CLRSkinButton::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
- {
- // TRACE("DrawItem\n");
- // TODO: 添加您的代码以绘制指定项
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- HDC hDC = pDC->GetSafeHdc();
- // 按钮客户区域
- CRect rectItem(lpDrawItemStruct->rcItem);
- m_nHeight = rectItem.Height();
- m_nWidth = 26;
- CRect rectCenter(rectItem.left+m_nWidth, rectItem.top, rectItem.right-m_nWidth, rectItem.bottom);
- CRect rectLeft(rectItem.left, rectItem.top, rectItem.left+m_nWidth, rectItem.top+m_nHeight);
- CRect rectRight(rectItem.right-m_nWidth,rectItem.top,rectItem.right,rectItem.bottom);
- static int nClrWidth = rectCenter.Width()/10;
- CRect rectColor(rectCenter.left, rectCenter.top, rectCenter.left, rectCenter.bottom);
- rectCenter.DeflateRect(0,1,0,1);
- // pDC->SetBkMode(TRANSPARENT);
- HPEN hOldPen;
- UINT action, state;
- action = lpDrawItemStruct->itemAction;
- state = lpDrawItemStruct->itemState;
- BOOL bIsPressed, bIsFocus, bIsDisabled;
- bIsPressed = state & ODS_SELECTED;
- bIsDisabled = state & ODS_DISABLED;
- bIsFocus = (state & ODS_FOCUS) == ODS_FOCUS; // ::GetFocus() == m_hWnd;
- ::SetBkColor(hDC, RGB(22, 33, 55));
- // Draw pressed button
- if (bIsPressed)
- {// 按钮按下状态
- /*
- HPEN penBtnHiLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));//COLOR_3DLIGHT)); // Bianco
- HPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW)); // Grigio scuro
- // draw darkline of left-top conner
- hOldPen = (HPEN)SelectObject(hDC,penBtnShadow);
- MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
- LineTo(hDC,rectItem.left, rectItem.top);
- LineTo(hDC,rectItem.right, rectItem.top);
- // draw hilight line of right-bottom conner
- SelectObject(hDC,penBtnHiLight);
- MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
- LineTo(hDC,rectItem.right-1, rectItem.bottom-1);
- LineTo(hDC,rectItem.right-1, rectItem.top-1);
- //release resource
- SelectObject(hDC,hOldPen);
- DeleteObject(penBtnShadow);
- DeleteObject(penBtnHiLight);
- */
- // 判断点击的是左区域还是右区域
- POINT pos;
- GetCursorPos( &pos );
- ScreenToClient(&pos);
- if (PtInRect( &rectLeft, pos))
- {// 左键
- TRACE(_T("Clicked Left...\n"));
- nClrWidth -= 5;
- if (nClrWidth <=0)
- {
- nClrWidth = 0;
- }
- }
- if (PtInRect( &rectRight, pos))
- {// 右键
- TRACE(_T("Clicked Right...\n"));
- nClrWidth += 5;
- if (nClrWidth >= rectCenter.Width())
- {
- nClrWidth = rectCenter.Width();
- }
- }
- }
- else // ...else draw non pressed button
- {
- if(!m_bIsFlat || (m_bIsFlat && m_MouseOnButton))
- {// 鼠标移动到按钮上面时的状态
- /*
- HPEN pen3DLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));//COLOR_3DLIGHT)); // Light gray
- HPEN penBtnShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW)); // Dark gray
- // White line
- hOldPen = (HPEN)SelectObject(hDC,pen3DLight);
- MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
- LineTo(hDC,rectItem.left, rectItem.top);
- LineTo(hDC,rectItem.right, rectItem.top);
- // Dark gray line
- SelectObject(hDC,penBtnShadow);
- MoveToEx(hDC,rectItem.left, rectItem.bottom-1,NULL);
- LineTo(hDC,rectItem.right-1, rectItem.bottom-1);
- LineTo(hDC,rectItem.right-1, rectItem.top-1);
- //
- SelectObject(hDC,hOldPen);
- DeleteObject(pen3DLight);
- DeleteObject(penBtnShadow);
- */
- }
- else{// FLAT 属性
- if(m_bDrawBorder)
- { // 失去焦点的时候绘制按钮边框
- HPEN penBorder = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
- hOldPen = (HPEN)SelectObject(hDC,penBorder);
- SelectObject(hDC,GetStockObject(NULL_BRUSH));
- // 绘制按钮边框
- Rectangle(hDC,rectItem.left, rectItem.top, rectItem.right, rectItem.bottom);
- SelectObject(hDC, hOldPen);
- DeleteObject(penBorder);
- }
- }
- }
- // if (lpDrawItemStruct->itemData != NULL)
- // {
- // 画图标
- CRect rect(rectCenter);
- // rect.DeflateRect(0,5,0,0); // 改变矩形范围
- CDC dcMem;
- dcMem.CreateCompatibleDC(pDC);
- // 背景图
- CBitmap bmp;
- BITMAP bitmap;
- bmp.LoadBitmap(m_nBmpBK);
- bmp.GetBitmap( &bitmap );
- CBitmap* pOldBmp = dcMem.SelectObject(&bmp);
- pDC->StretchBlt(rectCenter.left, rectCenter.top, rectCenter.Width(), rectCenter.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
- bmp.DeleteObject();
- // 左按钮图
- bmp.LoadBitmap( m_nBmpLeft );
- dcMem.SelectObject( &bmp );
- bmp.GetBitmap( &bitmap );
- // pDC->BitBlt(rectLeft.left,rectLeft.top,rectLeft.Width(),rectLeft.Height(),&dcMem,0,0,SRCCOPY);
- pDC->StretchBlt(rectLeft.left, rectLeft.top, rectLeft.Width(), rectLeft.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
- bmp.DeleteObject();
- // 右按钮图
- bmp.LoadBitmap( m_nBmpRight );
- bmp.GetBitmap( &bitmap );
- dcMem.SelectObject( &bmp );
- // pDC->BitBlt(rectRight.left,rectRight.top,rectRight.Width(),rectRight.Height(),&dcMem,0,0,SRCCOPY);
- pDC->StretchBlt(rectRight.left, rectRight.top, rectRight.Width(), rectRight.Height(), &dcMem, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
- bmp.DeleteObject();
- dcMem.SelectObject(pOldBmp);
- // 绘制颜色进度条
- bmp.LoadBitmap(IDB_BMP_BTNLEFT);
- // CBrush brush(&bmp); //RGB(255, 255, 0)
- CBrush brush(RGB(255, 255, 0)); //
- rectColor.right = rectColor.left+nClrWidth;
- pDC->FillRect(rectColor, &brush);
- // CBrush *pOldBrush = (CBrush*)pDC->SelectObject(&brush);
- // pDC->Rectangle(&rectColor);
- // pDC->SelectObject(pOldBrush);
- bmp.DeleteObject();
- // 绘制文字
- rect = rectCenter;
- // rect.DeflateRect(0,5,0,0); // 调整矩形大小
- rect.InflateRect(0,1,0,1);
- pDC->SetTextColor(RGB(0,0,0));
- // rect.OffsetRect(2,1); // 平行移动矩形位置
- // char zsCaption[64] = {0};
- CString str;
- GetWindowText( str );
- COLORREF clr = GetSysColor( COLOR_3DHILIGHT);
- clr = RGB(55, 155, 55);
- if (bIsPressed)
- {
- clr = RGB(155, 55, 55);
- }
- else if (bIsFocus /*|| m_MouseOnButton*/)
- {
- clr = RGB(55, 55, 155);
- HPEN penBorder = CreatePen(PS_SOLID, 1, RGB(255,0,255));
- hOldPen = (HPEN)SelectObject(hDC,penBorder);
- SelectObject(hDC,GetStockObject(NULL_BRUSH));
- // 绘制按钮边框
- Rectangle(hDC,rect.left, rect.top, rect.right, rect.bottom);
- SelectObject(hDC, hOldPen);
- DeleteObject(penBorder);
- }
- pDC->SetBkColor(clr);
- pDC->SetTextColor( RGB(255, 0, 0) );
- pDC->DrawText(str, str.GetLength(),rect, DT_CENTER | DT_VCENTER| DT_SINGLELINE);
- // }
- }
- void CLRSkinButton::SetBtnBmps( UINT uBmpBK, UINT uBmpLeft, UINT uBmpRight )
- {
- m_nBmpBK = uBmpBK;
- m_nBmpLeft = uBmpLeft;
- m_nBmpRight = uBmpRight;
- }
- void CLRSkinButton::PreSubclassWindow()
- {
- UINT nBS = GetButtonStyle();
- if(nBS & BS_DEFPUSHBUTTON)
- m_bDefaultBtn = TRUE;
- else
- m_bDefaultBtn = FALSE;
- SetButtonStyle(nBS | BS_OWNERDRAW);
- CButton::PreSubclassWindow();
- }
- /////////////////////////////////////////////////////////////////////////////
- // CLRSkinButton message handlers
- void CLRSkinButton::OnCaptureChanged(CWnd *pWnd)
- {
- if(m_MouseOnButton == TRUE)
- {
- ReleaseCapture();
- Invalidate();
- }
- CButton::OnCaptureChanged(pWnd);
- }
- void CLRSkinButton::OnMouseMove(UINT nFlags, CPoint point)
- {
- CButton::OnMouseMove(nFlags, point);
- HWND hParent; // Finestra che contiene il bottone
- // If the mouse enter the button with the left button pressed then do nothing
- if (nFlags & MK_LBUTTON && !m_MouseOnButton)
- return;
- // If our button is not flat then do nothing
- if (m_bIsFlat)
- {
- hParent = ::GetParent(m_hWnd);
- if ((::GetCapture() != m_hWnd) && (hParent != NULL))
- {
- m_MouseOnButton = TRUE;
- SetCapture();
- Invalidate();
- }
- else
- {
- RECT rc;
- GetClientRect(&rc);
- if (!PtInRect(&rc,point))
- {
- // Redraw only if mouse goes out
- if (m_MouseOnButton == TRUE)
- {
- m_MouseOnButton = FALSE;
- Invalidate();
- }
- // If user is NOT pressing left button then release capture!
- if (!(nFlags & MK_LBUTTON))
- ReleaseCapture();
- }
- }
- }
- }
- BOOL CLRSkinButton::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
- {
- if (m_hBtnCursor != NULL)
- {
- ::SetCursor(m_hBtnCursor);
- return TRUE;
- }
- return CButton::OnSetCursor(pWnd, nHitTest, message);
- }
- void CLRSkinButton::OnKillFocus(CWnd* pNewWnd)
- {
- CButton::OnKillFocus(pNewWnd);
- if(!m_bIsFlat)
- {
- m_MouseOnButton = FALSE;
- Invalidate();
- }
- }

vc 按钮自绘的更多相关文章
- VC++ WIN32 sdk实现按钮自绘详解.
网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片: 首先建立一个标准的Win32 Application 工程.选择a simple Wi ...
- VC++ WIN32 sdk实现按钮自绘详解 之二(关键是BS_OWNERDRAW和WM_DRAWITEM)
网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片: 首先建立一个标准的Win32 Application 工程.选择a simple Wi ...
- VC++ WIN32 sdk实现按钮自绘详解 之二.
网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片: 首先建立一个标准的Win32 Application 工程.选择a simple Wi ...
- VC按钮控件实现指示灯效果
VC为按钮控件添加图片的方法有很多种: 直接调用SetBitmap: CButton pButton->SetBitmap(hBitmap); 使用CButtonST控件: 使用CDC: 使用 ...
- Windows开发进阶之VC++中如何实现对话框的界面重绘
技术:Windows 系统+Visual studio 2008 概述 应用程序界面是用户与应用程序之间的交互的桥梁和媒介,用户界面是应用程序中最重要的组成部分,也是最为直观的视觉体现.对用户而言 ...
- Windows 开发之VC++垃圾清理程序软件
概述 本程序软件的主要实现垃圾文件清理的功能,即对指定的文件格式的临时文件或垃圾文件进行遍历.扫描.显示.删除清理等功能.在程序界面设计方面,对默认对话框重新自定义绘制,主要包括标题栏的重绘.对话框边 ...
- win32进阶之路:给锁屏软件增加一个超链接按钮
前言: windows下一切皆窗口,我们看到的超链接也是窗口,效果图如下: 鼠标放在赵大哥博客园主页和关于软件两个按钮上,按钮上的字体会从绿色变成红色,同时鼠标指针变为手型,点下鼠标左键就会调用默认浏 ...
- MFC/VC++ UI界面美化技术
1. 工具: 1.1设备环境类: Windows下的绘图操作说到底就是DC操作.DC(Device Context设备环境)对象是一个抽象的作图环境,可能是对应屏幕,也可能是对应打印机或其它. ...
- 用Delphi制作仿每行带按钮的列表
Delphi做程序开发在使用到列表控件时,一般是列表放文本内容,在列表以外放操作按钮,选中列表某项再点按钮进行操作.现在Web开发做列表的样式总是列表的每行都有操作按钮,如微博的列表风格: Web开发 ...
随机推荐
- WeCenter 社交化问答社区程序 | WeCenter 是一款知识型的社交化问答社区程序,专注于社区内容的整理、归类、检索和再发行
WeCenter 社交化问答社区程序 | WeCenter 是一款知识型的社交化问答社区程序,专注于社区内容的整理.归类.检索和再发行 为什么选择 WeCenter 程序? 让您的社区更智能地运作,强 ...
- android大牛高焕堂最新力作-android架构师之路
android大牛高焕堂 个人介绍: Android专家顾问,台湾Android论坛主席,现任亚太地区Android技术大会主席,台湾Android领域框架开发联盟总架构师.发表100多篇Androi ...
- 浅析Linux的软中断的实现
參考: http://bbs.chinaunix.net/thread-2333484-1-1.html http://liu1227787871.blog.163.com/blog/static/2 ...
- 《音乐商店》第4集:自动生成StoreManager控制器
一.自动生成StoreManager控制器 二.查看 StoreManager 控制器的代码 现在,Store Manager 控制器中已经包含了一定数量的代码,我们从头到尾重新过一下. 1.访问数据 ...
- perl oracle utf-8 结果匹配中文字符
[oracle@oadb sbin]$ cat s1.pl #!/usr/bin/perl use DBI; use Encode; use HTTP::Date qw(time2iso str2ti ...
- ORA-01093: ALTER DATABASE CLOSE only permitted with no sessions connected解决方法
在进行物理主备库角色转换的时候遇到ORA-01093错误 SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY; ALTER ...
- [置顶] think in java interview-高级开发人员面试宝典(八)
面经出了7套,收到许多读者的Email,有许多人说了,这些基础知识是不是为了后面进一步的”通向架构师的道路“做准备的? 对的,你们没有猜错,就是这样的,我一直在酝酿后面的”通向架构师的道路“如何开章. ...
- IT忍者神龟之Oracle DBA经常使用查询吐血列举
–1. 查询系统全部对象 select owner, object_name, object_type, created, last_ddl_time, timestamp, status from ...
- 符号文件(.pdb)——Windows 应用程序调试必备
最近在做项目需求过程中,时不时会遇到崩溃,总是异常中断,于是学习了windbg进行调试的一些基础,windbg在接下来文章进行更新,先介绍在windbg调试中一个重要文件(符号文件) 一.符号文件定义 ...
- Android Content Provider的启动过程源码分析
本文參考Android应用程序组件Content Provider的启动过程源码分析http://blog.csdn.net/luoshengyang/article/details/6963418和 ...