Chinaunix首页 | 论坛 | 博客
  • 博客访问: 539159
  • 博文数量: 252
  • 博客积分: 6057
  • 博客等级: 准将
  • 技术积分: 1635
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-21 10:17
文章分类

全部博文(252)

文章存档

2013年(1)

2012年(1)

2011年(32)

2010年(212)

2009年(6)

分类:

2010-07-27 14:48:07

发表于:2002-09-24 09:51:02
DsFancyButton 是一个漂亮的图形按钮控件,边缘的渐变效果使按钮具有透明玻璃似的效果。还支持圆形、椭圆形、橄榄形等多种形状。可以在这个地址下载 。可惜是用PASCAL写的,而 在公司那花了20000RMB买回来的BCB6.0上居然装不上。于是偶就想将其改为BCB的。改后的代码由TABCButton.cpp及 TABCButton.h两个文件构成。编译等都OK,但生成的按钮闪烁不定.....实在是不能用,我估计是是消息没处理好,但具体错在什么地方也找不 出来。只好把代码贴出来,希望能通过“网聚天下人的力量”来解决问题。分数不多,以共同学习为目的。
代码:TABCButton.h
//------------------------------------------------------------------------#ifndef   ABCButtonH
#define   ABCButtonH
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
#include  
//---------------------------------------------------------------------------
enum   TTextStyle   {txNone,   txLowered,   txRaised,   txShadowed};
enum   TButtonShape   {shCapsule,   shOval,   shRectangle,   shRoundRect};

class   TABCButton   :   public   TGraphicControl
{
private:
        TColor   FButtonColor;
        bool   FIsDown;
        TColor   FFrameColor;
        int   FFrameWidth;
        int   FCornerRadius;
        HRGN   FRgn;
        HRGN   MRgn;
        TButtonShape   FShape;
        TColor   FTextColor;
        TTextStyle   FTextStyle;

        void   __fastcall   SetButtonColor(TColor   Value);
        MESSAGE   void   __fastcall   CMEnabledChanged(TMessage   &Message);
        MESSAGE   void   __fastcall   CMTextChanged(TMessage   &Message);
        MESSAGE   void   __fastcall   CMDialogChar(TCMDialogChar   &Message);
        MESSAGE   void   __fastcall   WMSize(TWMSize   &Message);
protected:
        BEGIN_MESSAGE_MAP
                MESSAGE_HANDLER(CM_ENABLEDCHANGED,   TMessage,   CMEnabledChanged)
                MESSAGE_HANDLER(CM_TEXTCHANGED,   TMessage,   CMTextChanged)
                MESSAGE_HANDLER(CM_DIALOGCHAR,   TCMDialogChar,   CMDialogChar)
                MESSAGE_HANDLER(WM_PAINT,   TWMSize,   WMSize)
                MESSAGE_HANDLER(WM_LBUTTONDOWN,   TWMLButtonDown,   WMLButtonDown)
                MESSAGE_HANDLER(WM_LBUTTONUP,   TWMMouse,   WMLButtonUp)
        END_MESSAGE_MAP(TGraphicControl);
protected:
DYNAMIC   void   __fastcall   Click(void);
        virtual   void   __fastcall   Paint(void);
        void   __fastcall   SetFrameColor(TColor   Value);
        void   __fastcall   SetFrameWidth(int   Value);
        void   __fastcall   SetCornerRadius(int   Value);
        void   __fastcall   SetShape(TButtonShape   Value);
        void   __fastcall   SetTextStyle(TTextStyle   Value);
        void   __fastcall   WMLButtonDown(TWMLButtonDown   &Message);
        void   __fastcall   WMLButtonUp(TWMMouse   &Message);
        void   __fastcall   DrawShape();
        void   __fastcall   WriteCaption();
public:
        virtual   __fastcall   TABCButton(TComponent*   Owner);
        virtual   __fastcall   ~TABCButton();

__published:
        __property   TColor   ButtonColor={read=FButtonColor,write=SetButtonColor};
        __property   Caption;
        __property   DragCursor;
        __property   DragMode;
        __property   Enabled;
        __property   Font;
        __property   TColor   FrameColor={read=FFrameColor,write=SetFrameColor};
        __property   int   FrameWidth={read=FFrameWidth,write=SetFrameWidth};
        __property   ParentFont;
        __property   ParentShowHint;
        __property   PopupMenu;
        __property   int   CornerRadius={read=FCornerRadius,write=SetCornerRadius};
        __property   TButtonShape   Shape={read=FShape,write=SetShape,default=shRoundRect};
        __property   ShowHint;
        __property   TTextStyle   TextStyle={read=FTextStyle,write=SetTextStyle};
        __property   Visible;
        __property   OnClick;
        __property   OnDragDrop;
        __property   OnDragOver;
        __property   OnEndDrag;
        __property   OnMouseDown;
        __property   OnMouseUp;
        __property   OnMouseMove;
};
#endif

