GdiButton

在QQ、MSN等软件中,可以看到许多漂亮的按钮,例如MSN聊天窗口中的“发送”按钮看上去有一种立体感,用户体验很好。

我使用GDI+实现了这种风格的按钮,下面简单介绍一下按钮的实现过程和使用方法。

1.   创建一个基于对话框的工程“TestGdiplusButton”,所有设置都使用默认值既可。

2.   加入新类CGdiplusButton,修改基类为CButton,将生成GdiplusButton.h和GdiplusButton.cpp两个文件。

3.   按照后文所述的源代码修改MFC为你生成的代码,由于代码很简单,我就不在这里做具体说明了,大家可以边动手边看代码。

4.   修改完成后,在资源文件中为主对话框添加一个按钮,并为其添加CButton形的控制变量m_ctrlButton,在TestGdiplusButtonDlg.h中包含GdiplusButton.h,并把m_ctrlButton的类型由CButton改为CGdiplusButton,如果一些顺利的话,编译并运行程序,你就应该可以看到一个漂亮的按钮啦。

5.   由于该类使用gdi+库,如果用到你最终的产品上,最好连同dll一起发布。

6.   附源代码(已在XP+SP2+VC6/VC.NET 2003测试通过)。

// GdiplusButton.h 文件

#pragma once

 

#include <GdiPlus.h>

 

class CGdiplusButton : public CButton

{

     DECLARE_DYNAMIC(CGdiplusButton)

 

public:

     CGdiplusButton();

     virtual ~CGdiplusButton();

 

protected:

     DECLARE_MESSAGE_MAP()

    

     virtual void PreSubclassWindow();

private:

     Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;

     ULONG_PTR m_gdiplusToken;

     COLORREF m_BorderColor;

     COLORREF m_InsideColor1;

     COLORREF m_InsideColor2;

     BOOL m_bIsLButtonDown;

 

public:

     virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

     afx_msg void OnLButtonDown(UINT nFlags, CPoint point);

     afx_msg void OnLButtonUp(UINT nFlags, CPoint point);

};

 

// GdiplusButton.cpp 文件

#include "stdafx.h"

#include "GdiplusButton.h"

 

using namespace Gdiplus;

#pragma comment(lib,"gdiplus.lib")

 

IMPLEMENT_DYNAMIC(CGdiplusButton, CButton)

 

CGdiplusButton::CGdiplusButton()

{

     m_BorderColor  = RGB(0, 0, 0);

     m_InsideColor1 = RGB(177, 228, 245);

     m_InsideColor2 = RGB(52, 166, 203);

     m_bIsLButtonDown = FALSE;

     GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL);

}

 

CGdiplusButton::~CGdiplusButton()

{

     GdiplusShutdown(m_gdiplusToken);

}

 

BEGIN_MESSAGE_MAP(CGdiplusButton, CButton)

     ON_WM_LBUTTONDOWN()

     ON_WM_LBUTTONUP()

END_MESSAGE_MAP()

 

 

void CGdiplusButton::PreSubclassWindow()

{

     ModifyStyle(0, BS_OWNERDRAW);

     CButton::PreSubclassWindow();

}

 

void CGdiplusButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

{

     CRect rc;

     GetClientRect(&rc);

 

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

     pDC->RoundRect(&rc, CPoint(3, 3));

 

     CPen BorderPen;

     LOGPEN logpen;

     ::ZeroMemory(&logpen,sizeof(LOGPEN));

     logpen.lopnColor = m_BorderColor;

     logpen.lopnStyle = PS_SOLID;

     BorderPen.CreatePenIndirect(&logpen);

     HPEN hOldPen =  (HPEN)pDC->SelectObject(&BorderPen);

     pDC->RoundRect(&rc, CPoint(5, 5));

     pDC->SelectObject(hOldPen);

     BorderPen.DeleteObject();

 

     CRgn rgn;

     rgn.CreateRoundRectRgn(rc.left+1, rc.top+1, rc.right, rc.bottom, 3, 3);

 

     Region region((HRGN)rgn.GetSafeHandle());

     Graphics graphics(lpDrawItemStruct->hDC);

 

     if(m_bIsLButtonDown)

     {

         LinearGradientBrush linGrBrush(

              Point(0, 0),

              Point(0, rc.Height()-2),

              Color(255, GetRValue(m_InsideColor2), GetGValue(m_InsideColor2), GetBValue(m_InsideColor2)),  

              Color(255, GetRValue(m_InsideColor1), GetGValue(m_InsideColor1), GetBValue(m_InsideColor1))); 

         graphics.FillRegion(&linGrBrush, &region);

     }

     else

     {

         LinearGradientBrush linGrBrush(

              Point(0, 0),

              Point(0, rc.Height()-2),

              Color(255, GetRValue(m_InsideColor1), GetGValue(m_InsideColor1), GetBValue(m_InsideColor1)),  

              Color(255, GetRValue(m_InsideColor2), GetGValue(m_InsideColor2), GetBValue(m_InsideColor2))); 

         graphics.FillRegion(&linGrBrush, &region);

     }

 

     rgn.DeleteObject();

 

     CString str;

     GetWindowText(str);

     pDC->SelectStockObject(BLACK_PEN);

     pDC->SetBkMode(TRANSPARENT);

     if(m_bIsLButtonDown)

     {

         pDC->DrawText(str, CRect(rc.top+3, rc.left+3, rc.right, rc.bottom), DT_CENTER|DT_VCENTER|DT_SINGLELINE);

     }

     else

     {

         pDC->DrawText(str, rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);

     }

}

 

void CGdiplusButton::OnLButtonDown(UINT nFlags, CPoint point)

{

     m_bIsLButtonDown = TRUE;

 

     CButton::OnLButtonDown(nFlags, point);

}

 

void CGdiplusButton::OnLButtonUp(UINT nFlags, CPoint point)

{

     CRect rc;

     GetClientRect(&rc);

     if(m_bIsLButtonDown && !rc.PtInRect(point))

     {

         m_bIsLButtonDown = FALSE;

         Invalidate();

     }

     m_bIsLButtonDown = FALSE;

 

     CButton::OnLButtonUp(nFlags, point);

}


原文地址:http://blog.csdn.net/fisker0303/article/details/661133


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值