终于找到了完美的透明窗口源代码,不过是c#的,有谁为大家造福,翻译成delphi!!(50分)

  • 主题发起人 wujingping
  • 开始时间
98 肯定是不行的!本人99年就放弃98改用NT了。<br>本人不保留,全贴出来了,刚改了一个比较大的bug,内存会直线上升,现在好了。<br>最好在有代码着色的工具里面看。一点保留都没有了!!<br><br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls, ExtCtrls, Menus, gdipapi, gdipobj; //最后两个是 GDI+ 引擎<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Timer1: TTimer;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormDestroy(Sender: TObject);<br>&nbsp; &nbsp; Procedure MoveForm(var M:TWMNCHITTEST); Message WM_NCHITTEST;<br>&nbsp; &nbsp; procedure Timer1Timer(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>const<br>&nbsp; WS_EX_LAYERED = $80000;<br>&nbsp; LWA_COLORKEY &nbsp;= 1;<br>&nbsp; LWA_ALPHA &nbsp; &nbsp; = 2;<br>&nbsp; ULW_COLORKEY &nbsp;= 1;<br>&nbsp; ULW_ALPHA &nbsp; &nbsp; = 2;<br>&nbsp; ULW_OPAQUE &nbsp; &nbsp;= 4;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; bmp, old_bmp : HBITMAP;<br>&nbsp; DC : HDC;<br>&nbsp; bitmap:array[1..15] of tgpbitmap;<br>&nbsp; j:integer;<br><br>Function UpdateLayeredWindow(hWnd : HWND;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hdcDst : HDC; pptDst : PPoint; psize : PSize;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hdcSrc : HDC; pptSrc : PPoint;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; crKey &nbsp;: COLORREF;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pblend : PBlendFunction;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dwFlags : DWORD): BOOL; stdcall;<br><br>implementation<br><br>{$R *.dfm}<br><br>Function UpdateLayeredWindow; external 'user32.dll';<br><br>Procedure TForm1.MoveForm (var M:TWMNCHITTEST); // 移动无标题窗口用的<br>begin<br>&nbsp;//继承,窗体可以继续处理以后的事件<br>&nbsp; inherited;<br>&nbsp; M.Result:=HTCAPTION;<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>&nbsp; &nbsp;i : integer;<br>begin<br>//-------为窗口添加必要的属性 WS_EX_LAYERED<br>&nbsp; if SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED) = 0 then ShowMessage(SysErrorMessage(GetLastError)); <br>&nbsp; &nbsp;//----调入15张图片,tgpbitmap是gdi+ 的类,支持带alpha 通道的png 文件<br>&nbsp; for i:=1 to 15 do bitmap:=tgpbitmap.Create('./images/dd.'+inttostr(i)+'.png');<br>&nbsp; form1.Width:=bitmap[1].GetWidth;<br>&nbsp; form1.Height:=bitmap[1].GetHeight;<br>&nbsp; J:=1;<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>var<br>&nbsp; i:integer;<br>begin<br>&nbsp; SelectObject(DC, old_bmp);<br>&nbsp; DeleteObject(bmp);<br>&nbsp; DeleteDC(DC);<br>&nbsp; for i:=1 to 15 do bitmap.Free;<br>end;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>var<br>&nbsp; pt1, pt2 : TPoint;<br>&nbsp; sz : TSize;<br>&nbsp; bf : TBlendFunction;<br>begin<br>&nbsp; if j&gt;15 then j:=1;<br>&nbsp; //----准备updatelayeredwindow 的参数<br>&nbsp; pt1 := Point(left, top); //窗口做上角的坐标<br>&nbsp; pt2 := Point(0, 0); //这个就不用说了,一看见(0,0)就应该明白了<br>&nbsp; sz.cx := bitmap[1].GetWidth; &nbsp;//尺寸不要超过图像大小,不然窗口就什么都没有了,连个影子都没有<br>&nbsp; sz.cy := bitmap[1].GetHeight; &nbsp;//同上<br>&nbsp; bf.BlendOp := AC_SRC_OVER; //这些死记就行了<br>&nbsp; bf.BlendFlags := 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //同上<br>&nbsp; bf.SourceConstantAlpha := $ff; &nbsp;//同上<br>&nbsp; bf.AlphaFormat := AC_SRC_ALPHA; //同上<br>&nbsp; //-----------------------------------<br>&nbsp; DeleteObject(bmp); //前面就是在这里犯的错误,不然占用的内存会无限增大<br>&nbsp; bitmap[j].GetHBITMAP(0,bmp); // HBITMAP是windows标准位图格式,支持透明,这里是从tgpbitmap 转化成 HBITMAP<br>&nbsp; DeleteDC(DC);<br>&nbsp; DC := CreateCompatibleDC(Canvas.Handle); //API的含义我倒是明白,为什么写这句话我就不明白了,反正就是需要<br>&nbsp; old_bmp := SelectObject(DC, bmp); //同上<br>&nbsp; UpdateLayeredWindow(Handle, Canvas.Handle, @pt1, @sz, DC, @pt2,0, @bf,ULW_ALPHA); //最关键的地方,前面都在为这句作准备<br>&nbsp; // 有了这句话,WM_PAINT就不发生了,窗口也不画了,控件也看不见了,titlebar都不见了,还好,功能还在,虽然都看不见,还是可以点的,菜单不受影响。总之,全都自己来画吧。<br>&nbsp; j:=j+1;<br>end;<br><br>end.<br>
 
