`

XP风格Button源代码

XP 
阅读更多

XpButton.h

#pragma once

// CXpButton
class CXpButton : public CButton
{
	DECLARE_DYNAMIC(CXpButton)

public:
	CXpButton();
	virtual ~CXpButton();

protected:
	virtual void PreSubclassWindow();
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

	DECLARE_MESSAGE_MAP()

protected:
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
	afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);

public:
	virtual	void DoGradientFill(CDC *pDC, CRect* rect);
	virtual void DrawInsideBorder(CDC *pDC, CRect* rect);

protected:
	//按钮的外边框
	CPen	m_penBoundry;

	//鼠标指针置于按钮之上时按钮的内边框
	CPen	m_penInsideBoundryLeft;
	CPen	m_penInsideBoundryRight;
	CPen	m_penInsideBoundryTop;
	CPen	m_penInsideBoundryBottom;

	//按钮获得焦点时按钮的内边框
	CPen	m_penInsideBoundryLeftSel;
	CPen	m_penInsideBoundryRightSel;
	CPen	m_penInsideBoundryTopSel;
	CPen	m_penInsideBoundryBottomSel;

	//按钮的底色,包括有效和无效两种状态
	CBrush	m_brActive;
	CBrush	m_brInactive;

	//按钮状态
	BOOL	m_bOver;		//鼠标位于按钮之上时该值为true,反之为flase
	BOOL	m_bTracking;	//在鼠标按下没有释放时该值为true
	BOOL	m_bSelected;	//按钮被按下是该值为true
	BOOL	m_bFocus;		//按钮为当前焦点所在时该值为true
};
 

 

XpButton.cpp

// XpButton.cpp : implementation file
//
#include "stdafx.h"
#include "XpBtn.h"
#include "XpButton.h"


// CXpButton
IMPLEMENT_DYNAMIC(CXpButton, CButton)
CXpButton::CXpButton()
{
	//按钮的外边框
	m_penBoundry.CreatePen(PS_INSIDEFRAME | PS_SOLID, 1, RGB(0, 0, 0));

	//鼠标指针置于按钮之上时按钮的内边框
	m_penInsideBoundryLeft.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(250, 196, 88));
	m_penInsideBoundryRight.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(251, 202, 106));
	m_penInsideBoundryTop.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(252, 210, 121));
	m_penInsideBoundryBottom.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(229, 151, 0));

	//按钮获得焦点时按钮的内边框
	m_penInsideBoundryLeftSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(153, 198, 252));
	m_penInsideBoundryRightSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 3, RGB(162, 189, 252));
	m_penInsideBoundryTopSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(162, 201, 255));
	m_penInsideBoundryBottomSel.CreatePen(PS_INSIDEFRAME | PS_SOLID, 2, RGB(162, 201, 255));

	//按钮的底色,包括有效和无效两种状态
	m_brActive.CreateSolidBrush(RGB(223, 222, 236));
	m_brInactive.CreateSolidBrush(RGB(222, 223, 236));

	m_bOver = FALSE;		//鼠标位于按钮之上时该值为true,反之为flase
	m_bTracking = FALSE;	//在鼠标按下没有释放时该值为true
	m_bSelected = FALSE;	//按钮被按下是该值为true
	m_bFocus = FALSE;		//按钮为当前焦点所在时该值为true    
}

CXpButton::~CXpButton()
{
	//按钮的外边框
	m_penBoundry.DeleteObject();

	//鼠标指针置于按钮之上时按钮的内边框
	m_penInsideBoundryLeft.DeleteObject();
	m_penInsideBoundryRight.DeleteObject();
	m_penInsideBoundryTop.DeleteObject();
	m_penInsideBoundryBottom.DeleteObject();

	//按钮获得焦点时按钮的内边框
	m_penInsideBoundryLeftSel.DeleteObject();
	m_penInsideBoundryRightSel.DeleteObject();
	m_penInsideBoundryTopSel.DeleteObject();
	m_penInsideBoundryBottomSel.DeleteObject();

	//按钮的底色,包括有效和无效两种状态
	m_brActive.DeleteObject();
	m_brInactive.DeleteObject();
}


BEGIN_MESSAGE_MAP(CXpButton, CButton)
	ON_WM_MOUSEMOVE()
	ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
	ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
END_MESSAGE_MAP()

// CXpButton message handlers
void CXpButton::PreSubclassWindow()
{
	__super::PreSubclassWindow();
	ModifyStyle(0, BS_OWNERDRAW);
}

void CXpButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	//从lpDrawItemStruct获取控件的相关信息
	CRect rect = lpDrawItemStruct->rcItem;
	CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

	int nSaveDc = pDC->SaveDC();
	UINT uState = lpDrawItemStruct->itemState;

	POINT pt;
	char szText[MAX_PATH + 1] = {0};
	::GetWindowText(m_hWnd, szText, MAX_PATH);

	//画按钮的外边框,它是一个半径为5的圆角矩形
	pt.x = 5;
	pt.y = 5;
	CPen* pPenOld = pDC->SelectObject(&m_penBoundry);
	pDC->RoundRect(&rect, pt);

	//获取按钮的状态
	if (ODS_FOCUS & uState)
	{
		m_bFocus = TRUE;
		m_bSelected = TRUE;
	}
	else
	{
		m_bFocus = FALSE;
		m_bSelected = FALSE;
	}

	if (uState & ODS_SELECTED || uState & ODS_DEFAULT)
	{
		m_bFocus = TRUE;
	}

	pDC->SelectObject(pPenOld);
	rect.DeflateRect(CSize(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)));

	//根据按钮的状态填充按钮的底色
	CBrush* pBrushOld = NULL;

	if (m_bOver)
	{
		pBrushOld = pDC->SelectObject(&m_brActive);
		DoGradientFill(pDC, &rect);
	}
	else
	{
		pBrushOld = pDC->SelectObject(&m_brInactive);
		DoGradientFill(pDC, &rect);
	}

	//根据按钮的状态绘制内边框
	if (m_bOver || m_bSelected)
	{
		DrawInsideBorder(pDC, &rect);
	}

	if (NULL != szText)
	{
		CFont* pFont = GetFont();
		CFont* pFontOld = pDC->SelectObject(pFont);
		CSize szExtent = pDC->GetTextExtent(szText, strlen(szText));

		CPoint pt(rect.CenterPoint().x - szExtent.cx / 2, rect.CenterPoint().y - szExtent.cy / 2);

		if (ODS_SELECTED & uState)
		{
			pt.Offset(1, 1);
		}

		int nMode = pDC->SetBkMode(TRANSPARENT);
		if (ODS_DISABLED & uState)
		{
			pDC->DrawState(pt, szExtent, szText, DSS_DISABLED, TRUE, 0, (HBRUSH)NULL);
		}
		else
		{
			pDC->DrawState(pt, szExtent, szText, DSS_NORMAL, TRUE, 0, (HBRUSH)NULL);
		}

		pDC->SelectObject(pFontOld);
		pDC->SetBkMode(nMode);
	}

	pDC->RestoreDC(nSaveDc);
}

void CXpButton::OnMouseMove(UINT nFlags, CPoint point)
{
	if (!m_bTracking)
	{
		TRACKMOUSEEVENT	tme;
		tme.cbSize = sizeof(tme);
		tme.hwndTrack = m_hWnd;
		tme.dwFlags = TME_LEAVE | TME_HOVER;
		tme.dwHoverTime = 1;
		
		m_bTracking = _TrackMouseEvent(&tme);
	}

	__super::OnMouseMove(nFlags, point);
}

LRESULT CXpButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
	m_bOver = FALSE;
	m_bTracking = FALSE;
	InvalidateRect(NULL, FALSE);

	return S_OK;
}

LRESULT CXpButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
	m_bOver = TRUE;
	InvalidateRect(NULL, TRUE);

	return S_OK;
}

void CXpButton::DoGradientFill(CDC *pDC, CRect* rect)
{
	CBrush	brArrBk[64];
	int nWidth = rect->Width();
	int nHeight = rect->Height();

	CRect rct;
	int i = 0;

	for (i = 0; i < 64; i++)
	{
		if (m_bOver)
		{
			if (m_bFocus)
			{
				brArrBk[i].CreateSolidBrush(RGB(255 - (i / 4), 255 - (i / 4), 255 - (i / 3)));
			}
			else
			{
				brArrBk[i].CreateSolidBrush(RGB(255 - (i / 4), 255 - (i / 4), 255 - (i / 5)));
			}
		}
		else
		{
			if (m_bFocus)
			{
				brArrBk[i].CreateSolidBrush(RGB(255 - (i / 3), 255 - (i / 3), 255 - (i / 4)));
			}
			else
			{
				brArrBk[i].CreateSolidBrush(RGB(255 - (i / 3), 255 - (i / 3), 255 - (i / 5)));
			}
		}
	}

	for (i = rect->top; i <= nHeight + 2; i++)
	{
		rct.SetRect(rect->left, i, nWidth + 2, i + 1);
		pDC->FillRect(&rct, &brArrBk[i * 63 / nHeight]);
	}

	for (i = 0; i < 64; i++)
	{
		brArrBk[i].DeleteObject();
	}
}

void CXpButton::DrawInsideBorder(CDC *pDC, CRect* rect)
{
	CPen*	pPenLeft = NULL;
	CPen*	pPenRight = NULL;
	CPen*	pPenTop = NULL;
	CPen*	pPenBottom = NULL;

	if (m_bSelected && !m_bOver)
	{
		pPenLeft = &m_penInsideBoundryLeftSel;
		pPenRight = &m_penInsideBoundryRightSel;
		pPenTop = &m_penInsideBoundryTopSel;
		pPenBottom = &m_penInsideBoundryBottomSel;
	}
	else
	{
		pPenLeft = &m_penInsideBoundryLeft;
		pPenRight = &m_penInsideBoundryRight;
		pPenTop = &m_penInsideBoundryTop;
		pPenBottom = &m_penInsideBoundryBottom;
	}

	CPoint ptOld = pDC->MoveTo(rect->left, rect->bottom - 1);
	CPen* pPenOld = pDC->SelectObject(pPenLeft);
	pDC->LineTo(rect->left, rect->top + 1);

	pDC->SelectObject(pPenRight);
	pDC->MoveTo(rect->right - 1, rect->bottom - 1);
	pDC->LineTo(rect->right - 1, rect->top);

	pDC->SelectObject(pPenTop);
	pDC->MoveTo(rect->left - 1, rect->top);
	pDC->LineTo(rect->right - 1, rect->top);

	pDC->SelectObject(pPenBottom);
	pDC->MoveTo(rect->left, rect->bottom);
	pDC->LineTo(rect->right - 1, rect->bottom);

	pDC->SelectObject(pPenOld);
	pDC->MoveTo(ptOld);

	if (m_bSelected && !m_bOver)
	{
		DrawFocusRect(pDC->m_hDC, rect);
	}
}
 
分享到:
评论

相关推荐

    抛砖引玉——XP风格的按钮源代码

    ### XP风格按钮源代码知识点解析 #### 一、概述 本文档主要介绍了一段实现Windows XP风格按钮的源代码。该按钮控件继承自`System.Windows.Forms.Button`类,并通过重写部分方法来达到视觉上的XP风格效果。这段代码...

    VB6 XP风格Button

    在提供的压缩包文件“XpButton”中,应该包含了实现上述功能的VB6源代码文件。打开这个源文件,你可以看到详细的代码实现,包括各种函数和过程,以及如何在控件的`OnPaint`事件中调用这些函数来绘制XP风格的按钮。...

    仿XP风格界面的好友管理器VB源代码_xp风格_

    【标题】"仿XP风格界面的好友管理器VB源代码"是基于Visual Basic(VB)开发的一款应用程序,它旨在提供类似微软Windows XP操作系统的用户界面体验。XP风格的界面设计,包括了蓝色的任务栏和经典的按钮样式,这些都是...

    VB XP按钮控件 源代码 很详细!!

    总之,VB XP按钮控件是通过源代码自定义的一种用户界面元素,它允许开发者在VB程序中构建具有Windows XP风格的按钮,提供更丰富的用户体验。通过研究和理解这些源代码,开发者可以学习到如何利用VB的图形绘制能力,...

    具有XP风格的Button类

    例如,如果XPButton类是在一个名为`XPButton.h`的头文件中定义的,那么在你的源代码文件顶部,你需要加入如下代码: ```cpp #include "XPButton.h" ``` 接下来,你可以像创建普通按钮一样创建XPButton对象,并设置...

    开发XP风格程序原代码

    在本文中,我们将深入探讨如何利用C++或.NET Framework等技术实现XP风格的程序,并通过源代码实例进行讲解。 首先,XP风格的实现依赖于Windows API,特别是`UxTheme`库,它提供了启用和使用视觉样式的功能。在C++中...

    WinCE Button XP 风格 CButtonST VS2005 EVC

    `CButtonST`(即“Styled Button”)是一个类库,它允许开发者在Visual Studio 2005(EVC,Embedded Visual C++)环境下为WinCE系统创建具有XP风格的按钮控件。这个类库扩展了标准的MFC `CButton`类,增加了额外的...

    XP风格按钮类 VC

    首先,XP风格按钮(XPStyle Button)是通过Windows API中的Comctl32库提供的,该库包含了支持XP风格控件的新版本。在VC++项目中,我们需要确保使用的是Comctl32库的6.0版本或更高。这通常需要在项目的属性设置中启用...

    xp_button_menu.src.rar_button菜单

    1. **源代码**:压缩包中的"xp_button_menu.src"很可能是用某种编程语言(如C++、C#或VB.NET)编写的源代码文件,开发者可以通过阅读和修改这些代码来适应自己的项目需求,或者研究其内部实现机制。 2. **Windows XP...

    XPDlg(XP风格按钮).rar_button

    本项目"XPDlg(XP风格按钮).rar_button"正是这样一个实例,它演示了如何在基于对话框的应用程序中实现XP风格的按钮,并且当用户点击该按钮时,会弹出一个具有XP风格的帮助对话框。 首先,我们需要理解“XP风格”是...

    VB.Programming.XP.button.design.module.code.rar_button vb xp_xp

    1. **自定义控件类**:开发者可能会创建一个继承自`System.Windows.Forms.Button`的自定义控件类,以便在其中添加XP风格的绘图逻辑。 2. **重写OnPaint方法**:在自定义控件类中,`OnPaint`方法是关键,因为它负责...

    一个XP风格的Button XPButton

    1. 将`XPButton`文件添加到你的项目中,通常是通过“添加现有项”将控件的DLL或源代码文件引入项目。 2. 在Windows Forms设计器中,从工具箱中拖放`XPButton`控件到窗体上。 3. 在属性窗口中设置控件的属性,如文字...

    xp效果的button类

    通过深入理解这些概念并分析提供的源代码,我们可以学习到如何在C++环境中实现具有XP风格的自定义按钮控件,这对于开发具有原生系统风格的应用程序非常有用。在实际编程中,开发者可以根据需求灵活地调整和扩展此类...

    SplitButton an XP style dropdown split button

    【标题】"SplitButton an XP风格下拉分隔按钮"是一种在Windows XP界面风格下的特殊按钮控件,它结合了单击按钮和下拉菜单的功能。这种设计在用户界面中提供了一种高效的交互方式,允许用户执行快速操作或访问更多...

    VB界面编程xp风格

    - **VB源代码**:展示了如何编写代码来实现XP风格的控件和界面。 - **图片和图标**:用于界面的图形资源,如按钮图片、背景图等。 - **文档或教程**:可能包括对示例代码的解释和使用说明,帮助理解实现原理。 通过...

    VC++自制的XP风格按钮全部代码

    内容索引:VC/C++源码,界面编程,按钮 VC++自制的XP风格按钮完整源代码,全部C++代码实现, 没有用到任何三方插件。仿XP按钮虽然有点过时了,但对编程新手还是有帮助的,如果搞懂了仿XP,接下来就可以仿VISTA了,呵呵...

    VC制作XP风格的按钮

    在提供的“核心实例2 XP风格按钮”压缩包中,应该包含了具体的源代码示例,通过查看和学习这个实例,你可以更深入地理解如何在VC++中自绘XP风格的按钮。记得仔细研究代码中的每个函数和细节,这将有助于你掌握自定义...

    超市管理信息系统(数据库)源代码

    以前好像在某些地方发布过这些控件的源代码,但那些都是老版本了,这个程序集成了3个最新版本的XP风格控件,呵呵,应该能令大家满意了吧。最后一个 XPButton 是网上流行的XP按钮,不过遗憾是这个按钮的代码太多了,...

    计算机软件-商业源码-很不错的按钮xp风格的.zip

    对于"计算机软件-商业源码-很不错的按钮xp风格的.zip"这个压缩包,我们可以推测它包含的是一个用于创建具有Windows XP风格按钮的软件或库的源代码。Windows XP是一款经典的微软操作系统,其界面设计风格在当时广受...

    VB漂亮的XP样式按钮代码.rar

    1. **自定义控件**:在VB中,可以通过继承自`Button`控件创建一个新的类,然后覆盖或扩展其默认行为,比如重写`OnPaint`事件,以绘制出XP风格的外观。 2. **绘图基础**:实现XP风格按钮的关键在于绘图,这需要对GDI...

Global site tag (gtag.js) - Google Analytics