同事演示了一个.NET的的PNG异形窗口.挺漂亮.于是也想用Delphi显摆一个.
关于Delphi用PNG做异形窗口的资料有不少.都是用GDIPlus或者TPNGImage组件加载PNG图像做的.但是我很懒,不想引用的GDIPlus,也不想去找PNGImage下载.
好在从Delphi2009开始Delphi中就收购了PNGImage,并集成到后继的版本中.Delphi2010又包装了微软的IWICImagingFactory接口,这样处理PNG的工作就交给操作系统去做了.
函数很简单一共就几行,关键就是UpdateLayeredWindow.
发现CodeGear真让我上火.他们收工了PNGImage以后搞的东西居然改出了问题.透明盒渐变都有问题.做异形窗口该渐变部分居然是透明的.该透明的部分居然是不透明的.看了一下被收购前的PNGImage一点问题都没有.CodeGear真实的.
只好用Delphi2010提供的IWICImagingFactory接口的包装了,这次PNG的处理交给微软的操作系统了,一点问题也没有.其他版本的Delphi只要能对IWICImagingFactory进行包装,也一样能处理.但还是Delphi2010最方便.什么控件也不用,多余的东西都不要.
代码如下,很简单吧:)
{*******************************************************} { } { 异形窗口 } { } { 2009.12.4 王 锐 } { } {*******************************************************}
unit UnitYXForm;
interface uses Windows, Forms, Classes, Graphics;
//从文件加载PNG procedure YXForm_FromFile(AForm : TForm; AFileName : String); //从资源加载PNG procedure YXForm_FromResource(AForm : TForm; ResName : String; ResType : PWideChar; Instance : HINST = 0); //从图像对象加载 procedure YXForm_FromGraphic(AForm : TForm; AGraphic : TGraphic);
implementation
procedure YXForm_FromFile(AForm : TForm; AFileName : String); var wic : TWICImage; begin wic := TWICImage.Create; wic.LoadFromFile(AFileName); YXForm_FromGraphic(AForm, wic); wic.Free; end;
procedure YXForm_FromResource(AForm : TForm; ResName : String;ResType : PWideChar; Instance : HINST); var wic : TWICImage; r : TResourceStream; begin if Instance = 0 then Instance := HInstance; r := TResourceStream.Create(Instance, ResName, ResType); wic := TWICImage.Create; wic.LoadFromStream(r);
YXForm_FromGraphic(AForm, wic); wic.Free; r.Free; end;
procedure YXForm_FromGraphic(AForm : TForm; AGraphic : TGraphic); var ptDst, ptSrc: TPoint; Size: TSize; BlendFunction: TBlendFunction; bmp : TBitmap; begin bmp := TBitmap.Create; bmp.Assign(AGraphic); ptDst := Point(AForm.Left, AForm.Top); ptSrc := Point(0, 0); Size.cx := AGraphic.Width; Size.cy := AGraphic.Height;
BlendFunction.BlendOp := AC_SRC_OVER; BlendFunction.BlendFlags := 0; BlendFunction.SourceConstantAlpha := $FF; // 透明度 BlendFunction.AlphaFormat := AC_SRC_ALPHA;
SetWindowLong(AForm.Handle, GWL_EXSTYLE, GetWindowLong(AForm.Handle, GWL_EXSTYLE) or WS_EX_LAYERED); UpdateLayeredWindow(AForm.Handle, AForm.Canvas.Handle, @ptDst, @Size, bmp.Canvas.Handle, @ptSrc, 0, @BlendFunction, ULW_ALPHA); bmp.Free(); end;
end.
想要用的时候很简单,举个例子:
ff := TForm2.Create(Self); YXForm_FromFile(ff, 'c:\a.png');
ff.Show;
实现动画也很容易.只要不停地YXForm_FromFile(ff, 'c:\a.png');调用一套动作PNG就可以了.
效果如下:
|
请发表评论