to wujingping<br>在程序完工后方便给我一份代码吗,我想了解一下关于gdi的东西<br>或者留个qq,我也有不少代码可以共享的<br>我的qq 42524783 留java或者delphi都可以<br>liukun966123@hotmail.com
 
to wujingping<br>你的代码中的gdipapi, gdipobj; //最后两个是 GDI+ 引擎<br>这两个单元文件delphi自带了吗?我没找着。<br>请问在哪,或者发给我,谢谢了。<br>phyyun@ha.lss.gov.cn<br>
 
to wujingping:<br>那个UpdateLayeredWindow函数也是在2K的user32.DLL中才有的,<br>如果不能在98下运行那就不能算完美了,<br>我觉得还不如看看我贴的那个控件,看那作者是如何实现的,然后自己动手把它改得好些,<br>让它既能在98下运行,又不能延迟太厉害,这样才称得上完美
 
gdipapi, gdipobj; //最后两个是 GDI+ 引擎<br>找不到,是jidi的吗
 
&nbsp; &nbsp;我这里也有一段代码。不过比较挫。窗体创建后捕捉当前背景了,看上去是透明的。<br>如果把窗体移动就不是了^_^。<br>unit Unit1;<br><br>interface<br><br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs;<br><br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; private<br>&nbsp; procedure CMEraseBkgnd(var Message:TWMEraseBkgnd);Message WM_ERASEBKGND;<br>{拦截CMEraseBkgnd消息}<br><br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br>procedure TForm1.CMEraseBkgnd(var Message:TWMEraseBkgnd);<br><br>begin<br><br>Brush.style:=bsClear;{设置背景透明}<br>Inherited;<br>end;<br><br>end.
 
http://www.progdigy.com/download/gdiplus.zip<br>两个单元自己去下
 
to lyunfeng,如果是要全透明的,那太简单了<br>我有一段代码可以让窗体上除了控件外都是透明的,移动后也是,而且延迟也不明显<br>我觉得如何让窗体半透明,这才是讨论的重点
 
to 低调一贱男,谢谢。<br>to LovingTse,<br>能否把你的代码给我看看,支持98的透明代码我一直没找到。或者发我信箱,<br>谢谢。phyyun@ha.lss.gov.cn
 
to:低调一贱男,<br>嘿我在下载你的两个单元时,到一半就再也下载不了了!是不是<br>你从FTP上删除了!
 
