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

    线段树的合并..对于一个点x, 我们只需考虑是否需要交换左右儿子, 递归处理左右儿子. #include<bits/stdc++.h> using namespace std; #defi ...

  2. Java开发中常见的危险信号(上)

    本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...

  3. [转]PostgreSQL 中文资料汇总

    原文链接:http://francs3.blog.163.com/blog/static/405767272014017341219/ --1 中文社区网站  PostgreSQL 中文社区官网: h ...

  4. 【译】在Asp.Net中操作PDF – iTextSharp -利用块,短语,段落添加文本

    原文 [译]在Asp.Net中操作PDF – iTextSharp -利用块,短语,段落添加文本 本篇文章是讲述使用iTextSharp这个开源组件的系列文章的第三篇,iTextSharp可以通过As ...

  5. stm32智能小车之路之小车启动

           首先.安装完小车后最激动的还是想让他跑动,那么就開始吧.写个简单的程序測试下电机是否正常.打开keil软件新建一个project,详细简历keilproject不会的请百度.或者call ...

  6. Eclipse一个打开文件夹目录插件——Open In Explorer

    MyEclipse开发的都常用到其中一个"Open In Explorer"的小插件,可以直接在Windows资源管理器中打开选中文件所在的目录,工具虽小,但我们经常需要用到它 由 ...

  7. javascript每日一练(一)——javascript基础

    一.javascript的组成 ECMAScript DOM BOM 二.变量类型 常见类型有:number, string, boolean, undefined, object, function ...

  8. CodeFirst 表之间的关联

    多重性关系可以是Optional(一个属性可拥有一个单个实例或没有) Required(一个属性必须拥有一个单个实例) Many很多的(一个属性可以拥有一个集合或一个单个实例). Has方法包括如下几 ...

  9. IOS开发之UIView总结

    如果想调用某个类的某个方法可以写成这样,这个方法来自NSObject类 performSelector: performSelector:withObject: performSelector:wit ...

  10. AngularJS之WebAPi上传

    AngularJS之WebAPi上传(十)   前言 前面一系列我们纯粹是讲AngularJS,在讲一门知识时我们应该结合之前所学综合起来来做一个小的例子,前面我们讲了在MVC中上传文件的例子,在本节 ...