日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

窗体的Alpha通道透明色支持

發布時間:2024/4/17 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 窗体的Alpha通道透明色支持 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考:?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函數更新這個位圖即可!

轉載于:https://www.cnblogs.com/MaxWoods/p/3295867.html

總結

以上是生活随笔為你收集整理的窗体的Alpha通道透明色支持的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。