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风格按钮源代码知识点解析 #### 一、概述 本文档主要介绍了一段实现Windows XP风格按钮的源代码。该按钮控件继承自`System.Windows.Forms.Button`类,并通过重写部分方法来达到视觉上的XP风格效果。这段代码...
在提供的压缩包文件“XpButton”中,应该包含了实现上述功能的VB6源代码文件。打开这个源文件,你可以看到详细的代码实现,包括各种函数和过程,以及如何在控件的`OnPaint`事件中调用这些函数来绘制XP风格的按钮。...
【标题】"仿XP风格界面的好友管理器VB源代码"是基于Visual Basic(VB)开发的一款应用程序,它旨在提供类似微软Windows XP操作系统的用户界面体验。XP风格的界面设计,包括了蓝色的任务栏和经典的按钮样式,这些都是...
总之,VB XP按钮控件是通过源代码自定义的一种用户界面元素,它允许开发者在VB程序中构建具有Windows XP风格的按钮,提供更丰富的用户体验。通过研究和理解这些源代码,开发者可以学习到如何利用VB的图形绘制能力,...
例如,如果XPButton类是在一个名为`XPButton.h`的头文件中定义的,那么在你的源代码文件顶部,你需要加入如下代码: ```cpp #include "XPButton.h" ``` 接下来,你可以像创建普通按钮一样创建XPButton对象,并设置...
在本文中,我们将深入探讨如何利用C++或.NET Framework等技术实现XP风格的程序,并通过源代码实例进行讲解。 首先,XP风格的实现依赖于Windows API,特别是`UxTheme`库,它提供了启用和使用视觉样式的功能。在C++中...
`CButtonST`(即“Styled Button”)是一个类库,它允许开发者在Visual Studio 2005(EVC,Embedded Visual C++)环境下为WinCE系统创建具有XP风格的按钮控件。这个类库扩展了标准的MFC `CButton`类,增加了额外的...
首先,XP风格按钮(XPStyle Button)是通过Windows API中的Comctl32库提供的,该库包含了支持XP风格控件的新版本。在VC++项目中,我们需要确保使用的是Comctl32库的6.0版本或更高。这通常需要在项目的属性设置中启用...
1. **源代码**:压缩包中的"xp_button_menu.src"很可能是用某种编程语言(如C++、C#或VB.NET)编写的源代码文件,开发者可以通过阅读和修改这些代码来适应自己的项目需求,或者研究其内部实现机制。 2. **Windows XP...
本项目"XPDlg(XP风格按钮).rar_button"正是这样一个实例,它演示了如何在基于对话框的应用程序中实现XP风格的按钮,并且当用户点击该按钮时,会弹出一个具有XP风格的帮助对话框。 首先,我们需要理解“XP风格”是...
1. **自定义控件类**:开发者可能会创建一个继承自`System.Windows.Forms.Button`的自定义控件类,以便在其中添加XP风格的绘图逻辑。 2. **重写OnPaint方法**:在自定义控件类中,`OnPaint`方法是关键,因为它负责...
1. 将`XPButton`文件添加到你的项目中,通常是通过“添加现有项”将控件的DLL或源代码文件引入项目。 2. 在Windows Forms设计器中,从工具箱中拖放`XPButton`控件到窗体上。 3. 在属性窗口中设置控件的属性,如文字...
通过深入理解这些概念并分析提供的源代码,我们可以学习到如何在C++环境中实现具有XP风格的自定义按钮控件,这对于开发具有原生系统风格的应用程序非常有用。在实际编程中,开发者可以根据需求灵活地调整和扩展此类...
【标题】"SplitButton an XP风格下拉分隔按钮"是一种在Windows XP界面风格下的特殊按钮控件,它结合了单击按钮和下拉菜单的功能。这种设计在用户界面中提供了一种高效的交互方式,允许用户执行快速操作或访问更多...
- **VB源代码**:展示了如何编写代码来实现XP风格的控件和界面。 - **图片和图标**:用于界面的图形资源,如按钮图片、背景图等。 - **文档或教程**:可能包括对示例代码的解释和使用说明,帮助理解实现原理。 通过...
内容索引:VC/C++源码,界面编程,按钮 VC++自制的XP风格按钮完整源代码,全部C++代码实现, 没有用到任何三方插件。仿XP按钮虽然有点过时了,但对编程新手还是有帮助的,如果搞懂了仿XP,接下来就可以仿VISTA了,呵呵...
在提供的“核心实例2 XP风格按钮”压缩包中,应该包含了具体的源代码示例,通过查看和学习这个实例,你可以更深入地理解如何在VC++中自绘XP风格的按钮。记得仔细研究代码中的每个函数和细节,这将有助于你掌握自定义...
以前好像在某些地方发布过这些控件的源代码,但那些都是老版本了,这个程序集成了3个最新版本的XP风格控件,呵呵,应该能令大家满意了吧。最后一个 XPButton 是网上流行的XP按钮,不过遗憾是这个按钮的代码太多了,...
对于"计算机软件-商业源码-很不错的按钮xp风格的.zip"这个压缩包,我们可以推测它包含的是一个用于创建具有Windows XP风格按钮的软件或库的源代码。Windows XP是一款经典的微软操作系统,其界面设计风格在当时广受...
1. **自定义控件**:在VB中,可以通过继承自`Button`控件创建一个新的类,然后覆盖或扩展其默认行为,比如重写`OnPaint`事件,以绘制出XP风格的外观。 2. **绘图基础**:实现XP风格按钮的关键在于绘图,这需要对GDI...