使用GDI+绘制的360风格按钮控件(使用CN_DRAWITEM消息重绘,并使用TGPGraphics,TGPPen,TGPImage,TGPBitmap等)good

将下面的代码拷贝到一个单元中,创建一个包,加入这个单元后安装.使用的时候设置好背景颜色,边框颜色,图标(png格式)相对路径的文件名称.这个控件可以利用PNG图像的颜色透明特性,背景色默认透明度为50%,可以将按钮后面的内容显示出来.GDIPAPI, GDIPOBJ, GDIPUTIL三个单元可用万一的博客上寻找下载地址.

unit u360StyleButton;
  
interface  
  
uses  
  SysUtils, Classes, Controls, StdCtrls,Graphics, Messages, Windows,
  GDIPAPI, GDIPOBJ, GDIPUTIL;
  
type
  TBtn360Style = class(TButton)
  private
    FBkgColor: TColor; //鼠标悬停是的背景颜色
    FEdgColor: TColor; //边框颜色
    FCanvas: TCanvas;
    FMouseEnter: Boolean;
    FPngFileName: string;
    procedure CNDrawItem(var Message:TWMDrawItem);message CN_DRAWITEM;
    procedure SetPngFileName(const Value: string);
    procedure SetBkgColor(const Value: TColor);
    procedure SetEdgColor(const Value: TColor);
  protected
    procedure CreateParams(var Params:TCreateParams);override;
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure SetButtonStyle(ADefault:Boolean);override; //必须重新找个函数 否则会按默认样式绘制
  public
    constructor Create(AOwner:TComponent);override;  
    destructor Destroy;override;  
  published
    property PngFileName: string read FPngFileName write SetPngFileName;
    property BkgColor: TColor read FBkgColor write SetBkgColor;
    property EdgColor: TColor read FEdgColor write SetEdgColor;
  end;

procedure Register;  
  
implementation

constructor TBtn360Style.Create(AOwner: TComponent);   
begin   
  inherited Create(AOwner);
  DoubleBuffered := True;   
  FCanvas := TCanvas.Create;
  FBkgColor := clBlue;
  FEdgColor := clSkyBlue;
end;

destructor TBtn360Style.Destroy;   
begin   
  FCanvas.Free;
  inherited Destroy;   
end;

procedure TBtn360Style.CreateParams(var Params: TCreateParams);
begin   
  inherited CreateParams(Params);   
  with Params do Style := Style or BS_OWNERDRAW;   
end;
  
procedure TBtn360Style.SetEdgColor(const Value: TColor);
begin
  if FEdgColor <> Value then
  begin
    FEdgColor := Value;
    Invalidate;
  end;
end;

procedure TBtn360Style.SetBkgColor(const Value: TColor);
begin
  if FBkgColor <> Value then
  begin
    FBkgColor := Value;
    Invalidate;
  end;
end;

procedure TBtn360Style.SetButtonStyle(ADefault: Boolean);
begin
  if csDesigning in ComponentState then
    inherited;
end;

procedure TBtn360Style.SetPngFileName(const Value: string);
begin
  if FPngFileName <> Value then
  begin
    FPngFileName := Value;
    Invalidate;
  end;
end;

procedure TBtn360Style.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  FMouseEnter := True;
  Invalidate;
end;

procedure TBtn360Style.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  FMouseEnter := False;
  Invalidate;
end;

procedure TBtn360Style.CNDrawItem(var Message: TWMDrawItem);   
var   
  IsDown: Boolean;
  ARect: TRect;
  DrawItemStruct: TDrawItemStruct;
  wh:TSize;
  g: TGPGraphics;
  pen: TGPPen;
  img: TGPImage;
  img2: TGPBitmap;
  imgAtt: TGPImageAttributes;
  i, j:Integer;
const
  ColorMatrix: TColorMatrix = (
    (1.0, 0.0, 0.0, 0.0, 0.0),
    (0.0, 1.0, 0.0, 0.0, 0.0),
    (0.0, 0.0, 1.0, 0.0, 0.0),
    (0.0, 0.0, 0.0, 1.0, 0.0),
    (1.0, 0.0, 0.0, 0.0, 1.0));
