参考: http://www.delphibbs.com/delphibbs/dispq.asp?lid=2190768

Windows 2000后,为了支持类似MAC界面的Alpha通道混合效果,提供了GDI+,提供了很多的界面功能函数,可以实现很好的界面效果。例如可以使用UpdateLayeredWindow来实现窗体的颜色透明。但是一旦 Form 被定义为利用 LayeredWindow ,窗口的绘图不再响应沿用多年的 WM_Paint 消息。

UpdateLayeredWindow(hwnd:HWND; // 窗口句柄

hdcDst:HDC; // 目标 DC

ptDst:pPoint; // 目标的 TopLeft

Size:pSize; // 显示 Size

hdcSrc:HDC; // 源 DC

ptSrc:pPoint; // 源 DC 的 TopLeft

crKey:COLORREF; // 透明颜色值

Blend:pBlendFunction; // Alpha 混合函数

dwFlags:DWord // 一组标志位常量

);

这个函数不但可以设置 Alpha Blend ,还可以完成类似本例中的异形窗口显示。标志常量有以下几个:

ULW_COLORKEY = $00000001; // 透明颜色设置是需要的

ULW_ALPHA = $00000002; // Alpha 混合是需要的

ULW_OPAQUE = $00000004; // 保持不透明

不管设置哪些常量,首先与 SetLayeredWindowAttributes 函数一样,

需要对窗口设置一个新的扩展风格标志:WS_EX_LAYERED 。

设置窗口的扩展标志,只对 Windows2000 以上操作系统有效,设置方法与设置普

通窗口风格的方法一样:

SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle,GWL_EXSTYLE)

\or  WS_EX_LAYERED // 增加这个标志

);

注意:如果设置了Alpha 混合标志,必须提供 BlendFunction 的值。

PBlendFunction = ^TBlendFunction;

TBlendFunction = packed record

BlendOp: BYTE; // 取值可以为 AC_SRC_OVER

BlendFlags: BYTE; // 必须是 0

SourceConstantAlpha: BYTE; // 取值为希望得到的 Alpha 的值

AlphaFormat: BYTE;

end;

下面的代码演示如何实现窗体上面某个颜色为全透明,并可以穿透鼠标,效果图如下:

代码如下(Delphi 6):

procedure TForm1.FormCreate(Sender: TObject);

begin

Color := clWhite;

TransparentColor := True;

TransparentColorValue := clWhite;

end;

这个比较简单,但是实际上还是用的上面的函数,察看Forms.pas单元就知道了。当然也可以使用图片来做效果:即设计一张合适的图片,然后使用上面的方法即可作出一个不规则的图片窗体出来,非常简单!!

function UpdateLayeredWindow(hWnd: HWND;

hdcDst: HDC; Dst: PPoint; const size: PSize;

hdcSrc: HDC; Src: PPoint;

crKey: COLORREF;

pblend: PBlendFunction;

dwFlags: DWORD): BOOL; stdcall; external 'user32.dll';

procedure ColorUpdateLayeredWindow(Wnd: HWND; BMP: TBitmap; TransColor: TColor);

var

R: TRect;

S: TSize;

P: TPoint;

begin

GetWindowRect(Wnd, R);

P := Point(0, 0);

S.cx := Bmp.Width;

S.cY := Bmp.Height;

SetWindowLong(Wnd, GWL_EXSTYLE, GetWindowLong(Wnd, GWL_EXSTYLE) or WS_EX_LAYERED);

UpdateLayeredWindow(Wnd, 0, @R.TopLeft, @S, Bmp.Canvas.Handle, @P, TransColor, 0, ULW_COLORKEY);

end;

procedure AlphaUpdateLayeredWindow(Wnd: HWND; Bmp: TBitmap; Alpha: Byte);

var

P: TPoint;

R: TRect;

S: TSize;

BF: _BLENDFUNCTION;

begin

GetWindowRect(Wnd, R);

P := Point(0, 0);

S.cx := Bmp.Width;

S.cY := Bmp.Height;

bf.BlendOp := AC_SRC_OVER;

bf.BlendFlags := 0;

bf.SourceConstantAlpha := Alpha;

bf.AlphaFormat := AC_SRC_ALPHA;

SetWindowLong(wnd, GWL_EXSTYLE, GetWindowLong(wnd, GWL_EXSTYLE) or WS_EX_LAYERED);

