将下面的代码拷贝到一个单元中,创建一个包,加入这个单元后安装.使用的时候设置好背景颜色,边框颜色,图标(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

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

  1. 使用GDI+绘制的360风格按钮控件

    将下面的代码拷贝到一个单元中,创建一个包,加入这个单元后安装.使用的时候设置好背景颜色,边框颜色,图标(png格式)相对路径的文件名称.这个控件可以利用PNG图像的颜色透明特性,背景色默认透明度为50 ...

  2. MFC基于对话框风格按钮控件添加图片的方法(大神止步)

    菜鸟还在研究这个东西,大神就不要看了.一直都在觉得用VC或VS建立的对话框总是全灰色感觉太单调了,如果可以在上面添加一些漂亮的图片就好了,今天终于实现了.其实挺简单的,下面就分几个步骤讲一下: 第一步 ...

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

    摘自:http://www.jcwcn.com/html/VC/10_19_51_12.htm 做一个透明的Edit控件的主要问题是字符的输出,在Edit里输出的刷新有几个时机,一个是在接收到键盘或鼠 ...

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

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

  5. dskinlite(uieasy mfc界面库)使用记录3:绘制动态元素(按钮控件通过隐藏方式修改图片显示)

    效果图: 分别是:正常,正常鼠标悬停,按下,按下鼠标悬停 XML代码: 75,76行定义了一个image,注意id和index属性 初始化代码: click代码: 147,148,153,154:通过 ...

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

    注:brush通过起止坐标来控制重绘范围及方向.比如从上到下渐变时,brush第二个Point参数是左下角坐标. private void PaintGradientBackground(Button ...

  7. WPF自定义控件第二 - 转盘按钮控件

    继之前那个控件,又做了一个原理差不多的控件.这个控件主要模仿百度贴吧WP版帖子浏览界面左下角那个弹出的按钮盘.希望对大家有帮助. 这个控件和之前的也差不多,为了不让大家白看,文章最后发干货. 由于这个 ...

  8. TCustomControl绘制自己和图形子控件共四步,TWinControl关键属性方法速记

    TCustomControl = class(TWinControl) private FCanvas: TCanvas; procedure WMPaint(var Message: TWMPain ...

  9. Qt编写自定义控件11-设备防区按钮控件

    前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...

随机推荐

  1. 快速傅里叶变换应用之二 hdu 4609 3-idiots

    快速傅里叶变化有不同的应用场景,hdu4609就比较有意思.题目要求是给n个线段,随机从中选取三个,组成三角形的概率. 初始实在没发现这个怎么和FFT联系起来,后来看了下别人的题解才突然想起来:组合计 ...

  2. 纠错记录(Could not open the editor: Android XML Editor cannot process this input.)

    Eclipse无法打开xml文件 preference->general->edit->file association->file types->选择.xml,然后在a ...

  3. linux下Python网络编程框架-Twisted安装

    Twisted是python下的用来进行网络服务和应用程序编程的框架,安装Twisted前需要系统预先安装有python. 一.安装Twisted http://twistedmatrix.com/R ...

  4. Intent数据传递

    (1)首先是Activity的简单跳转: 1).Activity的切换一般是通过Intent来实现的,Intent是一个Activity到达另一个Activity的引路者,它描述了起点(当前Activ ...

  5. WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]

    原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...

  6. mysql中IN和EXITS效率

    mysql中的in语句是把外表和内表作hash 连接.而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都觉得exists比in语句的效率要高.这样的说法事实上是不准 ...

  7. qingshow “不积跬步无以至千里,不积小流无以成江海”。--荀子《劝学篇》 用tomcat+花生壳搭建自己的web服务器+域名(参考)

    链接地址:http://www.blogjava.net/qingshow/archive/2010/01/17/309846.html 用tomcat搭建web服务器 目标:免费拥有自己的网站及域名 ...

  8. 前端面试题整理(css)

    1.介绍所知道的CSS hack技巧(如:_, *, +, \9, !important 之类). CSS hack的原理: 由于不同的浏览器和浏览器各版本对CSS的支持及解析结果不一样,以及CSS优 ...

  9. 它们偷偷干了啥?教你监督APP的运行

    由于Android系统的开放性,很多APP都会在后台运行各种我们不知道的权限,不仅泄露我们隐私,也给系统本身带来极大安全隐患.而且现在很普遍的是,在安装APP时它总会索取特别多的权限,又是拍照又是地理 ...

  10. 开始着手Oracle中Scott用户的管理系统

    准备好长时间,一直想把最近所学用于实践,正好想到Oracle的Scott用户的表设计还算合理,且自己也很熟悉,现将整个系统的架构设定如下: 1.数据库不用说,Oracle 11g 的 Scott 用户 ...