窗体的Alpha通道透明色支持(一旦 Form 被定义为利用 LayeredWindow ,窗口的绘图不再响应沿用多年的 WM_Paint 消息)
参考: 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函数更新这个位图即可!
http://www.csdn-123.com/html/itweb/20130902/94310_94299_94308.htm
窗体的Alpha通道透明色支持(一旦 Form 被定义为利用 LayeredWindow ,窗口的绘图不再响应沿用多年的 WM_Paint 消息)的更多相关文章
- 窗体的Alpha通道透明色支持
参考: http://www.delphibbs.com/delphibbs/dispq.asp?lid=2190768 Windows 2000后,为了支持类似MAC界面的Alpha通道混合效果,提 ...
- 什么是Alpha通道?
图像处理(Alpha通道,RGB,...)祁连山(Adobe 系列教程)****的UI课程 一个也许很傻的问题,在图像处理中alpha到底是什么? Alpha通道是计算机图形学中的术语,指的是特别的 ...
- RGBa颜色 css3的Alpha通道支持
CSS3中,RGBa 为颜色声明添加Alpha通道. RGB值被指定使用3个8位无符号整数(0 – 255)并分别代表红色.蓝色.和绿色.增加的一个alpha通道并不是一个颜色通道——它只是用来指定除 ...
- 如何基于纯GDI实现alpha通道的矢量和文字绘制
今天有人在QQ群里问GDI能不能支持带alpha通道的线条绘制? 大家的答案当然是否定的,很多人推荐用GDI+. 一个基本的图形引擎要包括几个方面的支持:位图绘制,文字绘制,矢量绘制(如矩形,线条). ...
- ImagXpress中如何修改Alpha通道方法汇总
ImagXpress支持处理Alpha通道信息来管理图像的透明度,Alpha通道支持PNG ,TARGA和TIFF文件,同时还支持BMP和ICO文件.如果说保存的图像样式不支持Alpha通道,就将会丢 ...
- ImageList半透明,Alpha通道bug处理。
由于ImageList的先天障碍,对alpha通道支持不好.虽然到xp有所改善,但瑕疵依然存在. 通过reflactor发现ImageList通过windows api来进行读写的.写入数据时会对原始 ...
- 关于Opengl中将24位BMP图片加入�一个alpha通道并实现透明的问题
#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...
- 关于Opengl中将24位BMP图片加入一个alpha通道并实现透明的问题
#include <windows.h>#include <GL/glut.h>#include <GL/glaux.h>#include <stdio.h& ...
- Alpha通道
Alpha通道是计算机图形学中的术语,指的是特别的通道,意思是“非彩色”通道,主要是用来保存选区和编辑选区.真正让图片变透明的不是Alpha 实际是Alpha所代表的数值和其他数值做了一次运算 为 ...
随机推荐
- C语言宏定义技巧
出处:http://blog.chinaunix.net/uid-14022540-id-2849095.html 1.宏中"#"和"##"的用法 一.一般用法 ...
- 演练5-7:Contoso大学校园管理系统(实现继承)
***操作视频下载:1 *** 在上一次教程中,你已经能够处理并发异常.这个教程将会展示如何在数据模型中实现继承. 在面向对象的程序设计中,你可以通过继承来清除冗余的代码.在这个教程中,你将要 ...
- iOS开发之自己封装一个progressHUD控件
看了几个轻量级的progress view 我觉得KVNProgress做的最漂亮吧 突然我想为什么我自己不封装一个控件 然后我研究了一下KVNProgress KVN简单的界面是由storyboar ...
- Qt信号槽的一些事(第一次知道信号还有返回值,以及Qt::UniqueConnection)
注:此文是站在Qt5的角度说的,对于Qt4部分是不适用的. 1.先说Qt信号槽的几种连接方式和执行方式. 1)Qt信号槽给出了五种连接方式: Qt::AutoConnection 0 自动连接:默认的 ...
- 【Unity 3D】使用 2DToolkit 插件 制作2D精灵动画
话说博客传图也太麻烦了吧,一个一个文件一个一个传....为什么不能直接粘贴了,自动上传呢... 刚直接粘贴了,结果一张图没有,又重新截一次图,在传了一次...真是太**了 好了,吐槽完了,开始博客吧 ...
- Java进阶02 异常处理
链接地址:http://www.cnblogs.com/vamei/archive/2013/04/09/3000894.html 作者:Vamei 出处:http://www.cnblogs.com ...
- Java Socket实现HTTP客户端来理解Session和Cookie的区别和联系
HTTP协议本身是无状态的,即使是同一台电脑同一个浏览器打开同一个页面两次,服务器不知道这两次请求是同一个客户端发送过来的,两次请求是完全独立的.例如,第一次请求时已经登录了,第二次再请求服务器会“忘 ...
- B4A的软件下载
http://pan.baidu.com/share/home?uk=909467506#category/type=0
- 关于android多点触控
最近项目需要一个多点触控缩放的功能.然后上网查了下资料 总结一下: 首先android sdk版本很重要,比如你在AndroidManifest.xml中指定android:minSdkVersion ...
- android录音功能的实现
这个录音实现是我在Bus上看到并下载的,他那个源码不完整,再次把我整理完整的代码贴出,源码地址在这:http://download.csdn.net/detail/chaozhung/5618649 ...