delphi 水晶按钮

unit CrystalButton;

interface

uses
  SysUtils, Classes, Windows, Messages, Graphics, Controls, StdCtrls, Forms;
type
  PTriVertex = ^TTriVertex;
  TTriVertex = packed record
    x: Longint;
    y: Longint;
    Red: Word;
    Green: Word;
    Blue: Word;
    Alpha: Word;
  end;

  TFillDir = (fdHorizontal, fdVertical);
type
  TCrystalButton = class(TGraphicControl)
  private
    FMouseOver: Boolean;
    FDown: Boolean;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  protected
    procedure Paint; override;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;

    procedure GetRGB(C: TColor; out R, G, B: Integer);
    procedure SolidGradient(DC: HDC; Rect: TRect; Color1, Color2,Color3: TColor; Dir: TFillDir = fdVertical); overload;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Click; override;
  published
    property Caption;
    property Enabled;
    property Font;
    property OnClick;
    property OnMouseDown;
    property OnMouseMove;
    property OnMouseUp;
    property Height;
    property Width;
    property Left;
    property Top;
    property Name;
    property Visible;
    property Cursor;
  end;

procedure Register;

implementation

//uses uGradientFill;
function GradientFillEx(DC: HDC; Vertex: PTriVertex; NumVertex: ULONG; Mesh: Pointer; NumMesh, Mode: ULONG): BOOL; stdcall; external msimg32 name 'GradientFill';
//function GradientFillEx;
procedure ods(const str: string);
begin
  OutputDebugString(PChar(str));
end;

{ TButtonEx }

procedure TCrystalButton.Click;
begin
  inherited Click;
end;

procedure TCrystalButton.CMMouseEnter(var Message: TMessage);
begin
  FMouseOver := True;
  Repaint;
  if Parent <> nil then
    Parent.Perform(CM_MOUSEENTER, 0, Longint(Self));
end;

procedure TCrystalButton.CMMouseLeave(var Message: TMessage);
begin
  FMouseOver := False;
  if FDown then
    FDown := False;
  Repaint;
  if Parent <> nil then
    Parent.Perform(CM_MOUSELEAVE, 0, Longint(Self));
end;

constructor TCrystalButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := [csCaptureMouse, csDoubleClicks];
  ParentFont := True;
end;

procedure TCrystalButton.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
begin
  inherited MouseDown(Button, Shift, X, Y);
  if (Button = mbLeft) and Enabled then
  begin
    if not FDown then
    begin
      FDown := True;
      repaint;
    end;
  end;
end;

procedure TCrystalButton.MouseUp(Button: TMouseButton; Shift: TShiftState; X,
  Y: Integer);
var
  pt: TPoint;
  Rect: TRect;
  DoClick: Boolean;
begin
  inherited MouseUp(Button, Shift, X, Y);
  if FDown then
  begin
    pt.X := X;
    pt.Y := Y;
    Rect := ClientRect;
    DoClick := PtInRect(Rect, pt);
    if DoClick then
    begin
      FDown := False;
      repaint;
    end;
    if DoClick then Click;
  end;
end;

procedure TCrystalButton.Paint;
var
  Rect: TRect;
  clr1, clr2,clr3: TColor;
begin
  Rect := ClientRect;
  Canvas.Brush.Style := bsClear;
  Canvas.Pen.Color := RGB(85, 148, 22);
  Canvas.RoundRect(Rect.Left, Rect.Top, Rect.Right, Rect.Bottom, 6, 6);

  if FDown then
  begin
      InflateRect(Rect, -1, -1);
      clr3 := RGB($ef,$9a, $90);
      clr2 := RGB($ff,$ff, $ff );
      clr1 := RGB($ef,$9a, $90);
      SolidGradient(Canvas.Handle, Rect, clr1, clr2,clr3);
  end
  else
  begin
    if FMouseOver then
    begin

      InflateRect(Rect, -1, -1);
      clr3 := RGB($66, $cc,$99);
      clr2 := RGB($66, $cc,$99);
      clr1 := RGB($ff,$ff, $ff );
      SolidGradient(Canvas.Handle, Rect, clr1, clr2,clr3);
    end
    else
    begin
      InflateRect(Rect, -1, -1);
      clr3 := RGB($33, $cc,$99);
      clr2 := RGB($33, $cc,$99);
      clr1 := RGB($ff,$ff, $ff);
      SolidGradient(Canvas.Handle, Rect, clr1, clr2,clr3);
    end
  end;

 // Canvas.Font.Color := clBlack;//clWhite;
 // Canvas.Font.Style := [fsBold];
  Canvas.Font:=self.Font;
  DrawText(Canvas.Handle, PChar(Caption), -1, Rect, DT_SINGLELINE or DT_CENTER or DT_VCENTER);
end;

procedure TCrystalButton.GetRGB(C: TColor; out R, G, B: Integer);
begin
  if Integer(C) < 0 then C := GetSysColor(C and $000000FF);
  R := C and $FF;
  G := C shr 8 and $FF;
  B := C shr 16 and $FF;
end;

procedure TCrystalButton.SolidGradient(DC: HDC; Rect: TRect; Color1, Color2,Color3: TColor; Dir: TFillDir = fdVertical);
var
  vert: array[0..3] of TTriVertex;
  gRect:array[0..1] of TGradientRect;
  nMode: Cardinal;
begin
  vert[0].x := Rect.Left;
  vert[0].y := Rect.Top;
  vert[0].Red := GetRValue(Color1) shl 8;
  vert[0].Green := GetGValue(Color1) shl 8;
  vert[0].Blue := GetBValue(Color1) shl 8;
  vert[0].Alpha := 0;

  vert[1].x := Rect.Right;
  vert[1].y := Rect.Bottom div 2;
  vert[1].Red := GetRValue(Color2) shl 8;
  vert[1].Green := GetGValue(Color2) shl 8;
  vert[1].Blue := GetBValue(Color2) shl 8;
  vert[1].Alpha := 0;
  
  vert[2].x := Rect.Left;
  vert[2].y := Rect.Bottom div 2;
  vert[2].Red := GetRValue(Color2) shl 8;
  vert[2].Green := GetGValue(Color2) shl 8;
  vert[2].Blue := GetBValue(Color2) shl 8;
  vert[2].Alpha := 0; 
  
  vert[3].x := Rect.Right;//Right;
  vert[3].y := Rect.Bottom;
  vert[3].Red := GetRValue(Color3) shl 8;
  vert[3].Green := GetGValue(Color3) shl 8;
  vert[3].Blue := GetBValue(Color3) shl 8;
  vert[3].Alpha := 0;

  gRect[0].UpperLeft := 0;
  gRect[0].LowerRight := 1;
  gRect[1].UpperLeft := 2;
  gRect[1].LowerRight := 3;
  if Dir = fdVertical then
    nMode := GRADIENT_FILL_RECT_V
  else
    nMode := GRADIENT_FILL_RECT_H;
    
  GradientFillEx(DC, @vert, 4, @gRect, 2, nMode);
end;
procedure Register;
begin
  RegisterComponents('Samples', [TCrystalButton]);
end;

end.
 

显示效果如下

 

转载于:https://my.oschina.net/jingshishengxu/blog/684158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值