begin
  DrawItemStruct:=Message.DrawItemStruct^;
  FCanvas.Handle := DrawItemStruct.hDC;
  g := TGPGraphics.Create(FCanvas.Handle);
  pen := TGPPen.Create(GDIPAPI.MakeColor(128, FEdgColor and $FF, (FEdgColor shr 8) and $FF, (FEdgColor shr 16) and $FF));
  img := TGPImage.Create(FPngFileName);
  img2 := TGPBitmap.Create(Width, Height);
  for i := 0 to img2.GetWidth do
    for j := 0 to img2.GetHeight do
    begin
      color := GDIPAPI.MakeColor(128, FBkgColor and $FF, (FBkgColor shr 8) and $FF, (FBkgColor shr 16) and $FF);
      img2.SetPixel(i, j, color);
    end;
  ARect := ClientRect;
  with DrawItemStruct do
    IsDown := itemState and ODS_SELECTED <> 0;
  if FMouseEnter then   //鼠标在按钮上 则绘制一个背景及边框
  begin
    Perform($000B, 0, 0);
    g.DrawImage(img2, 0, 0, Width, Height);
    g.DrawRectangle(pen, 0, 0, Width - 1, Height - 1);
    Perform($000B, 1, 0);
  end;
  //按钮被按下时的状态绘制
  if IsDown then
  begin
    imgAtt := TGPImageAttributes.Create;
    imgAtt.SetColorMatrix(ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeDefault);
    g.DrawImage(img, MakeRect(0, 0, img.GetWidth, img.GetHeight),
                -10, -10, img.GetWidth + 10, img.GetHeight + 10, UnitPixel, imgAtt);
    FreeAndNil(imgAtt);
  end
  else  //绘制一个未按下的按钮
    g.DrawImage(img, (Width - img.GetWidth) div 2, 10);
  FreeAndNil(img);
  FreeAndNil(img2);
  FreeAndNil(g);
  FreeAndNil(pen);

//绘制Caption文本内容    
  FCanvas.Font := Self.Font;   
  ARect:=ClientRect;   
  wh:=FCanvas.TextExtent(Caption);   
  FCanvas.Pen.Width := 1;   
  FCanvas.Brush.Style := bsClear;   
  if not Enabled then   
  begin //按钮失效时应多绘一次Caption文本    
    FCanvas.Font.Color := clBtnHighlight;   
    FCanvas.TextOut((Width div 2)-(wh.cx div 2), height - wh.cy - 10,Caption);   
    FCanvas.Font.Color := clBtnShadow;   
  end
  else
    FCanvas.TextOut((Width div 2)-(wh.cx div 2), height - wh.cy - 10,Caption);
  FCanvas.Handle := 0;
end;

procedure Register;
begin
  RegisterComponents(‘HenreashPackages‘, [TBtn360Style]);
end;

end.

http://blog.csdn.net/henreash/article/details/7571660

时间: 2024-08-09 14:52:01

使用GDI+绘制的360风格按钮控件(使用CN_DRAWITEM消息重绘,并使用TGPGraphics,TGPPen,TGPImage,TGPBitmap等)good的相关文章

关于CEdit控件的透明(重绘)

摘自:http://www.jcwcn.com/html/VC/10_19_51_12.htm 做一个透明的Edit控件的主要问题是字符的输出,在Edit里输出的刷新有几个时机,一个是在接收到键盘或鼠标消息的时候 ,还有就是在接收到WM_PAINT消息.刷新的时候也不是全部重画,所以想通过在继承的Edit类中处理WM_PAINT消息是行不通的.但是Edit控件自己总是知道怎么去刷新,因此只要给控件发消息,让其自己来刷新就可以了.通过使用spy++的得知需要刷新有几个时机,一个是按键的时候,内容变

dskinlite(uieasy mfc界面库)使用记录2:绘制动态元素(按钮控件绘制元素动态控制,改变图片和文字)

