制作风格独特的按钮—用VC6扩展CButton类

2008-02-23 05:29:54来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

一、 本文介绍一个CButton的派生类CLinkButton,用此派生类制作的按钮具备以下特点:

1、按钮的外观类似静态控件类CStatic 产生的对象。(参见图一)

217775__image001.gif(图一)

2、当鼠标的光标移到按钮上,但并未按下时,光标改变形状,字体改变形状;按钮类似应用在工具条和菜单上的扁平钮效果。(参见图二)

217775__image003.gif(图二)

3、当按钮按下的情形:(参见图三)

217775__image005.gif(图三)

二、下面具体描述这种按钮的实现方法和步骤:

1. 在VC6的IDE环境中,生成一个基于对话框的PROJECT。

2. 将对话框资源中按钮的属性页打开,在“Style”标签页中选取按钮的“Owner Draw”(自绘)属性。

3. 将光标引入到应用程式的资源中。

4. 利用CLASSWIZARD,用CButton为基类,派生一个新类:CLinkButton。

5. 在派生类中重载基类CButton的虚函数:

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

之所以要重载这个函数是因为选择了按钮的 “Owner Draw”属性后,当按钮的可视行为发生变化时,应用程式的框架要调用这个函数来重新绘制按钮。

6. 定制以下的消息处理:

afx_msg void OnMouseMove(UINT nFlags, CPoint point);

afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);

afx_msg void OnTimer(UINT nIDEvent);

afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

afx_msg BOOL OnEraseBkgnd(CDC* pDC);

7. 声明类成员变量定义:

//定义字体变量

CFont fUnderline;

//定义光标变量

HCURSOR hHand;

//决定按钮是否按下

bool bLBtnDown;

//决定鼠标是否在按钮上

bool bHighlight;

二、 派生类CLinkButton 的具体实现:

1.重载函数  DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)。

void CLinkButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

// 获取一个CDC指针

CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

//定义按钮区域并初始化

CRect rect(lpDrawItemStruct->rcItem);

//配置背景模式

COLORREF oc = pDC->GetTextColor();

int iObk = pDC->SetBkMode(TRANSPARENT);

//初始化按钮状态

UINT state = lpDrawItemStruct->itemState;

CFont * pOldFont = NULL;

int iYOffset = 0, iXOffset = 0;

CString strText;

GetWindowText(strText);

rect.top = iYOffset;

rect.left = iXOffset;

if (state & ODS_DISABLED)

{

//按钮置灰状态(DISABLED)

CBrush grayBrush;

grayBrush.CreateSolidBrush (GetSysColor (COLOR_GRAYTEXT));

CSize sz = pDC->GetTextExtent(strText);

int x = rect.left (rect.Width() - sz.cx)/2;

int y = rect.top (rect.Height() - sz.cy)/2;

rect.top = 2;

rect.left = 2;

pDC->SetTextColor(GetSysColor(COLOR_3DHIGHLIGHT));

pDC->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

rect.top -= 2;

rect.left -= 2;

pDC->SetTextColor(GetSysColor(COLOR_GRAYTEXT));

pDC->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

}

else

{

if (bHighlight)//光标在按钮上

{

if (state & ODS_SELECTED)

{

//按下按钮

pDC->Draw3dRect(rect,GetSysColor(COLOR_3DSHADOW),

                GetSysColor(COLOR_3DHILIGHT));

}

else

{//未按下按钮

           pDC->Draw3dRect(rect,GetSysColor(COLOR_3DHILIGHT),

                GetSysColor(COLOR_3DSHADOW));

}

//字体颜色

pDC->SetTextColor(RGB(0,0,255));



//加下画线(也能够用其他字体)

if (fUnderline.GetSafeHandle() == NULL)

{

CFont * pFont = GetFont();

ASSERT(pFont);

LOGFONT lf;

pFont->GetLogFont(&lf);

lf.lfUnderline = TRUE;

fUnderline.CreateFontIndirect(&lf);

}

pOldFont = pDC->SelectObject(&fUnderline);

}

else pDC->SetTextColor(GetSysColor(COLOR_BTNTEXT));

pDC->DrawText(strText, rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);

if (pOldFont) pDC->SelectObject(pOldFont);

}

}

2.定制的消息处理函数

void OnMouseMove(UINT nFlags, CPoint point)

{

//配置一个定时器

SetTimer(1,10,NULL);

//

...

}

当鼠标光标移到按钮上时,执行此函数,定时器将发送一个 WM_TIMER消息到消息队列。

由OnTimer(UINT nIDEvent)函数处理这个消息。

void OnTimer(UINT nIDEvent)

{

//处理WM_TIMER消息

static bool pPainted = false;

POINT pt;

GetCursorPos(&pt);

CRect rect;

GetWindowRect (rect);

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: 实例解说Linux中fdisk分区使用方法(1)

下一篇: VC 中如何遍历整个目录树查找文档