c++builder自绘按钮

想找自绘按钮的代码,找了很久,下载到了一个。作者不记得了。不过有点不完美。原代码没有处理,鼠标放在按钮上,按钮高亮显示功能。因此,增加了两个鼠标的CM_MOUSEENTERH和CM_MOUSELEAVE事件。

#ifndef Unit12H
#define Unit12H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>
#include <memory>
using namespace std;
//---------------------------------------------------------------------------
class TColorButton : public TButton
{
public:
  __fastcall TColorButton(TComponent* Owner);

__published:
  __property TColor Color   ={read = GetColor, write = SetColor};
  __property TColor ColorLo ={read = ColorLo_, write = SetColorLo,default = clBtnShadow};
  __property TColor ColorHi ={read = ColorHi_, write = SetColorHi,default = clBtnHighlight};
protected:
  // 继承的成员函数
  virtual void __fastcall CreateParams(TCreateParams& Params);
  virtual void __fastcall SetButtonStyle(bool ADefault);

  // 引入的成员函数
  virtual void __fastcall DoDrawButtonFace(const TOwnerDrawState& state);
  virtual void __fastcall DoDrawButtonText(const TOwnerDrawState& state);

private:

  TColor ColorLo_;
  TColor ColorHi_;
  std::auto_ptr<TCanvas> Canvas_;
  bool draw_as_default_;
  bool inButton;


  TColor __fastcall GetColor();
  void __fastcall SetColor(TColor Value);
  void __fastcall SetColorLo(TColor Value);
  void __fastcall SetColorHi(TColor Value);

  MESSAGE void __fastcall CNDrawItem(TMessage& Msg);
  MESSAGE void __fastcall WMLButtonDblClk(TMessage& Msg);
  MESSAGE void __fastcall CMFontChanged(TMessage& Msg);
  MESSAGE void __fastcall CMEnabledChanged(TMessage& Msg);
  MESSAGE void __fastcall CMmouseover(TMessage & Msg);
  MESSAGE void __fastcall CMmouseleave(TMessage & Msg);

  void __fastcall DrawImag(AnsiString path);
public:
  BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(CN_DRAWITEM, TMessage, CNDrawItem)
    MESSAGE_HANDLER(WM_LBUTTONDBLCLK, TMessage, WMLButtonDblClk)
    MESSAGE_HANDLER(CM_FONTCHANGED, TMessage, CMFontChanged)
    MESSAGE_HANDLER(CM_ENABLEDCHANGED, TMessage, CMEnabledChanged)
    VCL_MESSAGE_HANDLER(CM_MOUSEENTER, TMessage, CMmouseover)
    VCL_MESSAGE_HANDLER(CM_MOUSELEAVE, TMessage, CMmouseleave)
  END_MESSAGE_MAP(TButton)


};

void __fastcall TColorButton::CreateParams(TCreateParams& Params)
{
  TButton::CreateParams(Params);
  Params.Style |= BS_OWNERDRAW;
}

void __fastcall TColorButton::
  SetButtonStyle(bool ADefault)
{
  if (draw_as_default_ != ADefault)
  {
    draw_as_default_ = ADefault;
    InvalidateRect(Handle, NULL, FALSE);
  }
}

void __fastcall TColorButton::CNDrawItem(TMessage& Msg)
{
  // 获取 DRAWITEMSTRUCT
  const DRAWITEMSTRUCT* pDrawItem =reinterpret_cast<DRAWITEMSTRUCT*>(Msg.LParam);

  // 保存当前状态
  // 目标DC
  SaveDC(pDrawItem->hDC);
  // 绑定 Canvas_ 到目标 DC
  Canvas_->Handle = pDrawItem->hDC;
  try
  {
    // extract the state flags...
    TOwnerDrawState state;
    // 按钮具有键盘焦点
    if (pDrawItem->itemState & ODS_FOCUS)
    {
      state = state << odFocused;
    }
    // 已经按下
    if (pDrawItem->itemState &
        ODS_SELECTED)
    {
      state = state << odSelected;
    }
    // 按钮禁用
    if (pDrawItem->itemState &
        ODS_DISABLED)
    {
      state = state << odDisabled;
    }

    // 画按钮
    DoDrawButtonFace(state);

    // 画文本
    //DoDrawButtonText(state);
  }
  catch (...)
  {
    // clean up
    Canvas_->Handle = NULL;
    RestoreDC(pDrawItem->hDC, -1);
  }
  // clean up
  Canvas_->Handle = NULL;
  RestoreDC(pDrawItem->hDC, -1);

  // reply TRUE
  Msg.Result = TRUE;
}

