5,926
社区成员




unit Skin360Button;
interface
uses
Windows,SysUtils,Classes,Controls,StdCtrls,Messages,Graphics,
GdiPlus,GdiSkinHelper,GdiPlusHelpers,Math;
type
TSkin360Button=class(TCustomButton)
private
FMouseDown:Boolean;
FCanvas:TCanvas;
FParentBkGndBitmap:TBitmap;
FHoverPicture: TPicture;
FDownPicture: TPicture;
FHoverBitmap: IGPBitmap;
FDownBitmap: IGPBitmap;
FIconBitmap:IGPBitmap;
FIconPicture: TPicture;
FIconHeight: Integer;
FIconWidth: Integer;
procedure OnIconPictureChanged(Sender:TObject);
procedure OnHoverPictureChanged(Sender:TObject);
procedure OnDownPictureChanged(Sender:TObject);
procedure SetDownPicture(const Value: TPicture);
procedure SetHoverPicture(const Value: TPicture);
procedure MakeGPBitmapByPicture(var ABitmap: IGPBitmap; APicture: TPicture);
procedure SetIconPicture(const Value: TPicture);
procedure SetIconHeight(const Value: Integer);
procedure SetIconWidth(const Value: Integer);
protected
procedure Paint;virtual;
procedure PaintWindow(DC:HDC);
procedure WMPaint(var Message:TWMPaint);message WM_PAINT;
procedure WMEraseBkGnd(var Message:TWMEraseBkGnd);message WM_ERASEBKGND;
procedure WMLButtonDown(var Message:TMessage);message WM_LBUTTONDOWN;
procedure WMLButtonUp(var Message:TMessage);message WM_LBUTTONUP;
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
published
property HoverPicture:TPicture read FHoverPicture write SetHoverPicture;
property DownPicture:TPicture read FDownPicture write SetDownPicture;
property IconPicture:TPicture read FIconPicture write SetIconPicture;
property IconWidth:Integer read FIconWidth write SetIconWidth;
property IconHeight:Integer read FIconHeight write SetIconHeight;
published
property Action;
property Align;
property Anchors;
property BiDiMode;
property Cancel;
property Caption;
property CommandLinkHint;
property Constraints;
property Default;
property DisabledImageIndex;
property DoubleBuffered;
property DragCursor;
property DragKind;
property DragMode;
property DropDownMenu;
property ElevationRequired;
property Enabled;
property Font;
property HotImageIndex;
property ImageAlignment;
property ImageIndex;
property ImageMargins;
property Images;
property ModalResult;
property ParentBiDiMode;
property ParentDoubleBuffered;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property PressedImageIndex;
property SelectedImageIndex;
property ShowHint;
property Style;
property TabOrder;
property TabStop;
property Visible;
property WordWrap;
property OnClick;
property OnContextPopup;
property OnDragDrop;
property OnDragOver;
property OnDropDownClick;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseActivate;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
property OnStartDock;
property OnStartDrag;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('SkinEngine',[TSkin360Button]);
end;
{ TSkin360Button }
procedure DrawParentImageDefault(ASelf: TControl; DC: HDC);
var
SaveIndex: Integer;
P: TPoint;
begin
if ASelf.Parent=nil then Exit;
if Not (csDesigning in ASelf.ComponentState) then
begin
SaveIndex := SaveDC(DC);
GetViewportOrgEx(DC, P);
SetViewportOrgEx(DC, P.X - ASelf.Left, P.Y - ASelf.Top, nil);
IntersectClipRect(DC, 0, 0, ASelf.Parent.Width, ASelf.Parent.Height);
ASelf.Parent.Perform(WM_ERASEBKGND, DC, 0);
ASelf.Parent.Perform(WM_PrintClient, DC, prf_Client);
RestoreDC(DC, SaveIndex);
end;
end;
procedure TSkin360Button.MakeGPBitmapByPicture(var ABitmap:IGPBitmap;APicture:TPicture);
begin
if (APicture.Graphic=nil)
or APicture.Graphic.Empty then
begin
ABitmap:=nil;
end
else
begin
ABitmap:=TSkinHelper.CreateBitmap(APicture.Graphic)
end;
end;
constructor TSkin360Button.Create(AOwner: TComponent);
begin
inherited;
FHoverPicture:=TPicture.Create;
FDownPicture:=TPicture.Create;
FIconPicture:=TPicture.Create;
FHoverPicture.OnChange:=Self.OnHoverPictureChanged;
FDownPicture.OnChange:=Self.OnDownPictureChanged;
FIconPicture.OnChange:=Self.OnIconPictureChanged;
FParentBkGndBitmap:=TBitmap.Create;
FCanvas := TControlCanvas.Create;
TControlCanvas(FCanvas).Control := Self;
FIconHeight:=16;
FIconWidth:=16;
end;
destructor TSkin360Button.Destroy;
begin
FIconPicture.Free;
FHoverPicture.Free;
FDownPicture.Free;
FParentBkGndBitmap.Free;
FCanvas.Free;
inherited;
end;
procedure TSkin360Button.OnDownPictureChanged(Sender: TObject);
begin
MakeGPBitmapByPicture(FDownBitmap,FDownPicture);
end;
procedure TSkin360Button.OnHoverPictureChanged(Sender: TObject);
begin
MakeGPBitmapByPicture(FHoverBitmap,FHoverPicture);
end;
procedure TSkin360Button.OnIconPictureChanged(Sender: TObject);
begin
MakeGPBitmapByPicture(FIconBitmap,FIconPicture);
end;
procedure TSkin360Button.Paint;
var
tmpBitmap:IGPBitmap;
tmpIconDrawRect:TRect;
tmpCaptionDrawRect:TRect;
tmpGraphics:IGPGraphics;
begin
FParentBkGndBitmap.SetSize(Width,Height);
//绘制父控件到缓存位图
DrawParentImageDefault(Self,FParentBkGndBitmap.Canvas.Handle);
tmpBitmap:=nil;
if Self.FMouseDown then
begin
tmpBitmap:=Self.FDownBitmap;
end
else if Self.MouseInClient then
begin
tmpBitmap:=Self.FHoverBitmap;
end;
//绘制背景图片
if (tmpBitmap<>nil) then
begin
//九宫格绘制
TSkinHelper.StretchDrawImageInRectByMargins(FParentBkGndBitmap.Canvas.ToGPGraphics,
tmpBitmap,
TGPRect.Create(0,0,Width,Height),
8,8,8,8);
end;
//确定图标的绘制矩形
tmpIconDrawRect.Left:=Ceil((Width-Self.FIconWidth) / 2);
tmpIconDrawRect.Top:=5;
tmpIconDrawRect.Right:=tmpIconDrawRect.Left+Self.FIconWidth;
tmpIconDrawRect.Bottom:=tmpIconDrawRect.Top+Self.FIconHeight;
//绘制标题的绘制矩形
tmpCaptionDrawRect.Left:=Ceil((Width-TSkinHelper.CalcFontWidth(FParentBkGndBitmap.Canvas.ToGPGraphics,Caption,Font)) / 2);
tmpCaptionDrawRect.Top:=tmpIconDrawRect.Bottom+5;
tmpCaptionDrawRect.Right:=Width;
tmpCaptionDrawRect.Bottom:=Height;
//绘制标题
tmpGraphics:=FParentBkGndBitmap.Canvas.ToGPGraphics;
tmpGraphics.TextRenderingHint:=TGPTextRenderingHint.TextRenderingHintAntiAlias;
TSkinHelper.DrawShadowText(tmpGraphics,
Caption,Font,
tmpCaptionDrawRect.Left,
tmpCaptionDrawRect.Top,
3,0,
TGPColor.CreateFromColorRef(clWhite));
//绘制图标
TSkinHelper.StretchDrawImageInRect(FParentBkGndBitmap.Canvas.ToGPGraphics,
Self.FIconBitmap,
TGPRect.Create(tmpIconDrawRect));
//显示到界面上
Bitblt(FCanvas.Handle,0,0,Width,Height,
FParentBkGndBitmap.Canvas.Handle,0,0,SRCCOPY);
end;
procedure TSkin360Button.PaintWindow(DC: HDC);
begin
FCanvas.Lock;
try
FCanvas.Handle := DC;
try
TControlCanvas(FCanvas).UpdateTextFlags;
Paint;
finally
FCanvas.Handle := 0;
end;
finally
FCanvas.Unlock;
end;
end;
procedure TSkin360Button.SetDownPicture(const Value: TPicture);
begin
FDownPicture.Assign(Value);
Invalidate;
end;
procedure TSkin360Button.SetHoverPicture(const Value: TPicture);
begin
FHoverPicture.Assign(Value);
Invalidate;
end;
procedure TSkin360Button.SetIconHeight(const Value: Integer);
begin
if FIconHeight<>Value then
begin
FIconHeight := Value;
Invalidate;
end;
end;
procedure TSkin360Button.SetIconPicture(const Value: TPicture);
begin
FIconPicture.Assign(Value);
Invalidate;
end;
procedure TSkin360Button.SetIconWidth(const Value: Integer);
begin
if FIconWidth<>Value then
begin
FIconWidth := Value;
Invalidate;
end;
end;
procedure TSkin360Button.WMEraseBkGnd(var Message: TWMEraseBkGnd);
begin
Message.Result:=1;
end;
procedure TSkin360Button.WMLButtonDown(var Message: TMessage);
begin
Inherited;
Self.FMouseDown:=True;
Invalidate;
end;
procedure TSkin360Button.WMLButtonUp(var Message: TMessage);
begin
Inherited;
Self.FMouseDown:=False;
Invalidate;
end;
procedure TSkin360Button.WMPaint(var Message: TWMPaint);
var
DC: HDC;
PS: TPaintStruct;
begin
DC := Message.DC;
if DC = 0 then DC := BeginPaint(Handle, PS);
try
PaintWindow(DC);
finally
if Message.DC = 0 then EndPaint(Handle, PS);
end;
end;
end.