使用VCL的Delphi按钮转换

时间:2019-04-17 15:34:21

标签: delphi vcl

是否可以使用Delphi和VCL进行过渡(例如,单击时红色按钮变为绿色)?类似于CSS过渡...

2 个答案:

答案 0 :(得分:2)

标准TButton不支持您的要求。默认情况下,它是从操作系统而不是VCL获取颜色的。

您需要一个所有者绘制的按钮来更改颜色,例如TBitBtnTSpeedBtn,否则您可以继承TButton来手动启用BS_OWNERDRAW窗口样式和处理WM_DRAWITEM通知。或使用第三者皮肤框架。或者,如果您的IDE支持VCL样式,则使用它们。

无论哪种方式,一旦有了一个可以改变颜色的按钮,就可以简单地使用TTimer来根据需要为从一种颜色到另一种颜色的动画设置动画。

答案 1 :(得分:2)

这是我进行的快速研究的结果

  • 首先,您需要从以下位置获取TAnimateEasing this sourceForge存储库。
  • 这本Answer用Java语言编写,讲述了如何从一种颜色变为另一种颜色。
  • 关于自定义TSpeedButton的Answer(我的)。

然后将所有这些结合起来就可以了

enter image description here

并且您可以看到我对Java答案的翻译不是那么好,但这将是一个不同的问题。您问如何转换按钮,这就是您的答案

unit NCRSpeedButton;

interface

uses
  Winapi.Windows, Vcl.Controls, Winapi.Messages, Vcl.Graphics, System.Classes, AnimateEasing;

type
  TButtonState = (bs_Down, bs_Normal, bs_Active);

  TNCRSpeedButton = class(TGraphicControl)
  private
    FEasingAnimation: TAnimateEasing;
    FColor: TColor;
    FFromColor : TColor;
    FToColor : TColor;
    FBorderColor: TColor;
    procedure CMMouseDown(var Message: TMessage); message WM_LBUTTONDOWN;
    procedure CMMouseUp(var Message: TMessage); message WM_LBUTTONUP;
    procedure SetBorderColor(aBorderColor: TColor);
    procedure SetFromColor(const Value: TColor);
    procedure SetToColor(const Value: TColor);
    procedure AnimateTickEvent(Sender: TObject; Value: Extended);
    procedure ANotifyEvent(Sender: TObject);
  protected
    procedure Paint; override;
  public
    Constructor Create(Owner: TComponent); override;
    Destructor Destroy; override;
  published
    property FromColor: TColor read FFromColor write SetFromColor;
    property ToColor: TColor read FToColor write SetToColor;
    property BorderColor: TColor read FBorderColor write SetBorderColor;
    property ParentShowHint;
    property ParentBiDiMode;
    property PopupMenu;
    property ShowHint;
    property Visible;
    property OnClick;
    property OnDblClick;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
  end;


implementation
 Uses
  System.Math,
  System.UITypes;


{ TNCRSpeedButton }

Constructor TNCRSpeedButton.Create(Owner: TComponent);
begin
  inherited Create(Owner);
  FColor := clBtnFace;
  FBorderColor := clBlue;
  SetBounds(0, 0, 200, 50);
  FEasingAnimation := TAnimateEasing.Create;
  FEasingAnimation.OnTick := AnimateTickEvent;
  FEasingAnimation.OnFinish := ANotifyEvent;
end;

Destructor TNCRSpeedButton.Destroy;
begin
  FEasingAnimation.Free;
  inherited;
end;

procedure TNCRSpeedButton.Paint;
begin

  Canvas.Brush.Color := FColor;
  Canvas.FillRect(ClientRect);

  // Drawing Borders

  Canvas.Pen.Color := FBorderColor;
  Canvas.MoveTo(0, 0);
  Canvas.LineTo(Width-1, 0);
  Canvas.LineTo(Width-1, Height-1);
  Canvas.LineTo(0, Height-1);
  Canvas.LineTo(0, 0);

end;

procedure TNCRSpeedButton.AnimateTickEvent(Sender: TObject; Value: Extended);
var
  Ratio: Integer;
begin
  Ratio := 1 - Floor(Value);

  TColorRec(FColor).R := Floor((Ratio  * TColorRec(FToColor).R) + ((1 - Ratio) * TColorRec(FFromColor).R));
  TColorRec(FColor).G := Floor((Ratio  * TColorRec(FToColor).G) + ((1 - Ratio) * TColorRec(FFromColor).G));
  TColorRec(FColor).B := Floor((Ratio  * TColorRec(FToColor).B) + ((1 - Ratio) * TColorRec(FFromColor).B));

  Invalidate;
end;

procedure TNCRSpeedButton.ANotifyEvent(Sender: TObject);
begin
  FColor := FToColor;
  Invalidate;
end;

procedure TNCRSpeedButton.CMMouseDown(var Message: TMessage);
begin
  inherited;
  Invalidate;
end;

procedure TNCRSpeedButton.CMMouseUp(var Message: TMessage);
begin
  inherited;
  Invalidate;
  FColor := FFromColor;

  FEasingAnimation.Animating(0, 500, 2000, TEasingType.etBackEaseIn);
end;

procedure TNCRSpeedButton.SetBorderColor(aBorderColor: TColor);
begin
  FBorderColor := aBorderColor;
  Invalidate;
end;

procedure TNCRSpeedButton.SetFromColor(const Value: TColor);
begin
  FColor := Value;
  FFromColor  := Value;
  Invalidate;
end;

procedure TNCRSpeedButton.SetToColor(const Value: TColor);
begin
  FToColor := Value;
  Invalidate;
end;

end. 

在转换过程中,我将保留如何解决黑色的问题:)。