UpdateLayeredWindow(wnd, 0, @R.TopLeft, @S, Bmp.Canvas.Handle, @P, 0, @BF, ULW_ALPHA);

end;

procedure TForm1.FormCreate(Sender: TObject);

var

BMP: TBitmap;

GB: TGPBitmap;

h: HBITMAP;

begin

Bmp := TBitmap.Create;

Bmp.LoadFromFile('F:\password.bmp');

//  GB := TGPBitmap.Create('F:\水晶图标\1.png');

//  GB.GetHBITMAP(0, h);

//  Bmp.Handle := h;

//  AlphaUpdateLayeredWindow(Handle, Bmp, 200);

ColorUpdateLayeredWindow(Handle, Bmp, Bmp.TransparentColor);

Bmp.Free;

//  GB.Free;

end;

使用上面得ColorLayeredWindow函数,就可以使BMP作为一个通透的窗口出来,上面的方式不支持Alpha混合,因此对PNG之类的支持不好。使用AlphaLayeredWindow可以支持Alpha通道。如果要支持PNG图片,可以使用GDI+,也可以使用TPNGObject来读取PNG图片,下面代码使用GDI+,需要使用GDIPAPI和GDIPObj两个单元,这两个单元Google一把到处可以找到。

使用上面的方法,窗体上面的控件都需要自己绘制,否则不可见了,但是实际上是在的,可以响应事件等。
 
可惜上面的方法不能使窗体的某些部分半透明,设置AlphaBlend和AlphaBlendValue又会使所有的窗体部分半透明,达不到要求的效果,而且那种透明效果不太好,不能实现Alpha通道效果。那么如何实现下面的效果呢?

要实现这个效果,不知道XDeskWeather是如何实现的,但是使用SGlass可以做到窗体透明效果。

procedure TForm1.FormCreate(Sender: TObject);

var

b : TBitmap;

h : HBITMAP;

gb: TGPBitmap;

begin

BorderStyle := bsNone;

Image1.Picture.LoadFromFile('F:\[2508]水晶图\[16]警告类\1.png');

with TStainedGlass.Create(Self) do

begin

AltTransparency := 100;

//BackStyle := bsCentered;

BackStyle := bsMosaic;

DelayTime := 1;

b := TBitmap.Create;

//    gb := tgpbitmap.Create('F:\[2508]水晶图\[16]警告类\1.png');

//    gb.GetHBITMAP(0, h);

//    b.Handle := h;

//Glyph := b;

end;

end;

需要GDIPlus和SGlass,PNGImage的支持,你也可以使用前面的GDI+的方法,这样不需要PNGImage。附件中有SGlass单元。