Form1.AlphaBlend:=True;<br>Form1.AlphaBlendValue:=123;<br><br>这个只能在2000以上版本可以用
 
to phyyun,半透明的就是上面我贴的控件,下面的代码是让窗体全透明,也就是建立一个不规则窗体<br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br>&nbsp; &nbsp;FullRgn, ClientRgn, ButtonRgn: THandle;<br>&nbsp; &nbsp;LeftMargin,TopMargin:Integer;<br>&nbsp; &nbsp;Margin, X, Y: Integer;<br>&nbsp; &nbsp;i:integer;<br>begin<br>&nbsp; &nbsp; &nbsp;Margin := (Width - ClientWidth) div 2;<br>&nbsp; &nbsp; &nbsp;FullRgn := CreateRectRgn(0, 0, Width, Height);<br>&nbsp; &nbsp; &nbsp;LeftMargin := Margin;<br>&nbsp; &nbsp; &nbsp;TopMargin := Height - ClientHeight - Margin;<br>&nbsp; &nbsp; &nbsp;ClientRgn := CreateRectRgn(LeftMargin, TopMargin, LeftMargin + ClientWidth, TopMargin + ClientHeight);<br>&nbsp; &nbsp; &nbsp;CombineRgn(FullRgn, FullRgn, ClientRgn, RGN_DIFF);<br><br>&nbsp; &nbsp; &nbsp;for i:= 0 to ComponentCount-1 do<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if not (Components is TWinControl) then continue;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (Components as TWinControl).Parent&lt;&gt;self then continue;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;X := LeftMargin + (Components as TWinControl).Left;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Y := TopMargin + (Components as TWinControl).Top;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ButtonRgn := CreateRectRgn(X, Y, X + (Components as TWinControl).Width, Y + (Components as TWinControl).Height);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;CombineRgn(FullRgn, FullRgn, ButtonRgn, RGN_OR);<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end;<br><br>&nbsp; &nbsp; &nbsp;SetWindowRgn(Handle, FullRgn, True);<br>end;
 
WIN98 快被淘汰了,5年前的东西,建议不要再用了!!硬件都用不了5年,何况软件。<br>一个窗口均匀的半透明,没有太大用处,(前几天作了一把屏幕标尺,用滚轮控制透明度来着)。用 “RGN” 的方法在屏幕上挖个洞也是达不到我的目的的,关键是图片控制透明,这样才能够实现反锯齿平滑,东西才好看。<br>我现在是一家公司的艺术总监,对这个太敏感了。说到底,透明窗口不是什么关键技术,研究一下好玩而已,比如做个小精灵漂在桌面上等等。大家就不要死钻牛角尖了。<br>
 
谢谢LovingTse<br>to wujingping,很多机器还是在跑98,不过,你说的也有道理。
 
wujingping, 你的那颗钻石好漂亮的,事怎么做的啊!能说一下大概原理妈?!<br>还有PNG图片是什么图片啊!其他格式的图片可以做吗/?
 
To WuJingPing &nbsp; &nbsp; &nbsp;那颗钻石真棒!!!
 
钻石是我用三维软件画的,十五张图片。<br>PNG是本来是专门为网络设计的传输格式,作用和 JPG 、GIF 、差不多。不同的是它可以支持带 ALPHA 通道,ALPHA 是管透明度的,所以可以显示出发光之类的效果,GIF虽然也支持透明,但是不能支持半透明,也就是说每个点的透明度不可调,要么全透明,要么不透明,不能半透明,不规则的轮廓一定会有难看的锯齿状边缘。<br>现在支持PNG的软件很多,firework保存的缺省格式就是PNG,但是macromedia污染了这个格式,由firework直接保存得到的 PNG 虽然也可以像普通PNG一样使用,但是文件的尾部有大量附加信息(矢量,图层,很多附加信息),这些附加信息别的软件是打不开的,只有firework 可以读。如果要使用PNG格式的话一定要导出而不是保存(保存也是需要的,因为是图片的源文件),不然文件体积会大很多倍。
 
顶部