回复于:2002-09-24 09:53:17 代码:TABCButton.CPP(第一部分)
//--------------------------------------------------------------
//---------------------------------------------------------------------------
#pragma   hdrstop
#include   "ABCButton.h "
//---------------------------------------------------------------------------
#pragma   package(smart_init)
namespace   Abcbutton
{
        void   __fastcall   PACKAGE   Register()
        {
                  TComponentClass   classes[1]   =   {__classid(TABCButton)};
                  RegisterComponents( "Samples ",   classes,   0);
        }
}
__fastcall   TABCButton::TABCButton(TComponent*   Owner)   :   TGraphicControl(Owner)
{
    TControlStyle   TmpCS;
    TmpCS <     ControlStyle=TmpCS;
    Enabled=true;
    FButtonColor=clBtnFace;
    FIsDown=false;
    FFrameColor=clGray;
    FFrameWidth=6;
    FCornerRadius=10;
    FRgn=0;
    FShape=shRoundRect;
    FTextStyle=txRaised;
    Height=25;
    Visible=true;
    Width=97;
}
__fastcall   TABCButton::~TABCButton()
{
    delete   FRgn;
    delete   MRgn;
}
void   __fastcall   TABCButton::Paint()
{
        int   Dia;
        TColor   ClrUp,   ClrDown;
        Canvas-> Brush-> Style=bsClear;
        if(FIsDown)
        {
                ClrUp=clBtnShadow;   ClrDown=clBtnHighlight;
        }else
        {
                ClrUp=clBtnHighlight;   ClrDown=clBtnShadow;
        }
        switch(FShape)
        {
                case   shRoundRect:
                {
                        Dia=2*CornerRadius;
                        MRgn=CreateRoundRectRgn(0,   0,   Width,   Height,   Dia,   Dia);
                        break;
                }
                case   shCapsule:
                {
                    if(Width                     else   Dia=Height;
                    MRgn=CreateRoundRectRgn(0,   0,   Width,   Height,   Dia,   Dia);
                    break;
                }
                case   shRectangle:
                {
                        MRgn=CreateRectRgn(0,   0,   Width-1,   Height-1);
                        break;
                }
                case   shOval:
                {
                        CreateEllipticRgn(0,   0,   Width,   Height);
                        break;
                }
        }
        Canvas-> Brush-> Color=FButtonColor;
        FillRgn(Canvas-> Handle,MRgn,   Canvas-> Brush-> Handle);
        Canvas-> Brush-> Color=ClrUp;
        FrameRgn(Canvas-> Handle,   MRgn,   Canvas-> Brush-> Handle,   1,   1);
        OffsetRgn(MRgn,   1,   1);
        Canvas-> Brush-> Color=ClrDown;
        FrameRgn(Canvas-> Handle,   MRgn,   Canvas-> Brush-> Handle,   1,   1);
        DrawShape();
        WriteCaption();
}
void   __fastcall   TABCButton::DrawShape()
{
        TColor   FC,   Warna;
        BYTE   R,   G,   B;
        int   AwalR,   AwalG,   AwalB,
        AkhirR,   AkhirG,   AkhirB,
        n,   t,   Dia;

    if(!(FFrameWidth%2))       t=FFrameWidth;
    else   t=FFrameWidth+1;

    Warna=(TColor)ColorToRGB(ButtonColor);
    FC=(TColor)ColorToRGB(FrameColor);
    Canvas-> Brush-> Color=Warna;

    //   gradient   preparation
    AwalR=GetRValue(FC);   AkhirR=GetRValue(Warna);
    AwalG=GetGValue(FC);   AkhirG=GetGValue(Warna);
    AwalB=GetBValue(FC);   AkhirB=GetBValue(Warna);
    FRgn=0;
    for(n=0;n     {
                R=AwalR+(int)(sqrt(t*t-sqrt(t-n))*(AkhirR-AwalR)/t);
                G=AwalG+(int)(sqrt(t*t-sqrt(t-n))*(AkhirG-AwalG)/t);
                B=AwalB+(int)(sqrt(t*t-sqrt(t-n))*(AkhirB-AwalB)/t);
                Canvas-> Brush-> Color=(TColor)RGB(R,   G,   B);
                switch(Shape)
                {
                        case   shOval:
                        {
                                FRgn=CreateEllipticRgn(1+n,   1+n,   Width-n,   Height-n);
                                break;
                        }
                        case   shRoundRect:
                        {
                                Dia=CornerRadius;
                                if((Dia-n)> 0)
                                        FRgn=CreateRoundRectRgn(1+n,   1+n,   Width-n,   Height-n,   2*(Dia-n),   2*(Dia-n));
                                else   FRgn=CreateRectRgn(1+n,   1+n,   Width-n-1,   Height-n-1);
                                break;
                        }
                        case   shCapsule:
                        {
                                if(Width                                 else   Dia=Height/2;
                                if   ((Dia-n)> 0)
                                        FRgn=CreateRoundRectRgn(1+n,   1+n,   Width-n,   Height-n,   2*(Dia-n),   2*(Dia-n));
                                else   FRgn=CreateRectRgn(1+n,   1+n,   Width-n-1,   Height-n-1);
                                break;
                        }
                }
                FrameRgn(Canvas-> Handle,   FRgn,   Canvas-> Brush-> Handle,   1,   1);
    }
}
void   __fastcall   TABCButton::WriteCaption()
{
        UINT   Flags;
        int   BtnL,   BtnT,   BtnR,   BtnB;
        TRect   R,   TR;

        R=ClientRect;
        TR=ClientRect;
        Canvas-> Font=Font;
        Canvas-> Brush-> Style=bsClear;
        Flags=DT_CENTER|DT_SINGLELINE;
        Canvas-> Font=Font;

        if(FIsDown)   FTextColor=FrameColor;
        else   FTextColor=Font-> Color;

        BtnT=(Height+Canvas-> TextHeight(Caption))/2;
        BtnB=BtnT+Canvas-> TextHeight(Caption);
        BtnL=(Width-Canvas-> TextWidth(Caption))/2;
        BtnR=BtnL+Canvas-> TextWidth(Caption);
        TR=Rect(BtnL,   BtnT,   BtnR,   BtnB);
        R=TR;
        if(((TextStyle==txLowered)   &&   FIsDown)   ||
              ((TextStyle==txRaised)   &&   !FIsDown))
        {
                Font-> Color=clHighlight;
                OffsetRect(TR,   -1+1,   -1+1);
                DrawText(Canvas-> Handle,   Caption.c_str(),   Caption.Length(),&TR,   Flags);
        }
        else   if(((TextStyle==txLowered)   &&   !FIsDown)||
                        ((TextStyle==txRaised)   &&   FIsDown))
        {
            Font-> Color=clBtnHighlight;
            OffsetRect(TR,   +2,   +2);
            DrawText(Canvas-> Handle,   Caption.c_str(),   Caption.Length(),   &TR,   Flags);
        }
        else   if   ((TextStyle==txShadowed)   &&   FIsDown)
        {
                Font-> Color=clBtnShadow;
                OffsetRect(TR,   3+1,   3+1);
                DrawText(Canvas-> Handle,   Caption.c_str(),   Caption.Length(),   &TR,   Flags);
        }
        else   if   ((TextStyle==txShadowed)   &&   (!FIsDown))
        {
                Font-> Color=clBtnShadow;
                OffsetRect(TR,   2+1,   2+1);
                DrawText(Canvas-> Handle,   Caption.c_str(),   Caption.Length(),   &TR,   Flags);
        }

        if(Enabled)   Font-> Color=FTextColor;
        else   if((TextStyle==txShadowed)   &&   (!Enabled))
                Font-> Color=clBtnFace;
        else   Font-> Color=clBtnShadow;

        if(FIsDown)   OffsetRect(R,   1,   1);
        else   OffsetRect(R,   -1,   -1);
        DrawText(Canvas-> Handle,   Caption.c_str(),Caption.Length(),   &R,   Flags);
}

回复于:2002-09-24 09:55:31 代码   ABCButton.cpp(第二部分)
//-----------------------------------------------------------------
void   __fastcall   TABCButton::SetButtonColor(TColor   Value)
{
        if(Value!=FButtonColor)
        {
                FButtonColor=Value;
                Invalidate();
        }
}
void   __fastcall   TABCButton::WMLButtonDown(TWMLButtonDown   &Message)
{
    if   (!PtInRegion(MRgn,   Message.XPos,   Message.XPos))   return   ;
    FIsDown=true;
    Paint();
    TGraphicControl::DefaultHandler(&Message);
//     Dispatch(&Message);
}
void   __fastcall   TABCButton::WMLButtonUp(TWMMouse   &Message)
{
    if(!FIsDown)   return;
    FIsDown=false;
    Paint();
    TGraphicControl::DefaultHandler(&Message);
//     Dispatch(&Message);
}
void   __fastcall   TABCButton::SetShape(TButtonShape   Value)
{
    if(Value!=FShape)
    {
        FShape=Value;
        Invalidate();
    }
}
void   __fastcall   TABCButton::SetTextStyle(TTextStyle   Value)
{
    if(Value!=FTextStyle)
    {
        FTextStyle=Value;
        Invalidate();
    }
}
void   __fastcall   TABCButton::SetFrameColor(TColor   Value)
{
    if(Value!=FFrameColor)
    {
        FFrameColor=Value;
        Invalidate();
    }
}
void   __fastcall   TABCButton::SetFrameWidth(int   Value)
{
        int   w;
        if(Width         else   w=Height;
        if(Value!=FFrameWidth)
                FFrameWidth=Value;
        if(FFrameWidth <4)
                FFrameWidth=4;
        if(FFrameWidth> (w/2))
                FFrameWidth=w/2;
        Invalidate();
}
void   __fastcall   TABCButton::SetCornerRadius(int   Value)
{
        int   w;
        if(Width                 w=Width;
        else   w=Height;
        if(Value!=FCornerRadius)
                FCornerRadius=Value;
        if(FCornerRadius <3)
                FCornerRadius=3;
        if(FCornerRadius> w)
                FCornerRadius=w;
        Invalidate();
}
void   __fastcall   TABCButton::CMEnabledChanged(TMessage   &Message)
{
    TGraphicControl::DefaultHandler(&Message);
    Invalidate();
}
void   __fastcall   TABCButton::CMTextChanged(TMessage   &Message)
{
    Invalidate();
}
void   __fastcall   TABCButton::CMDialogChar(TCMDialogChar   &Message)
{
        if(IsAccel(Message.CharCode,   Caption)   &&   Enabled)
        {
            Click();
            Message.Result=1;
        }
        else
        {
                ;
            TGraphicControl::DefaultHandler(&Message);
//     Dispatch(&Message);
        }
}
void   __fastcall   TABCButton::WMSize(TWMSize   &Message)
{
//         TGraphicControl::DefaultHandler(&Message);
        TGraphicControl::Dispatch(&Message);
        if(Message.Width> 145)       Width=145;
        if(Message.Height> 145)     Height=145;
}
void   __fastcall   TABCButton::Click(void)
{
    FIsDown=false;
    Invalidate();
    TControl::Click();
}


回复于:2002-09-24 15:43:35 为什么闪阿?因为有错误啊!

。。。。
嗬嗬,贴主忙着从delphi翻成BCB,却忘了With   Canvas的作用范围。恰恰Font属性是控件和Canvas共有的...
所以麽就死循环了...闪阿...

WriteCaption方法中...
if(((TextStyle==txLowered)   &&   FIsDown)   ||
              ((TextStyle==txRaised)   &&   !FIsDown))
        {
                Font-> Color=clHighlight;//错!   Canvas-> Font-> Color。。
下同。略去!
Inherited   视情况而定,如果在构造和析构时,不用再添足了...

DefaultHandler(&Message);是用来派发消息的吧...

回复于:2002-09-24 17:13:49 ysh   (大白菜)     :
帮你改好了。不再有闪烁。
这里已经很长了,不适合再贴,如何把程序给你





阅读(834) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~