效果图:这4个分别是按钮按下后4种状态的效果 第88行是显示默认的按钮文字,没有id,SetWindowText改的就是它了 第87行是左边的图片,id是ico,可以通过程序控制 第89行是蓝色的文字,id是type,可以通过程序控制 下面是程序示例:

WinForm中按钮等控件的背景渐变色重绘

注:brush通过起止坐标来控制重绘范围及方向.比如从上到下渐变时,brush第二个Point参数是左下角坐标. 1 private void PaintGradientBackground(Button btn) 2 { 3 Bitmap newGradientBackImg = new Bitmap(btn.Width, btn.Height); 4 LinearGradientBrush brush = new LinearGradientBrush(new PointF(0, 0), n

第三章 按钮控件的创建

一.前言 不知不觉一晃两个月过去,说来惭愧,在此期间alterto一直没有再研究DuiEngine.主要是因为DuiEngine的作者现在构建一个新的界面库soui,而笔者也一直处于观望状态,因为DuiEngine的作者说了以后可能就不维护DuiEngine了,要把主要的经历放在SOUI上.alterto顿时犹豫了,既然这样我还为DuiEngine做什么教程啊.于是这两个月的时间里一直都很犹豫,也没有再出DuiEngine相关的教程.现在看来这种焦躁对于一个优秀的程序猿来说着实不应该,这也正暴露

UIButton 按钮控件

文章出处:http://blog.csdn.net/iukey UIButton是一个标准的UIControl控件,所以如果你对UIControl不甚了解还是先看一下我的另一篇博文:<UIControl IOS控件编程> 一.创建 两种方法: 1. 常规的 initWithFrame UIButton *btn1 = [[UIButton alloc]initWithFrame:CGRectMake(10, 10, 80, 44)]; 对代码创建View(UIControl继承自UIView,

自定义水晶按钮控件

namespace 自定义水晶按钮控件 { partial class Form1 { /// <summary> /// 必需的设计器变量. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源. /// </summary> /// <param name="disposing&quo

(转载)VS2010/MFC编程入门之二十二(常用控件:按钮控件Button、Radio Button和Check Box)

因为私人问题,鸡啄米暂停更新了几天,首先向关注鸡啄米动态的朋友说一声抱歉. 言归正传,鸡啄米上一节中讲了编辑框的用法,本节继续讲解常用控件--按钮控件的使用. 按钮控件简介 按钮控件包括命令按钮(Button).单选按钮(Radio Button)和复选框(Check Box)等.命令按钮就是我们前面多次提到的狭义的按钮控件,用来响应用户的鼠标单击操作,进行相应的处理,它可以显示文本也可以嵌入位图.单选按钮使用时,一般是多个组成一组,组中每个单选按钮的选中状态具有互斥关系,即同组的单选按钮只能有

andorid 控件 Bootstrap3.0风格的控件 精美UI控件库

Bootstrap是Twitter推出的一个开源的用于前端开发的工具包.它由Twitter的设计师Mark Otto和Jacob Thornton合作开发,是一个CSS/HTML框架.Bootstrap提供了优雅的HTML和CSS规范,它即是由动态CSS语言Less写成.Bootstrap一经推出后颇受欢迎,一直是GitHub上的热门开源项目,包括NASA的MSNBC(微软全国广播公司)的Breaking News都使用了该项目.在逛github的时候,发现有位牛人做成 android版的 bo

iOS: 工具栏控件UIToolBar和工具栏按钮控件UIBarButtonItem的使用

一.工具栏控件:UIToolBar:UIView 介绍: ToolBar工具栏是视图View的属性,可以在工具栏上添加工具栏按钮Bar Button Item(可以是自定义的Custom.也可以是系统自带的BarButtonSystemItem ),视图控制器可以通过工具栏项对视图中内容进行操作. 注意事项: 在导航栏控制器中会有一个UIToolBar实例,但默认是隐藏的,如果需要显示,需要通过这个方法将其打开: 在这里需要注意的是,与UINavigationBar类似,导航控制器拥有且只拥有一