void __fastcall TColorButton::DoDrawButtonFace(const TOwnerDrawState& state)
{
  //Brush->Style = bsClear;//绘图事件里,已对图片作透明处理,不须再处理
  Canvas_->Brush = Brush;

  TRect RClient = ClientRect;

  // 缺省按钮
  // 有键盘焦点...
  if (draw_as_default_ || state.Contains(odFocused))
  {
     DrawImag("UI\\down.bmp");
  }

  // 按下中...
  if (state.Contains(odSelected))
  {
      DrawImag("UI\\down.bmp");
  }

  // 按钮未按下...
  else
  {
      if(!inButton)//按钮normal
      {
         DrawImag("UI\\Normal.bmp");
      }
      else
      {
         DrawImag("UI\\over.bmp"); //鼠标在按钮上
      }
  }
}
//暂且未使用函数,图片代替,也可以启用,自绘文字
void __fastcall TColorButton::DoDrawButtonText(const TOwnerDrawState& state)
{
  if (Caption.Length() == 0) return;

  RECT RText = {0, 0, Width, Height};
  Canvas_->Font = Font;
  Canvas_->Brush = Brush;
  SetBkMode(
    Canvas_->Handle, TRANSPARENT
    );

  // 按钮按下...
  if (state.Contains(odSelected))
  {
     // 文件偏移
     OffsetRect(&RText, 1, 1);
  }
  // 按钮禁用...
  if (!Enabled || state.Contains(odDisabled))
  {
    // 重绘文字
    // 禁用时的文字
    OffsetRect(&RText, 1, 1);
    Canvas_->Font->Color = ColorHi_;
    DrawText(
      Canvas_->Handle, Caption.c_str(),
      -1, &RText, DT_CENTER |
      DT_VCENTER | DT_SINGLELINE
      );
    OffsetRect(&RText, -1, -1);
    Canvas_->Font->Color = ColorLo_;
  }

  if(inButton)
  {
    Canvas_->Font->Color = clYellow;
    DrawText(Canvas_->Handle, Caption.c_str(), -1,
    &RText, DT_CENTER | DT_VCENTER |
    DT_SINGLELINE
    );
  }
  else
  {
    Canvas_->Pen->Color = clRed;
    // 重绘文字
    DrawText(
      Canvas_->Handle, Caption.c_str(), -1,
      &RText, DT_CENTER | DT_VCENTER |
      DT_SINGLELINE
      );
   }
  // 键盘按下时的焦点...
  if (state.Contains(odFocused))
  {
    // 重绘选中时的矩形
    TRect RFocus = ClientRect;
    InflateRect(reinterpret_cast<TRect *>(&RFocus),-4, -4);
    Canvas_->DrawFocusRect(RFocus);
  }
}

TColor __fastcall TColorButton::GetColor()
{
  return Brush->Color;
}

void __fastcall TColorButton::SetColor(TColor Value)
{
  if (Brush->Color != Value)
  {
    Brush->Color = Value;
    InvalidateRect(Handle, NULL, TRUE);
  }
}

void __fastcall TColorButton::SetColorLo(TColor Value)
{
  if (ColorLo_ != Value)
  {
    ColorLo_ = Value;
    InvalidateRect(Handle, NULL, TRUE);
  }
}

void __fastcall TColorButton::SetColorHi(TColor Value)
{
  if (ColorHi_ != Value)
  {
    ColorHi_ = Value;
    InvalidateRect(Handle, NULL, TRUE);
  }
}

void __fastcall TColorButton::CMFontChanged(TMessage& Msg)
{
  TButton::Dispatch(&Msg);
  InvalidateRect(Handle, NULL, TRUE);
}

void __fastcall TColorButton::CMEnabledChanged(TMessage& Msg)
{
  TButton::Dispatch(&Msg);
  InvalidateRect(Handle, NULL, TRUE);
}

void __fastcall TColorButton::WMLButtonDblClk(TMessage& Msg)
{
  SNDMSG(Handle, WM_LBUTTONDOWN,Msg.WParam, Msg.LParam);
}
void __fastcall TColorButton::CMmouseover(TMessage & Msg)
{
      inButton = true;
      Repaint();
}
void __fastcall TColorButton::CMmouseleave(TMessage & Msg)
{
      inButton = false;
      Repaint();
}
void __fastcall TColorButton::DrawImag(AnsiString path)
{
        ::Graphics::TBitmap *bmp= new ::Graphics::TBitmap;
        bmp->Transparent = true;//是否透明
        bmp->LoadFromFile(path);
        Canvas_->Draw(0,0,bmp);
        delete bmp;
}
//---------------------------------------------------------------------------
#endif

调用方法如下:先准备3张图片,分别代码按钮正常、高亮、点击时的状态。即normal.bmp,over.bmp,down.bmp,
在当前运行目录中,建一个文件夹,名为UI,将这三张图片复制到文件夹中。
.h头文件如下:
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Buttons.hpp>

//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
        TButton *Button1;
        void __fastcall Button1Click(TObject *Sender);

private:	// User declarations
public:		// User declarations
        __fastcall TForm1(TComponent* Owner);

        void __fastcall myButton(TObject *Sender);//自绘按钮的事件

protected:

};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;

.cpp文件如下:

#include <vcl.h>
#pragma hdrstop
#include "ColorButton.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TColorButton *gButton;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
__fastcall TColorButton::TColorButton(TComponent* Owner)
         : TButton(Owner), ColorLo_(clBtnShadow), ColorHi_(clBtnHighlight),
          Canvas_(new TCanvas()),draw_as_default_(false)
{
}


void __fastcall TForm1::myButton(TObject *Sender)
{
   ShowMessage("按钮被点击");
}


void __fastcall TForm1::Button1Click(TObject *Sender)
{
   gButton = new TColorButton(Form1);

   gButton->Parent = Form1;
   
   gButton->Top=70;
   gButton->Left=50;
   gButton->Width = 345;
   gButton->Height = 42;
   gButton->Color=clGreen;
   gButton->Font->Name="宋体";
   gButton->Font->Size =9;
   gButton->Font->Color=clRed;
   gButton->Caption="按钮";
   gButton->OnClick = myButton;//自定义事件

}


扩展一下,可以改成CheckBox按钮,增加一个是否选中的属性,然后再准备3张,选中时显示的图片即可。
效果图如下:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值