編程實現表單的半透明效果
如果你不是使用Windows2000+Delphi編程的話,我不想浪費你的時間。如果是,請繼續。 大家都知道Windows 2000支援淡入淡出的表單顯示效果。如何讓自己的應用程式也具備這種效果呢?前兩天研究FormContainer的Form顯示效果時(註:FormContainer是一個強大的Delphi特效處理控制項,有興趣的朋友可以訪問http://www.billeniumsoft.com/),得高人告知,核心API函數就是SetLayeredWindowAttributes。 要實現淡入淡出效果,就需要實現視窗的可調整的透明效果。傳統的Windows應用程式想實現透明效果,一般來說需要處理自己的視窗的WM_Paint訊息,程式員需要GetDC擷取螢幕的HDC,調用BitBlt函數將螢幕將要被覆蓋的地區拷貝到記憶體的TBitmap對象中,然後對該Tbitmap的ScanLine二維數組逐象素的修改rgbtRed、rgbtGreen和rgbtBlue值。天哪,實在是太麻煩了。 Windows2000的API庫中終於提供了半透明的表單顯示效果支援(雖然不是很完善)。要實現半透明的視窗效果,首先需要給建立的視窗添加WS_EX_LAYERED 擴充屬性,這是一個新的視窗擴充屬性,Delphi5並沒有定義相應的常量和SetLayeredWindowAttributes函數,我們需要手工聲明。 function SetLayeredWindowAttributes(Handle: HWND; COLORKEY: COLORREF; Alpha: BYTE; Flags: DWORD): Boolean; stdcall; external 'USER32.DLL'; Const WS_EX_LAYERED = $80000; LWA_ALPHA = 2; 我們調用GetWindowLong函數擷取當前視窗的擴充屬性,並調用SetWindowLong函數將新的WS_EX_LAYERED視窗擴充屬性添加進去。 procedure TForm1.FormCreate(Sender: TObject); begin SetWindowLong(Handle,GWL_EXSTYLE,GetWindowLong(Handle,GWL_EXSTYLE) or WS_EX_LAYERED); end; 現在我們的視窗已經可以調用SetLayeredWindowAttributes函數,通過設定該函數的Alpha參數,我們就可以看到視窗的效果的變化。 procedure TForm1.Button1Click(Sender: TObject); begin SetLayeredWindowAttributes(Form1.Handle, 0, 180, LWA_ALPHA); end; 以下的VCL控制項代碼封裝了SetLayeredWindowAttributes函數,編程時動態改變AlphaValue值,您就可以看到視窗的透明效果了。控制項屏蔽了設計期的顯示效果,如果讀者願意可以改為設計期效果可見,不過那樣的話,一不小心,您可能就會找不著你要設計的表單了 unit TranForm; {DragonPC 2001.2.21 } interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms ; type TTranForm = class(TComponent) private FAlphaValue : integer ; FParentFormHandle : HWND ; procedure SetFAlphaValue(Alpha:integer) ; protected procedure UpdateDisplay ; public constructor Create(AOwner: TComponent); override; published property AlphaValue : integer read FAlphaValue write SetFAlphaValue ; end; procedure Register; function SetLayeredWindowAttributes(Handle: HWND; COLORKEY: COLORREF; Alpha: BYTE; Flags: DWORD): Boolean; stdcall; external 'USER32.DLL'; implementation procedure Register; begin RegisterComponents('Standard', [TTranForm]); end; procedure TTranForm.SetFAlphaValue(Alpha: integer); begin if (Alpha >= 0) and (Alpha < 256) then begin FAlphaValue := Alpha ; UpdateDisplay() ; end; end; procedure TTranForm.UpdateDisplay; begin if (csDesigning in ComponentState) then Exit ; SetLayeredWindowAttributes(FParentFormHandle, 0, FAlphaValue, 2); end; constructor TTranForm.Create(AOwner: TComponent); begin inherited; if (csDesigning in ComponentState) then Exit; FAlphaValue := 255 ; FParentFormHandle := TForm(AOwner).Handle ; SetWindowLong(FParentFormHandle, GWL_EXSTYLE, GetWindowLong(FParentFormHandle, GWL_EXSTYLE) or WS_EX_LAYERED); end; end. 謝謝您的莫大耐心得以看完此文,此文純粹本著賺取china-pub"假幣"目的所寫,萬一各位看官有任何的疑問,歡迎信至dragonpc@21cn.com,謝謝。
作者會員名:dragonpc
|