附:XDeskWeather使用了GDI+,采用了Raize控件和PNGImage,采用PNGImage里面的TPNGObject来支持PNG图片。PNGImage非常好用,和JPEG库类似,自己使用一下就知道了。XDeskWeather的透明效果是不是GDI+来实现的,问过作者,没有反应。  :-(

据说XDesk采取两个窗体来实现的,一个透明作为背景,另外一个是普通的窗体。

---------------------------------------

2005,6月10号又翻出来XDeskWeather看了一下,找到它的资源文件,于是又决心研究一下,发现点击它的About对话框的背景的时候,其设置对话框中的控件会失去焦点,这样很明显是两个不同的窗体才会出现的情况,因此决定按两个窗口的方式来实现一下,结果发现原来如此简单~~~~~~:两个窗口,一个背景,一个前台,控制同步移动即可!

结论:

使用Layer窗口,可以使用WM_PRINTCLIENT消息。最重要牢记一点:所有的窗口的更新都必须以图片方式提供给UpdateLayeredWindow函数!例如,你可以在你的窗口Active的时候,Move的时候,或者鼠标移动到你的控件的时候,在后台绘制一个图片,包括你的界面操作变化等,都需要更新图片,最后使用UpdateLayeredWindow函数更新这个位图即可!

窗体的Alpha通道透明色支持的更多相关文章

  1. 窗体的Alpha通道透明色支持(一旦 Form 被定义为利用 LayeredWindow ,窗口的绘图不再响应沿用多年的 WM_Paint 消息)

    参考: http://www.delphibbs.com/delphibbs/dispq.asp?lid=2190768 Windows 2000后,为了支持类似MAC界面的Alpha通道混合效果,提 ...

  2. RGBa颜色 css3的Alpha通道支持

    CSS3中,RGBa 为颜色声明添加Alpha通道. RGB值被指定使用3个8位无符号整数(0 – 255)并分别代表红色.蓝色.和绿色.增加的一个alpha通道并不是一个颜色通道——它只是用来指定除 ...

  3. 什么是Alpha通道?

    图像处理(Alpha通道,RGB,...)祁连山(Adobe 系列教程)****的UI课程 一个也许很傻的问题,在图像处理中alpha到底是什么?  Alpha通道是计算机图形学中的术语,指的是特别的 ...

  4. 如何基于纯GDI实现alpha通道的矢量和文字绘制

    今天有人在QQ群里问GDI能不能支持带alpha通道的线条绘制? 大家的答案当然是否定的,很多人推荐用GDI+. 一个基本的图形引擎要包括几个方面的支持:位图绘制,文字绘制,矢量绘制(如矩形,线条). ...

  5. ImagXpress中如何修改Alpha通道方法汇总

    ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...

  6. ImageList半透明,Alpha通道bug处理。

    由于ImageList的先天障碍,对alpha通道支持不好.虽然到xp有所改善,但瑕疵依然存在. 通过reflactor发现ImageList通过windows api来进行读写的.写入数据时会对原始 ...

  7. 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题

    #include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...

  8. 关于Opengl中将24位BMP图片加入一个alpha通道并实现透明的问题

    #include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...

  9. Alpha通道

     Alpha通道是计算机图形学中的术语,指的是特别的通道,意思是“非彩色”通道,主要是用来保存选区和编辑选区.真正让图片变透明的不是Alpha 实际是Alpha所代表的数值和其他数值做了一次运算  为 ...

随机推荐

  1. Ansible 插件 之 【CMDB】【转】

    Github地址: https://github.com/fboender/ansible-cmdb 从facts收集信息,生成主机概述 安装 wget https://github.com/fboe ...

  2. elasticsearch安装ik分词器(非极速版)

    1.下载下载地址为: https://github.com/medcl/elasticsearch-analysis-ik 2.解压把下载的 elasticsearch-analysis-ik.zip ...

  3. ZJOI2019爆蛋记

    Day-2 玩了一个下午,逛了填海校园,晚上吃肯德基 Day-1 上午听lyx巨佬讲课,讲到一半发现,越听越听不懂... 于是打开电脑开始刷知乎 下午听kcz孔爷讲课,emmmm电脑被我玩没电了... ...

  4. Gentoo rc-update service ‘net.eth0′ does not exist

    最近迷上了Gentoo,并相信以后也会把更多的精力放在Gentoo上,不过Gentoo的安装的过程的确让很多人却步. 本文只提到添加net.eth0到默认的运行级别时一个很小的报错解决. # nano ...

  5. ASP.NET应用技巧:非托管COM组件的使用

    众所周知,asp.net是基于通用语言运行库创建的,也就是所谓的托管执行环境.生成的代码称为托管代码.编译器能够从源代码的描述中产生元数据信息,而运行库又从元数据中获得托管代码的信息.而我们编写的组件 ...

  6. Python api认证

    本节内容: 基本的api 升级的api 终极版api 环境:Djanao, 项目名:api_auto, app:api 角色:api端,客户端,黑客端 1.基本的api [api端] #api_aut ...

  7. wpf 自定义控件展开popup,点击popup之外的部分,popup不能自动关闭

    比如textbox点击展开popup,这样popup也是不能自动关闭的.可能是textbox获得了焦点. 可是使用textblock,或者ToggleButton来代替textbox点击展开popup ...

  8. Vue(SPA) WebPack模块化打包、SEO优化(Vue SSR服务端同构直出)、全浏览器兼容完整解决方案

    白驹过隙,时光荏苒 大概去年这个时候写了angular 结合webpack的一套前端方案,今年此时祭出vue2结合webpack的一套前端方案. 明年的这个时候我又是在做什么... 读在最前面: 1. ...

  9. SqlServer中Sql查看存储过程

    ( 一)利用Sql语句查询数据库中的所有表 1.利用sysobjects系统表 select * from sysobjects where xtype='U'  2,利用sys.tables目录视图 ...

  10. Git(五)IDEA应用Git

    一.IDEA客户端git 1.提交代码到本地仓库 1. 关联Git,创建本地库 关联git 配置git环境变量 设置本地仓库目录,一般是IDEA工作空间,选择VCS->Import into V ...