使用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
使用GDI+绘制的360风格按钮控件(使用CN_DRAWITEM消息重绘,并使用TGPGraphics,TGPPen,TGPImage,TGPBitmap等)good的更多相关文章
- 使用GDI+绘制的360风格按钮控件
将下面的代码拷贝到一个单元中,创建一个包,加入这个单元后安装.使用的时候设置好背景颜色,边框颜色,图标(png格式)相对路径的文件名称.这个控件可以利用PNG图像的颜色透明特性,背景色默认透明度为50 ...
- MFC基于对话框风格按钮控件添加图片的方法(大神止步)
菜鸟还在研究这个东西,大神就不要看了.一直都在觉得用VC或VS建立的对话框总是全灰色感觉太单调了,如果可以在上面添加一些漂亮的图片就好了,今天终于实现了.其实挺简单的,下面就分几个步骤讲一下: 第一步 ...
- 关于CEdit控件的透明(重绘)
摘自:http://www.jcwcn.com/html/VC/10_19_51_12.htm 做一个透明的Edit控件的主要问题是字符的输出,在Edit里输出的刷新有几个时机,一个是在接收到键盘或鼠 ...
- dskinlite(uieasy mfc界面库)使用记录2:绘制动态元素(按钮控件绘制元素动态控制,改变图片和文字)
效果图:这4个分别是按钮按下后4种状态的效果 第88行是显示默认的按钮文字,没有id,SetWindowText改的就是它了 第87行是左边的图片,id是ico,可以通过程序控制 第89行是蓝色的文字 ...
- dskinlite(uieasy mfc界面库)使用记录3:绘制动态元素(按钮控件通过隐藏方式修改图片显示)
效果图: 分别是:正常,正常鼠标悬停,按下,按下鼠标悬停 XML代码: 75,76行定义了一个image,注意id和index属性 初始化代码: click代码: 147,148,153,154:通过 ...
- WinForm中的重绘 - 按钮等控件的背景渐变色重绘
注:brush通过起止坐标来控制重绘范围及方向.比如从上到下渐变时,brush第二个Point参数是左下角坐标. private void PaintGradientBackground(Button ...
- WPF自定义控件第二 - 转盘按钮控件
继之前那个控件,又做了一个原理差不多的控件.这个控件主要模仿百度贴吧WP版帖子浏览界面左下角那个弹出的按钮盘.希望对大家有帮助. 这个控件和之前的也差不多,为了不让大家白看,文章最后发干货. 由于这个 ...
- TCustomControl绘制自己和图形子控件共四步,TWinControl关键属性方法速记
TCustomControl = class(TWinControl) private FCanvas: TCanvas; procedure WMPaint(var Message: TWMPain ...
- Qt编写自定义控件11-设备防区按钮控件
前言 在很多项目应用中,需要根据数据动态生成对象显示在地图上,比如地图标注,同时还需要可拖动对象到指定位置显示,能有多种状态指示,安防领域一般用来表示防区或者设备,可以直接显示防区号,有多种状态颜色指 ...
随机推荐
- 快速傅里叶变换应用之二 hdu 4609 3-idiots
快速傅里叶变化有不同的应用场景,hdu4609就比较有意思.题目要求是给n个线段,随机从中选取三个,组成三角形的概率. 初始实在没发现这个怎么和FFT联系起来,后来看了下别人的题解才突然想起来:组合计 ...
- 纠错记录(Could not open the editor: Android XML Editor cannot process this input.)
Eclipse无法打开xml文件 preference->general->edit->file association->file types->选择.xml,然后在a ...
- linux下Python网络编程框架-Twisted安装
Twisted是python下的用来进行网络服务和应用程序编程的框架,安装Twisted前需要系统预先安装有python. 一.安装Twisted http://twistedmatrix.com/R ...
- Intent数据传递
(1)首先是Activity的简单跳转: 1).Activity的切换一般是通过Intent来实现的,Intent是一个Activity到达另一个Activity的引路者,它描述了起点(当前Activ ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...
- mysql中IN和EXITS效率
mysql中的in语句是把外表和内表作hash 连接.而exists语句是对外表作loop循环,每次loop循环再对内表进行查询.一直大家都觉得exists比in语句的效率要高.这样的说法事实上是不准 ...
- qingshow “不积跬步无以至千里,不积小流无以成江海”。--荀子《劝学篇》 用tomcat+花生壳搭建自己的web服务器+域名(参考)
链接地址:http://www.blogjava.net/qingshow/archive/2010/01/17/309846.html 用tomcat搭建web服务器 目标:免费拥有自己的网站及域名 ...
- 前端面试题整理(css)
1.介绍所知道的CSS hack技巧(如:_, *, +, \9, !important 之类). CSS hack的原理: 由于不同的浏览器和浏览器各版本对CSS的支持及解析结果不一样,以及CSS优 ...
- 它们偷偷干了啥?教你监督APP的运行
由于Android系统的开放性,很多APP都会在后台运行各种我们不知道的权限,不仅泄露我们隐私,也给系统本身带来极大安全隐患.而且现在很普遍的是,在安装APP时它总会索取特别多的权限,又是拍照又是地理 ...
- 开始着手Oracle中Scott用户的管理系统
准备好长时间,一直想把最近所学用于实践,正好想到Oracle的Scott用户的表设计还算合理,且自己也很熟悉,现将整个系统的架构设定如下: 1.数据库不用说,Oracle 11g 的 Scott 用户 ...